How to display wordpress page list with specific custom field value

WordPress lets you display a list of pages as links with many customizations. You can use wp_list_pages or get_pages to display or get list of pages. These functions let you do couple of customization. Some of the main customizations are:

  1. Only list children of a specific page.
  2. Limit the page depth while displaying.
  3. Exclude some specific pages.
  4. Include some pages (this does not work with child_of argument though)

Since you can’t have tags in wordpress page, it does not let you do any customization based on tags which is a convenient feature for wordpress posts. Here is a workaround which can be implemented using custom fields. The main steps are:

  1. Create custom a field e.g. mypagetag or something similar. You can add one or more custom field (mypagetag) values for desired wordpress pages.
  2. Now a regular code to display pages will look like this:
    $parent = "PARENT_PAGE_ID";
    $args = array(
      'depth'        => 0,
      'show_date'    => '',
      'date_format'  => get_option('date_format'),
      'child_of'     => $parent,
      'exclude'      => '',
      'include'      => '',
      'title_li'     => __(''),
      'echo'         => 1,
      'authors'      => '',
      'sort_column'  => 'menu_order, post_title',
      'link_before'  => '',
      'link_after'   => '',
      'walker'       => '',
      'post_type'    => 'page',
      'post_status'  => 'publish'
    );
    $pages = get_pages($args);
    
    foreach ($pages as $page) {
      echo "<a href=\"" . get_page_link($page->ID) . "\">" . $page->post_title . "</a><br/>";
    }
    

    This code display all pages which are children of a specific page.
  3. To display pages with custom field mypagetag having a specific value (say mycustomvalue).
    $post_has_tag = array();
    $q = "SELECT post_id, meta_key, meta_value from wp_postmeta where meta_key='mypagetag' and meta_value='mycustomvalue'";
    $res_arr = $wpdb->get_results($q);
    foreach ($res_arr as $one) {
      $post_has_tag[$one->post_id] = 1;
    }
    
    foreach ($pages as $page) {
      if (array_key_exists($page->ID, $post_has_tag)) {
        echo "<a href=\"" . get_page_link($page->ID) . "\">" . $page->post_title . "</a><br/>";
      }
    }
    

    Here we could have got the custom field values per page also instead of querying table wp_postmeta. I did it this way to reduce the number of queries. wp_postmeta table has index on custom field (meta_key column name). Also I did not anticipate too many entries for a custom value mycustomvalue. So data returned is also not so large. If that is not the case for some specific situation, a different strategy can be taken.
Share this article: share on Google+ share on facebook share on linkedin tweet this submit to reddit

Comments

Click here to write/view comments