Thursday 25 May 2023

Enable WordPress to Search Custom Fields (PODS etc) and Display Automatically Generated Excerpt

 By default, WordPress doesn't allow searching on dynamically generated pages, but if a search matches the title then it will not display any content in the search results!  There are many plugins that can improve this but so can a little bit of PHP code.

The following code allows standard WordPress to search within the extended fields (which is stored as meta data):

 

//=======================================================

function AddCustomFieldsToSearchText($query)

//      https://wordpress.org/support/topic/default-wordpress-search-does-not-work/

//      This allows Wordpress Search to search pods fields as well as it's normal content.

//=======================================================

{

    //--- Abort if we shouldn't perform the following code ------------------

    //if (! is_main_query() )           //Function is_main_query was called <strong>incorrectly</strong>. In <code>pre_get_posts</code>, use the <code>WP_Query->is_main_query()</code> method, not the <code>is_main_query()</code> function. See https://developer.wordpress.org/reference/functions/is_main_query/. Please see <a href="https://wordpress.org/support/article/debugging-in-wordpress/">Debugging in WordPress</a> for more information. (This message was added in version 3.7.0.) in /home/wcipporg/public_html/wp-includes/functions.php on line 5865

    //   return;

    if (! $query->is_main_query())

        return;

    if (! is_search() )

        return;



    add_filter( 'posts_join',

                function( $join )

                {

                    global $wpdb;

                    return $join .' LEFT JOIN ' . $wpdb->postmeta . ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';

                }

              );


    add_filter( 'posts_where',

                function ( $where )

                {

                    global $wpdb;


                    $or = array(

                                    "(".$wpdb->posts.".post_title LIKE $1)",

                                    "(".$wpdb->postmeta.".meta_value LIKE $1)",

                               );


                    if ( is_main_query() && is_search() )

                    {

                        $where = preg_replace(

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

                                                implode( ' OR ', $or ),

                                                $where

                                             );

                    }

                    return $where;

                }

              );


    add_filter( 'posts_distinct',

                function ()

                {

                    global $wpdb;

                    return "DISTINCT";

                }

              );

}

add_action( 'pre_get_posts', 'AddCustomFieldsToSearchText', 9 );

Now, for the excerpt,  you need to make sure it is enabled/supported (PODS Advanced).  That adds the field allowing you to manually enter it, but we will automatically add it after the POD (page) is saved.

In the following code, I use a PODS-specific hook but with a little variation to the code, you could also use the WordPress "save_post" hook:


//==============================================

function PLANT_post_save_function($pieces, $is_new_item, $PlantId)

// https://stackoverflow.com/questions/38049208/set-wordpress-excerpt-and-post-thumbnail-based-on-custom-field

//==============================================

{

    //$post_excerpt   = get_the_excerpt( $PlantId );               //Get Excerpt


    //--- Work out the New Excerpt ------------------------------------------

    $PrevBotanicalNames = $pieces['fields']['plant_previous_botanical_names']['value'];

    $CnArray            = $pieces['fields']['plant_common_names']['value'];

    $Size               = trim( $pieces['fields']['plant_size']['value'] );

    $Flowers            = trim( $pieces['fields']['plant_flowers']['value'] );

    $GeneralComments    = trim( $pieces['fields']['plant_general_comments']['value'] );

    $AKA                = PlantAKA($PrevBotanicalNames, $CnArray);

    $NE = "Australian native plant";

    if  ($AKA != '')

        $NE = 'An ' . $NE . ', also known as: <b>' . $AKA . '</b>';

    if  ($Size != '')

        $NE = $NE . '<br><b>SIZE:</b> ' . $Size;

    if  ($Flowers != '')

        $NE = $NE . '<br><b>FLOWERS:</b> ' . $Flowers;

    if  ($Flowers != '')

        $NE = $NE . '<br><b>COMMENTS:</b> ' . $GeneralComments;


    //--- Set up the array to save the Excerpt ------------------------------

    $post_array = array(

                            'ID'            => $PlantId,

                            'post_excerpt'  => $NE,

                       );



    //--- Saving ------------------------------------------------------------

    remove_action('pods_api_post_save_pod_item_plant', 'PLANT_post_save_function');

                    wp_update_post( $post_array );

    add_action('pods_api_post_save_pod_item_plant', 'PLANT_post_save_function', 10, 3);

}

add_action('pods_api_post_save_pod_item_plant', 'PLANT_post_save_function', 10, 3);


No comments: