admin管理员组文章数量:1291037
I have an old site that has sooo many child pages that I'd like to limit the return of child pages on a current page to just a specific year so that I can pull each year into an accordion.
I am currently using the following and it returns the pages I want listed, I just want to limit the returns to specific years.
global $id;
wp_list_pages("title_li=&child_of=$id&show_date=modified&date_format=$date_format");
What can I add to this statement to return only pages published in a specific year?
I have an old site that has sooo many child pages that I'd like to limit the return of child pages on a current page to just a specific year so that I can pull each year into an accordion.
I am currently using the following and it returns the pages I want listed, I just want to limit the returns to specific years.
global $id;
wp_list_pages("title_li=&child_of=$id&show_date=modified&date_format=$date_format");
What can I add to this statement to return only pages published in a specific year?
Share Improve this question asked Jun 14, 2021 at 16:30 AndreaAndrea 235 bronze badges 8 | Show 3 more comments1 Answer
Reset to default 0Due to wp_list_pages()
leveraging get_pages()
to actually retrieve the Page posts, and because get_pages()
implements it's own query logic independent of WP_Query
's, it's not possible to use arbitrary query variables which are not directly supported by get_pages()
, including year
, mothnum
, day
, date_query
, etc.
In order to continue using wp_list_pages()
to this end, I think the most elegant solution would be to implement a custom Walker_Page
class which you might pass to wp_list_pages()
as an argument in order to customize the generated HTML.
As an added benefit, this solution continues to use a single get_pages()
query instead of one query per year, and can fluidly handle grand-children pages and continue to scale as more years are added.
Tailored Walker_Page
In WordPress "Walkers" are classes which are designed to take lists representing hierarchical or tree-like data like that of a like of hierarchical post-types, taxonomies, or navigation menu items and turn them into markup for display.
wp_list_pages()
provides a parameter to pass a custom Walker to it in place of the Walker_Page
class it uses by default, allowing you to customize the markup the function produces.
// mytheme/lib/class-year-accordion-walker-page.php
// (or functions.php, or some other theme library code location)
/**
* A Walker_Page customized to additionally group first-level pages into lists based
* on their publication year.
**/
class Year_Accordion_Walker_Page extends Walker_Page {
/**
* Creates the opening markup for a year's accordion group.
*
* @param string &$output The string to append output to.
* @param int $year The year which to build group markup for.
* @param boolean $is_active If this year matches the publication date for the current page, as indicated by "child_of".
* @param array $args Any additional arguments passed to `walk()`.
**/
public function start_accordion_group( &$output, $year, $is_active = false, $args = [] ) {
// Setup HTML classes to be added to various parts of the markup.
$container_classes = [];
$header_classes = [ 'ui-accordion-header' ];
$content_classes = [ 'ui-accordion-content' ];
if( $is_active ) {
$container_classes[] = 'current_page_ancestor';
$header_classes[] = 'ui-accordion-header-active';
$content_classes[] = 'ui-accordion-content-active';
}
// Add this accordion group's opening markup to the output, joining each line with the configured indentation.
$output .= implode(
"\n\t",
[
'<li class="' . implode( ' ', $container_classes ) . '">',
'<h3 class="' . implode( ' ', $header_classes ) . '">' . $year . '</h3>',
'<ul class="' . implode( ' ', $content_classes ) . '">',
]
);
}
/**
* Creates the closing markup for a year's accordion group.
*
* @param string &$output The string to append output to.
* @param int $year The year which to build group markup for.
* @param boolean $is_active If this year matches the publication date for the current page, as indicated by "child_of".
* @param array $args Any additional arguments passed to `walk()`.
**/
public function end_accordion_group( &$output, $year, $is_active = false, $args = [] ) {
$output .= implode(
"\n",
[
"\t</ul>", // Close the accordion group's page list.
'</li>', // Close the accordion group's container li.
]
);
}
/**
* Display array of Pages, grouped by the topmost pages' publication year.
*
* $max_depth = 0 means display all levels.
* $max_depth > 0 specifies the number of display levels.
*
* @param array $pages An array of WP_Post items.
* @param int $max_depth The maximum hierarchical depth.
* @param mixed ...$args Optional additional arguments.
* @return string Markup representing $pages grouped by publication year.
**/
public function walk( $pages, $max_depth = 0, ...$args ) {
$output = '';
// Invalid parameter or nothing to walk.
if ( $max_depth < 0 || empty( $pages ) )
return $output;
$options = $args[0]; // When used with `walk_page_tree()` this is an assoc array of any additional arguments.
$current_page_id = $args[1]; // When used with `walk_page_tree()` this is the current post ID.
$active_page_year = null; // Keep track of which year the current_page_id Page was published in for custom classes, etc.
$parent_field = $this->db_fields['parent']; // Inherited from `Walker_Page` - will always be `ID`.
$parent_id = isset( $options['child_of'] ) ? $options['child_of'] : 0; // The ID of the top-level common parent, if any.
$top_level_pages_by_year = []; // A mapping of year => top-level pages (parent is $parent_id, or no parent if $parent_id is not set).
$child_pages_by_parent = []; // A mapping of parent_id => pages, collecting all pages whose parent is not $parent_id (or who have a parent, if $parent_id is not set)
// Split $pages into $child_pages_by_parent and $top_level_pages_by_year.
foreach( $pages as $page ) {
$year = date( 'Y', strtotime( $page->post_date ) );
if( $page->ID === $current_page_id )
$active_page_year = $year; // If this is the current page, record the year in which it was published.
// If this is a grandchild page, we don't care about it's publish date - just add it to the map of parent_id => child pages.
if( ( empty( $parent_id ) && ! empty( $page->$parent_field ) ) || ( ! empty( $parent_id ) && $page->$parent_field !== $parent_id ) ) {
if( ! isset( $child_pages_by_parent[ $page->$parent_field ] ) )
$child_pages_by_parent[ $page->$parent_field ] = [];
$child_pages_by_parent[ $page->$parent_field ][] = $page;
continue;
}
if( ! isset( $top_level_pages_by_year[ $year ] ) )
$top_level_pages_by_year[ $year ] = [];
$top_level_pages_by_year[ $year ][] = $page; // Add the top level page to it's respective year list.
}
// Build the markup, one year at a time.
foreach( $top_level_pages_by_year as $year => $pages ) {
// Build the opening markup for this year's accordion group.
$this->start_accordion_group( $output, $year, $year == $active_page_year, $args );
// Add each top-level page in the group's child tree markup as per usual.
foreach( $pages as $page )
$this->display_element( $page, $child_pages_by_parent, $max_depth, 1, $args, $output );
// Close this year's accordion group.
$this->end_accordion_group( $output, $year, $year == $active_page_year, $args );
}
return $output;
}
}
With the above class available, wp_list_pages()
can be called to utilize it as such:
// Template file
wp_list_pages(
[
'title_li' => '&',
'child_of' => $id,
'show_date' => 'modified',
'date_format' => $date_format,
'walker' => new Year_Accordion_Walker_Page,
]
);
Finishing Touches
For the icing on the cake, you might even create a "template tag" function to load and leverage this class when necessary:
// functions.php
// (or other library file loaded by functions.php)
/**
* Display pages in an accordion, grouped by year. Loads the customized
* Walker_Page if it's not already available.
*
* @param array $args Array of wp_list_pages() arguments.
**/
function wpse390524_page_year_accordion( $args = [] ) {
if( ! class_exists( 'Year_Accordion_Walker_Page' ) )
require_once get_stylesheet_directory() . '/lib/class-year-accordion-walker-page.php';
$args['walker'] = new Year_Accordion_Walker_Page;
wp_list_pages( $args );
}
// Template file
wpse390524_page_year_accordion(
[
'title_li' => '&',
'child_of' => $id,
'show_date' => 'modified',
'date_format' => $date_format,
]
);
本文标签: List child pages of current page but limit to specific year
版权声明:本文标题:List child pages of current page but limit to specific year 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741504028a2382211.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
wp_list_pages()
depending onget_pages()
and how the latter implements it's own esoteric database query logic, I don't believe you can achieve the desired outcome by just adding something to the query. I think this would be a good use-case for a customWalker_Page
class. In any scenario, can you elaborate on the specific behavior a little more - if a child was published three years ago, and it has grandchildren published two years ago as well as this year, does the child appear in just 2018, or all of 2018, 2019, and 2021? – bosco Commented Jun 14, 2021 at 17:10