We are using custom breadcrumb titles for a hierarchical custom post type. We would like to have the page parent dropdown use the breadcrumb title if it is available and then the title if it is not.
We are using custom breadcrumb titles for a hierarchical custom post type. We would like to have the page parent dropdown use the breadcrumb title if it is available and then the title if it is not.
Share Improve this question asked Mar 12, 2019 at 11:22 Dane MorganDane Morgan 1961 silver badge8 bronze badges 4- How is the custom breadcrumb title set? With a plugin? – Jacob Peattie Commented Mar 12, 2019 at 11:25
- Correct. We are setting it through the Yoast plugin. – Dane Morgan Commented Mar 12, 2019 at 11:31
- 2 Here's the relevant code: github/WordPress/WordPress/blob/5.1/wp-admin/includes/… Those args are passed to get_pages; I don't know if you can use the page_attributes_dropdown_pages_args filter to set up the query how you want? Alternatively you might need to hook into wp_dropdown_pages, or replace its output with a filter. – Rup Commented Mar 12, 2019 at 11:50
- Yes, I've drilled down through this section into wp_dropdown_pages and wp_parse_args. I can see in these how I could filter the query itself to return a different set or subset of pages, but I can't see how I could filter the output to replace the title with another value. – Dane Morgan Commented Mar 12, 2019 at 12:23
1 Answer
Reset to default 1I suppose you aren't still looking for this, but I was, and I managed to figure out a solution. I'm posting it up here as this came up pretty high in the search results.
What I did was to filter on the dropdown box generator for WordPress.
It passes in an array of args. One is the id
of the select element, which for that part of the page is parent_id
, and it also passes in the post_type
so I restricted that to the post type I wanted to modify.
The technique is then to modify the array of WP_Query
objects with a new title.
Unfortunately, by the time this filter is called, the full html markup is generated for the select box, so what I did was to just grab that snippet of html out of the WordPress core and put it into my filter. That way it would regenerate it with my modified WP_Query
objects.
function customise_parent_page_dropdown($output, $parsed_args, $pages)
{
// CUSTOMISE HERE TO FILTER TO THE POST_TYPE YOU WANT
if("parent_id" === $parsed_args['id'] && "mix-question" === $parsed_args['post_type']) {
// update the page titles
foreach($pages as $key => $page){
// CUSTOMISE HERE TO ALTER THE TITLE HOW YOU WANT
$previous_answer = get_field('previous_answer', $pages[$key]->ID);
if($previous_answer !== "") {
$pages[$key]->post_title = $previous_answer . " – " . $pages[$key]->post_title;
}
}
// regenerate the select tag - clone of the wordpress core code
// https://github/WordPress/WordPress/blob/d5b8d282e8c03929aafb1fa660181b7db9ad55d3/wp-includes/post-template.php#L1187
if ( ! empty( $pages ) ) {
$class = '';
if ( ! empty( $parsed_args['class'] ) ) {
$class = " class='" . esc_attr( $parsed_args['class'] ) . "'";
}
$output = "<select name='" . esc_attr( $parsed_args['name'] ) . "'" . $class . " id='" . esc_attr( $parsed_args['id'] ) . "'>\n";
if ( $parsed_args['show_option_no_change'] ) {
$output .= "\t<option value=\"-1\">" . $parsed_args['show_option_no_change'] . "</option>\n";
}
if ( $parsed_args['show_option_none'] ) {
$output .= "\t<option value=\"" . esc_attr( $parsed_args['option_none_value'] ) . '">' . $parsed_args['show_option_none'] . "</option>\n";
}
$output .= walk_page_dropdown_tree( $pages, $parsed_args['depth'], $parsed_args );
$output .= "</select>\n";
}
}
return $output;
}
add_filter('wp_dropdown_pages', 'customise_parent_page_dropdown', 100, 3);
In my example code I'm pulling in an ACF field that I wanted to prefix it with. Change this to whatever you want.
Potential pitfalls with this approach are that if somebody calls the dropdown generator on this post type with an id of parent_id
it will match and filter.
Also if WordPress changes the way it generates the select tag in the future then it will need to be updated here as well. I think these are reasonable trade-offs for getting the solution I wanted.