How to Only Retrieve Posts With Custom Fields 23comments
Thanks for visiting! If you're new here, you may want to subscribe to our RSS feed. This blog posts regular Wordpress news, updates of themes, plugins, ideas, hacks, quick fixes and everything about blogging, especially about Wordpress. Go ahead, subscribe to our feed! You can also receive updates from this blog via email.
One question I come across a lot regarding custom fields is how to only retrieve posts based on a custom field.
For example, if a post has a custom field of “MyData”, someone might want to only retrieve that particular post.
The WordPress Codex has a technique for retrieving posts based on custom fields, which consists of writing your own query and going through the results.
The technique in the Codex is good, but I’ve found a re-usable way one can retrieve only posts with certain custom fields.
The technique I use makes use of two custom functions placed in a theme’s “functions.php” and a custom WordPress Loop.
Let’s get started — The “functions.php” file
First, let’s place the two custom functions in the “functions.php” file. This file should be in your theme directory, but if it isn’t there, you can create one using any text editor.
Here are the two functions below:
function get_custom_field_posts_join($join) { global $wpdb, $customFields; return $join . " JOIN $wpdb->postmeta postmeta ON (postmeta.post_id = $wpdb->posts.ID and postmeta.meta_key in ($customFields)) "; } function get_custom_field_posts_group($group) { global $wpdb; $group .= " $wpdb->posts.ID "; return $group; }
The function “get_custom_field_posts_join” makes use of an advanced WordPress filter called “posts_join“. Each time posts are called, you can add on extra MySQL parameters using filters. In this case, I add on an option to find certain postmeta. Please note the use of a global variable called “customFields“, which I’ll explain a bit later.
The function “get_custom_field_posts_group” makes use of another advanced WordPress filter called “posts_group“. This is used to avoid duplicate entries in our return query.
Now Let’s Work on Our Loop
After the two functions are placed in the “functions.php” file, it’s time to work on placing the appropriate code into one of our template files.
For this example, I’ll be modifying the “sidebar.php” file in the WordPress default theme. You could place the below code in any of your theme files, however.
<?php /* Begin Custom Field Posts */ ?> <h2>Custom Posts</h2> <ul> <?php global $customFields; $customFields = "'Links', 'MyData'"; //Comma seperated 's1', 's2', 's3'
The first part of the code deals with establishing the structure of the output. You really could do anything you want here.
Please note the use of the global variable “customFields“. What we’re doing here is setting up a comma-separated variable that will be used to search for our custom fields. The “customFields” variable is used in the “get_custom_field_posts_join” function.
In this example, it is assumed we want to find posts with custom fields of “Links” and “MyData“.

Custom Fields - Links and MyData
The next bit of code instantiates a new instance of WP_Query and runs a query to return some posts.
$customPosts = new WP_Query(); add_filter('posts_join', 'get_custom_field_posts_join'); add_filter('posts_groupby', 'get_custom_field_posts_group'); $customPosts->query('showposts=5' );//Uses same parameters as query_posts remove_filter('posts_join', 'get_custom_field_posts_join'); remove_filter('posts_groupby', 'get_custom_field_posts_group');
Note the use of the “add_filter” and “remove_filter” functions. Since we are doing a post query, we can tap into the query and add our own parameters. So before the query is initiated, two query-type filters are added, and after the query is initiated, the two filters are deactivated since we only want them run once.
This last bit of code initiates our custom loop, gets the custom values, spits them out, and ends the loop.
while ($customPosts->have_posts()) : $customPosts->the_post(); $links = get_post_custom_values("Links"); $data = get_post_custom_values("MyData"); ?> <li><a href='<?php echo $links[0]; ?>'><?php echo $data[0]; ?></a></li> <?php endwhile; ?> </ul> <?php /* End Custom Field Posts */ ?>
The “get_post_custom_values” WordPress function returns an array of matching keys. It’s assumed there is only one key per post, which is why we echo out the first value (Ex: echo $links[0]).
The Full Post Code
Here is the full post code. The only thing you need to change for your own use is the custom fields needed (change the customFields text) and what type of output is desired within our custom loop.
<?php /* Begin Custom Field Posts */ ?> <h2>Custom Posts</h2> <ul> <?php global $customFields; $customFields = "'Links', 'MyData'"; //Comma seperated 's1', 's2', 's3' $customPosts = new WP_Query(); add_filter('posts_join', 'get_custom_field_posts_join'); add_filter('posts_groupby', 'get_custom_field_posts_group'); $customPosts->query('showposts=5' );//Uses same parameters as query_posts remove_filter('posts_join', 'get_custom_field_posts_join'); remove_filter('posts_groupby', 'get_custom_field_posts_group'); while ($customPosts->have_posts()) : $customPosts->the_post(); $links = get_post_custom_values("Links"); $data = get_post_custom_values("MyData"); ?> <li><a href='<?php echo $links[0]; ?>'><?php echo $data[0]; ?></a></li> <?php endwhile; ?> </ul> <?php /* End Custom Field Posts */ ?>

Custom Field Output
Downloadable Code
The full code mentioned in this post is available for download. Within the “zip” file are a sample “functions.php” and “sidebar.php“.
Conclusion
With the above technique, you can do some pretty fancy stuff. For example, you can only retrieve posts with custom images for a nice magazine effect.
If you have any questions regarding the code, I’ll do my best to answer them in the comments.










