WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] exclude from wp_list_pages with meta_value (24 posts)

  1. thecoup
    Member
    Posted 4 years ago #

    Can we exclude pages from wp_list_pages using met_key and meta_value?

    Does wordpress offer offer a way to do this?

    Or do I need to build an array manually? If so, what's the cleanest way to do this? To subtract one array (list by meta_value) from the full list?

    thanks!!

  2. MichaelH
    Member
    Posted 4 years ago #

    Didn't test this but something like this to get pages where custom field cf1 is equal to green:

    <?php
    $args=array(
      'showposts' => -1,
      'post_type' => 'page',
      'meta_key' => 'cf1',
      'meta_compare' => '=',
      'meta_value' => 'green'
    );
    $pages = get_posts($args);
    if ($pages) {
      foreach($pages as $post) {
        setup_postdata($post); ?>
        <p><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></p>
        <?php
      } // foreach($pages
    } // if ($pages
    ?>
  3. thecoup
    Member
    Posted 4 years ago #

    Can anyone think of a better method?

    $list_full = wp_list_pages('echo=0');
    $list_exclude = wp_list_pages('meta_value=XYZ&meta_key=ABC&echo=0');
    $the_list = array_diff($list_full, $list_exclude);

  4. thecoup
    Member
    Posted 4 years ago #

    Thanks Michael. I'm looking to exclude items with meta_value green.

    What does meta_compare do? Can I set that to be not equal and use it with wp_list_pages?

    (I want to use wp_list_pages to utilize the class and hierarchy generated by WP)

    thanks again...

  5. thecoup
    Member
    Posted 4 years ago #

    So it seems like this will do the trick. I hadn't seen meta_compare before.

    <?php

    $args = array(
    'meta_compare' => '!=',
    'meta_key' => 'Exclude_Page',
    'meta_value' => 'Yes_Sir',
    );

    wp_list_pages( $args );

    ?>

  6. iridiax
    Member
    Posted 4 years ago #

    wp_list_pages exclude is based on page ID and I just don't see how you could relate that to a meta value.

    http://codex.wordpress.org/Template_Tags/wp_list_pages#Exclude_Pages_from_List

  7. thecoup
    Member
    Posted 4 years ago #

    Oh well, doesn't work. I guess that meta_compare can't be passed to wp_list_pages. that's stinky. Back to the drawing board...

  8. MichaelH
    Member
    Posted 4 years ago #

    Build an array of post ids using the get_posts example then use that array with the wp_list_pages exclude argument.

  9. Mark / t31os
    Moderator
    Posted 4 years ago #

    You can use..

    <?php
    wp_list_pages( array('meta_key'=>'keyname','meta_value'=>'value') );
    ?>

    However you can't use meta_compare when using wp_list_pages as it only supports both meta_key and meta_value, but not meta_compare..
    http://codex.wordpress.org/Function_Reference/get_pages

    get_posts is not documented as supporting meta_compare, but does look to support it(wp-includes/query.php - line 2146).

    Use get_posts if you need the meta_compare parameter, as Michael suggested.

  10. MichaelH
    Member
    Posted 4 years ago #

    I believe that get_posts can use almost any argument listed in the query_posts() article.

  11. nathan12343
    Member
    Posted 4 years ago #

    Hi,

    I'm trying something similar - exclude pages which don't have the key/value of notmobile/notmobile.

    I've tried loads of different ways, and just used MichaelH's code above to come up with:

    <?php
    global $post;
    $args=array(
      'post_type' => 'page',
      'meta_key' => 'notmobile',
      'meta_compare' => '!=',
      'meta_value' => 'notmobile'
    );
    $pages = get_posts($args); ?> 
    
    <ul>
       <?php wp_list_pages('exclude'.$pages); ?>
    </ul>

    But it doesn't exclude the pages :(

    Any help would be sooo great!

    Thanks!

    origianlly posted here:

  12. MichaelH
    Member
    Posted 4 years ago #

    Will repeat from above:

    Build an array of post ids using the get_posts example then use that array with the wp_list_pages exclude argument.

  13. nathan12343
    Member
    Posted 4 years ago #

    sorry to show up my limited knowledge, but I thought that's what I did??

  14. MichaelH
    Member
    Posted 4 years ago #

    <?php
    global $post;
    $args=array(
      'post_type' => 'page',
      'meta_key' => 'notmobile',
      'meta_compare' => '!=',
      'meta_value' => 'notmobile'
    );
    $pages = get_posts($args);
    if ($pages) {
      $pageids = array();
      foreach ($pages as $page) {
        $pageids[]= $page->ID;
      }
    }
    ?>
    <ul>
       <?php wp_list_pages('exclude='.implode(",", $pageids)); ?>
    </ul>
  15. nathan12343
    Member
    Posted 4 years ago #

    I really appreciate you coming back so quickly on this. Unfortunately I get an error:

    Warning: implode() [function.implode]: Invalid arguments passed in myurl/wp-content/themes/combined/desk_index.php on line 77

    Line 77 being:
    <?php wp_list_pages('exclude='.implode(",", $pageids)); ?>

    This is beyond me to even guess...

  16. MichaelH
    Member
    Posted 4 years ago #

    Oops sorry, forgot to handle the situation where it finds NO pages with that meta_key/meta_compare/meta_value criteria:

    <?php
    global $post;
    $args=array(
      'post_type' => 'page',
      'meta_key' => 'notmobile',
      'meta_compare' => '!=',
      'meta_value' => 'notmobile'
    );
    $pages = get_posts($args);
    if ($pages) {
      $pageids = array();
      foreach ($pages as $page) {
        $pageids[]= $page->ID;
      }
     ?>
      <ul>
       <?php wp_list_pages('exclude='.implode(",", $pageids)); ?>
    </ul>
    <?php
    }
    ?>
  17. nathan12343
    Member
    Posted 4 years ago #

    With one small change ('meta compare' => '=' rather than '!=' because I want to find the matches and then exlude them (which was my error in the first place)) this works like an absolute dream.

    Michael, you are a prince amongst men!! I can't thank you enough!

  18. jamodu
    Member
    Posted 4 years ago #

    Thanks MichaelH, this code is pretty much what I've been looking for. However, I need to include pages that have a custom field value equal to the page title.

    I've used this code, but it doesn't work properly - please can someone help?

    <?php
    global $post;
    $args=array(
      'post_type' => 'page',
      'meta_key' => 'Project Group',
      'meta_compare' => '!=',
      'meta_value' => '<?php the_title(); ?>'
    );
    $pages = get_posts($args);
    if ($pages) {
      $pageids = array();
      foreach ($pages as $page) {
        $pageids[]= $page->ID;
      }
     ?>
      <ul>
       <?php wp_list_pages('include='.implode(",", $pageids)); ?>
    </ul>
    <?php
    }
    ?>
  19. Mark / t31os
    Moderator
    Posted 4 years ago #

    You would most likely need to change 2 lines in the args array..

    To something like..

    'meta_compare' => '=',
    'meta_value' => get_the_title()

    ..assuming you're placing this somewhere get_the_title can find a valid post id..

    Else you might need something like this for the second line..

    'meta_value' => get_the_title( get_the_ID() )
  20. Andy Macaulay-Brook
    Member
    Posted 4 years ago #

    Interesting thread - will save me some time - here's the alternative method I was considering. I want to set public/private pages and have the private pages show in the navigation for logged in users.

    Add a meta_key/meta_value pair to every page, with a default value of "public" set.
    Then for any private pages, set the value of the custom field to "private."
    If a user isn't logged in with a suitable role, call wp_list_pages with this key/value pair, else just call wp_list_pages without meta_key/meta_value parameters.

    This way you save the extra database hit you'd have with calling get_pages() to generate your exclusions.

  21. Andy Macaulay-Brook
    Member
    Posted 4 years ago #

    PS - reading the code for wp_list_pages, it seems to pass any extra arguments through to get_pages, so I would expect it to be happy with meta_compare.

    I'll experiment and try to remember to report back.

  22. Andy Macaulay-Brook
    Member
    Posted 4 years ago #

    Just for completeness, the following code taken from the get_pages() definition in includes/post.php shows that get_pages() hardcodes the = operator for comparing custom fields and so passing meta_compare to get_pages() has no effect. Pity.

    if ( ! empty( $meta_key ) || ! empty( $meta_value ) ) {
    		$join = " LEFT JOIN $wpdb->postmeta ON ( $wpdb->posts.ID = $wpdb->postmeta.post_id )";
    
    		// meta_key and meta_value might be slashed
    		$meta_key = stripslashes($meta_key);
    		$meta_value = stripslashes($meta_value);
    		if ( ! empty( $meta_key ) )
    			$where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_key = %s", $meta_key);
    		if ( ! empty( $meta_value ) )
    			$where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_value = %s", $meta_value);
    
    	}

    Passing meta_key => 'my_field_name', meta_value => 'success' will always result in a MySQL WHERE clause containing $wpdb->postmeta.meta_key = my_field_name AND $wpdb->postmeta.meta_value = success

    I guess this also means that any posts/pages that you want to be evaluated must always have a custom field my_field_name assigned too.

  23. Mark / t31os
    Moderator
    Posted 4 years ago #

    Yes i had mentioned that further up the thread, if you want to use meta_compare, use get_posts as i stated before...

    For this kind of thing you'd be better off writing your own query, simply so you can wrap it up in a single query, rather then several just to build an exclusion list..

  24. Andy Macaulay-Brook
    Member
    Posted 4 years ago #

    Ah, yes - thanks for reiterating that - I seem to have had a temporary blindness to the difference between get_pages & get_posts.

Topic Closed

This topic has been closed to new replies.

About this Topic