列出当前页面的子页面,但仅限于特定年份

时间:2021-06-14 作者:Andrea

我有一个旧网站,有太多的子页面,我想限制当前页面上子页面的返回仅限于特定的年份,这样我就可以将每年的子页面拉到一个手风琴中。

我目前正在使用以下内容,它返回我想要列出的页面,我只想将返回限制在特定年份。

  global $id;
  wp_list_pages("title_li=&child_of=$id&show_date=modified&date_format=$date_format"); 
为了只返回特定年份发布的页面,我可以在该语句中添加什么内容?

1 个回复
最合适的回答,由SO网友:bosco 整理而成

由于wp_list_pages() 杠杆作用get_pages() 要实际检索页面帖子get_pages() 实现独立于WP_Query\'s、 无法使用不受直接支持的任意查询变量get_pages(), 包括…在内year, mothnum, day, date_query, 等

为了继续使用wp_list_pages() 为此,我认为最优雅的解决方案是实现自定义Walker_Page class 你可以传给wp_list_pages() 作为参数,以自定义生成的HTML。

作为一个附加好处,此解决方案继续使用get_pages() 查询而不是每年一次查询,并且可以流畅地处理孙子页面,并随着年份的增加而继续扩展。

量身定制的Walker_Page

在WordPress中"Walkers" 类的设计目的是获取表示分层或树状数据的列表,如类似分层帖子类型、分类法或导航菜单项的列表,并将其转换为标记以供显示。

wp_list_pages() 提供一个参数以将自定义Walker传递给它,以代替the Walker_Page class 它默认使用,允许您自定义函数生成的标记。

// 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;
  }
}
有了上述课程,wp_list_pages() 可以调用以将其用作:

// Template file
wp_list_pages(
  [
    \'title_li\'    => \'&\',
    \'child_of\'    => $id,
    \'show_date\'   => \'modified\',
    \'date_format\' => $date_format,
    \'walker\'      => new Year_Accordion_Walker_Page,
  ]
); 

收尾工作

对于蛋糕上的糖霜,您甚至可以创建一个;模板标签;函数在必要时加载和利用此类:

// 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,
  ]
);

相关推荐

如何列出带有摘录的子页,例如[Child-Pages Depth=“1”Excerpt=“1”]

我想构建一个快捷码函数来生成父页面的子页面的HTML列表,并包含摘录。类似这样:<ul> <li> <h3>Child Page Title 1</h3> <p>Excerpt 1</p> <li> <li> <h3>Child Page Title 2</h3> <p>Exc