Here’s how you can list posts on a page using ACF field values within a shortcode. This solution involves adding a custom PHP function to your WordPress theme’s functions.php
file or a custom plugin.
I’ll provide the PHP code for the shortcode, along with instructions on how to use it.
<?php /** * Custom Shortcode to List Posts Based on ACF Field Value * * This code should be added to your theme's functions.php file * or a custom WordPress plugin. */ function custom_acf_post_list_shortcode($atts) { // Define default attributes for the shortcode $atts = shortcode_atts( array( 'field_name' => '', // The name of your ACF field 'field_value' => '', // The value to match in the ACF field 'post_type' => 'post', // The post type to query (e.g., 'post', 'page', 'custom_post_type') 'posts_per_page' => -1, // Number of posts to show (-1 for all) 'order' => 'DESC', // Order of posts (ASC or DESC) 'orderby' => 'date', // How to order posts (e.g., 'date', 'title', 'menu_order') ), $atts, 'acf_posts' // The name of your shortcode ); $field_name = sanitize_text_field($atts['field_name']); $field_value = sanitize_text_field($atts['field_value']); $post_type = sanitize_text_field($atts['post_type']); $posts_per_page = intval($atts['posts_per_page']); $order = sanitize_text_field($atts['order']); $orderby = sanitize_text_field($atts['orderby']); // Validate required attributes if (empty($field_name) || empty($field_value)) { return '<p>Error: Please specify both "field_name" and "field_value" in the [acf_posts] shortcode.</p>'; } // Prepare the meta query for WP_Query $meta_query = array( array( 'key' => $field_name, 'value' => $field_value, 'compare' => '=', // You can use '=', 'LIKE', 'IN', etc. 'type' => 'CHAR', // Data type of the field (e.g., 'CHAR', 'NUMERIC', 'DATE') ), ); // Arguments for WP_Query $args = array( 'post_type' => $post_type, 'posts_per_page' => $posts_per_page, 'order' => $order, 'orderby' => $orderby, 'meta_query' => $meta_query, 'post_status' => 'publish', // Only get published posts 'suppress_filters' => false, // Important for ACF to work correctly with meta_query ); // Create a new WP_Query instance $query = new WP_Query($args); $output = ''; // Check if there are any posts if ($query->have_posts()) { $output .= '<ul>'; while ($query->have_posts()) { $query->the_post(); $output .= '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>'; } $output .= '</ul>'; // Restore original post data wp_reset_postdata(); } else { $output .= '<p>No posts found matching the criteria.</p>'; } return $output; } add_shortcode('acf_posts', 'custom_acf_post_list_shortcode');
How to Use This Code:
- Add the Code to WordPress:
- Recommended: Create a custom plugin. This is the best practice as it keeps your functionality separate from your theme, so it won’t be lost if you change themes.
- Alternative: Add the code to your theme’s
functions.php
file. Go toAppearance > Theme File Editor
(or use an FTP client/cPanel file manager) and openfunctions.php
. Paste the code at the end of the file, before the closing?>
tag if it exists.
- Using the Shortcode in a Page or Post: Once the code is added, you can use the
[acf_posts]
shortcode in any page, post, or even a text widget in WordPress.Here are some examples:- Basic Usage (matching a specific value for an ACF field named ‘city’):
[acf_posts field_name="city" field_value="New York"]
- Specifying a Custom Post Type (e.g., ‘event’ post type, matching ‘status’ field with ‘upcoming’):
[acf_posts field_name="status" field_value="upcoming" post_type="event"]
- Limiting the number of posts and ordering by title:
[acf_posts field_name="category_type" field_value="premium" posts_per_page="5" orderby="title" order="ASC"]
- Basic Usage (matching a specific value for an ACF field named ‘city’):
Explanation:
custom_acf_post_list_shortcode($atts)
function: This is the core function that runs when the shortcode[acf_posts]
is encountered.shortcode_atts()
: This function merges the default attributes with the attributes provided in the shortcode, ensuring that all necessary parameters have a value.sanitize_text_field()
andintval()
: These are crucial for security, sanitizing the input from the shortcode attributes.$meta_query
: This is the key part for ACF integration. It tellsWP_Query
to look for posts where a specific custom field (key
) has a certainvalue
.'compare' => '='
: Means the value must exactly match. You can change this toLIKE
(for partial matches),IN
(iffield_value
is a comma-separated list), etc.'type' => 'CHAR'
: Specifies the data type of the custom field. Common types includeCHAR
(text),NUMERIC
,DATE
,DATETIME
,DECIMAL
,SIGNED
,UNSIGNED
. Choose the one that matches your ACF field’s data type for accurate comparisons.
WP_Query
: This is the standard WordPress class for querying posts. It uses the$args
array to define what posts to retrieve.- Looping through posts:
if ($query->have_posts()) { ... }
checks if any posts were found.while ($query->have_posts()) { $query->the_post(); ... }
iterates through each post, making its data available for functions likeget_permalink()
andget_the_title()
. wp_reset_postdata()
: This is essential after using a customWP_Query
to restore the global post data to the main query, preventing conflicts with other parts of your page.add_shortcode('acf_posts', 'custom_acf_post_list_shortcode');
: This line registers your shortcode with WordPress, linking the shortcode tagacf_posts
to your PHP function.
This shortcode provides a flexible way to display dynamic lists of posts based on your Advanced Custom Fields data.