How to Get Posts by Custom Fields in WordPress - Part 2
Tags: wordpress
Published: 2020-11-24 03:01:32

In <a href="https://metabox.io/get-posts-by-custom-fields-in-wordpress/">part 1</a> of <a href="https://metabox.io/series/get-post-by-custom-fields/">this series</a>, we learned about how to get posts by <a href="https://metabox.io/series/custom-fields">custom fields</a> in WordPress with the <code>WP_Query</code> function. However, if we need to deal with databases, it's better to find another faster, easier, and more convenient way. That method is joining <code>wp_posts</code> and <code>wp_postmeta</code> tables together, and then querying by SQL. In part 2 of the series "How to get posts by custom fields in WordPress", we'll use this way to add the advanced searching feature that allows users to search by keywords in posts / pages titles and custom fields content.

<!--more-->

<h2>Before Getting Started</h2>

In this article, we need to install and activate these tools:

<ul>

   <li><a href="https://metabox.io/">Meta Box</a>: A framework supports creating and editing custom fields in WordPress easily and quickly. You can download the <strong>free Meta Box core plugin</strong> on <a href="https://wordpress.org/plugins/meta-box/">wordpress.org</a>.</li>

   <li><a href="https://metabox.io/plugins/meta-box-builder/">Meta Box Builder</a>: A premium extension of Meta Box plugin that supports creating, editing, and managing custom fields with an <strong>intuitive user interface right on the back end without coding</strong>. Alternatively, you can use the <a href="https://metabox.io/online-generator/">Online Generator</a> tool of Meta Box to get a total free UI for creating custom fields.</li>

   <li><a href="https://metabox.io/plugins/mb-admin-columns/">MB Admin Columns</a>: A premium extension of Meta Box plugin that supports <strong>displaying custom fields on the post list on the front end</strong>, thus helping you manage and organize posts by custom fields easily and quickly.</li>

</ul>

<h2>Step 1: Create Custom Fields for Posts</h2>

Assuming that we have a blog about dishes, and each dish is a post so we need to classify them into different types of dishes using custom fields. Here is an example:

<img class="aligncenter" src="https://i.imgur.com/cYmkejH.png" alt="Create Custom Fields named Type for Posts in WordPress website" width="1366" height="657" />

First, on the <strong>Admin Dashboard</strong>, go to <strong>Meta Box</strong> &gt; <strong>Custom Fields</strong> and click <strong>Add New</strong>.

<img class="aligncenter" src="https://i.imgur.com/93uqz2x.png" alt="Add a custom field named Type for posts in WordPress website with Meta Box Builder" width="1350" height="657" />

In the <strong>Fields</strong> tab, add a new <strong>Text</strong> field, fill in the <strong>Title</strong>, <strong>ID</strong>, and <strong>Label</strong> boxes, and then click <strong>Publish</strong>. In this example, I create a custom field named <strong>Type</strong>.

<img class="aligncenter" src="https://i.imgur.com/rdTXnrA.png" alt="Create the custom field Type for posts in WordPress website" width="1348" height="657" />

Next, we need the <a href="https://metabox.io/plugins/mb-admin-columns/">MB Admin Columns</a> extension to<strong> display custom fields before post names</strong> on the<strong> All Posts</strong> section. Thus, you can manage posts by custom fields more easily. However, it's optional.

In the <strong>Advanced</strong> section, enter <code>admin_columns</code> and <code>after title</code>.

<img class="aligncenter" src="https://i.imgur.com/36oZSVT.png" alt="Edit the custom attribute to display it before the post name in All Posts section" width="1042" height="652" />

Finally, go to the <strong>Settings</strong> tab. In the <strong>Show for</strong> and <strong>Post</strong> <strong>types</strong> sections, choose <strong>Post</strong> to display the <strong>Type</strong> custom field to every post on the WordPress website. And don't forget to click <strong>Update</strong>!

<img class="aligncenter" src="https://i.imgur.com/YGp3CC8.png" alt="Display custom field Type on every post on WordPress website" width="1352" height="657" />

We've finished creating a new custom field named <strong>Type</strong> and add this custom field to every post on the WordPress website. Now when you go to a post and drag to the end, you will see the <strong>Type</strong> field. Now, you just need to fill in the value for this field.

<img class="aligncenter" src="https://i.imgur.com/S6YEPZA.png" alt="Fill in the value for the custom field Type in each posts" width="1366" height="657" />

After that, go to <strong>Posts</strong> &gt;<strong> All Posts</strong>, you will see the custom field values listed on the <strong>Type</strong> column.

<img src="https://i.imgur.com/cYmkejH.png" alt="Custom fields are displayed before the post names on the back end" width="1366" height="657" />

To create the advanced searching feature that allows users to search by custom field values, move to step 2.

<h2>Step 2: Create the Advanced Searching Feature</h2>

As mentioned above, WordPress only supports searching for keywords in the titles and content of <a href="https://gretathemes.com/post-page-different/" rel="follow">posts and pages</a>. To search for posts by keywords in the posts / pages titles and custom field values, you need to understand how the WordPress search feature works first.

By default, WordPress only allows searching by keywords on the <code>wp_posts</code> table in the database. Meanwhile, the <code>wp_postmeta</code> table stores additional data like custom fields' values.

Thus, to search by custom field values, we need to <code>JOIN wp_posts</code> and <code>wp_postmeta</code> tables together. This work can be done by adding this code to the <code>functions.php</code> file:

<pre>function justread_search_join( $join ) {

global $wpdb;

if ( is_search() ) {    

$join .=' LEFT JOIN '.$wpdb-&gt;postmeta. ' ON '. $wpdb-&gt;posts . '.ID = ' . $wpdb-&gt;postmeta . '.post_id ';

}

return $join;

}

add_filter( 'posts_join', 'justread_search_join' );

</pre>

<strong>Note</strong>: <code>justread</code> is the theme I'm using (you can download this free WordPress theme <a href="https://wordpress.org/themes/justread/">here</a>).

Next, you have to edit the query to search for posts by custom field values. To do it, add the following code to the <code>functions.php</code> file:

<pre>function justread_search_where( $where ) {

global $pagenow, $wpdb;

if ( is_search() ) {

$where = preg_replace(

"/\(\s*".$wpdb-&gt;posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",

"(".$wpdb-&gt;posts.".post_title LIKE $1) OR (".$wpdb-&gt;postmeta.".meta_value LIKE $1)", $where );

}

return $where;

}

add_filter( 'posts_where', 'justread_search_where' );

</pre>

From now on, you can search by custom field values. However, in the search results, there are some <a href="https://gretathemes.com/why-you-need-revision-in-wordpress/" rel="follow">revisions</a> that can make it difficult for users to choose the right result. Therefore, it's crucial to delete these revisions by adding the code including the <code>DISTINCT</code> keyword to the <code>functions.php</code> file

<pre>function justread_search_distinct( $where ) {

global $wpdb;

if ( is_search() ) {

return "DISTINCT";

}

return $where;

}

add_filter( 'posts_distinct', 'justread_search_distinct' );

</pre>

Now, the new feature to search by custom field values is complete.

To check if this search works well or not, I tried searching by the "breakfast" keyword. In the search results, except for one post that contains the "breakfast" keyword on its title (Lite breakfast with bread), there are two different posts with the "breakfast" keyword in the Type custom field. It means the advanced searching feature worked properly.

<img class="aligncenter" src="https://i.imgur.com/UW5AMNQ.png" alt="The advanced search feature worked well" width="1127" height="593" />

<h2>Last Words</h2>

Joining <code>wp_posts</code> and <code>wp_postmeta</code> tables together and editing the query will save more time and effort than the first method of this series. The reason is that we will query by SQL and don't need to create a page template.

Getting posts by custom field can be utilized to create an advanced search that helps users find their desired results quickly, easily, and appropriately. You should absolutely use this feature to improve the user experience! Besides, you may like <a href="https://metabox.io/create-advanced-search-box-wordpress/">this article</a> on how to create an advanced search box in WordPress.

<hr />

The publication at <a href="https://metabox.io/get-post-custom-field-wordpress-p2/">Meta Box</a>.