为复杂的自定义帖子类型创建自定义搜索页面的正确方法

时间:2011-08-14 作者:tollmanz

我正在尝试创建一个自定义搜索页面,以仅显示符合特定搜索条件的自定义帖子类型。我有一个复杂的表单,包括不同的选择、单选按钮和文本输入字段。我很乐意使用WP\\u Query类来查询通过搜索表单识别的帖子,但我不确定是否应该创建其他模板或使用内置搜索页面。

让我举一个例子来帮助你传达我的难题。假设你有一个CPT“人”。每个人都有“出生日期”、“性别”、“身高”和“体重”。你想搜索1972年以后出生的所有身高超过6英尺的男性。您将如何进行此搜索?同样,我可以很容易地把$args WP\\u Query类获取这些帖子。我需要知道将此与WordPress集成的最佳方法。

最终,我需要一个满足以下条件的解决方案:

1) 在搜索页面上保留分页2)仅搜索特定的CPT,而不搜索其他CPT

我有以下问题

1) 我应该为此单独设置一个模板,还是可以直接将其与search.php? 我目前的解决方案让人感觉很粗糙,我想开发一种替代方案。我已经在WP admin中创建了一个新页面。我使用此页面的URL作为action 属性。然后,我使用自定义模板显示该页面的结果。我觉得这是不对的。

2) 如果我将此与search.php 除了这些可爱的自定义搜索结果之外,我如何保存常规搜索结果?

非常感谢您的帮助!

编辑:进一步调查后,我开始认为pre_get_posts 可能会以一种“更好的方式”参与进来。

1 个回复
最合适的回答,由SO网友:tollmanz 整理而成

我找到了一种方法来实现这一点。我的想法是对的pre_get_posts 就是要走的路。首先,我添加了一个操作:

// Filter the search page
add_filter(\'pre_get_posts\', \'search_pre_get_posts\');
然后我添加了函数。此函数首先检查上下文是否正确。在自定义搜索表单中,我使用nonce。nonce帮助我验证正在运行的是我的自定义搜索,而不是内置搜索。然后,我操作将发送到查询的查询变量。我在这里展示了我的全部功能,其中包括所有变量的验证和清理,以及如何操作查询:

/**
 * Filters for search of events
 *
 * When a search is initiated, this filter will check to see if it is an
 * event search. If so, it will process the search data associated with
 * event searches and add it to the $query object prior to it being used
 * to query the database.
 *
 * @param $query The query object generated for this page
 * @return void
 */
function search_pre_get_posts($query)
{
    // Verify that we are on the search page that that this came from the event search form
    if($query->query_vars[\'s\'] != \'\' && is_search() && isset($_GET[\'prefix-submitted\']) && $_GET[\'prefix-submitted\'] && wp_verify_nonce($_GET[\'prefix-search-nonce\'], \'prefix-search\'))
    {
        // Always order by date
        $query->set(\'orderby\', \'meta_value\');
        $query->set(\'order\', \'ASC\');
        $query->set(\'meta_key\', \'_datetime-from\');

        // Set the text string for the search
        $clean_text = (isset($_GET[\'prefix-text\'])) ? wp_strip_all_tags($_GET[\'prefix-text\']) : \'\';
        $query->set(\'s\', $clean_text);

        // Validate dates
        $clean_from = (isset($_GET[\'prefix-from\'])) ? $this->handle_date($_GET[\'prefix-from\']) : false;
        $clean_to = (isset($_GET[\'prefix-to\'])) ? $this->handle_date($_GET[\'prefix-to\']) : false;

        // Validate taxonomies
        $clean_type = (isset($_GET[\'prefix-type\'])) ? $this->handle_taxonomy_id($_GET[\'prefix-type\'], \'prefix-type\') : false;
        $clean_location = (isset($_GET[\'prefix-location\'])) ? $this->handle_taxonomy_id($_GET[\'prefix-location\'], \'prefix-location\') : false;

        // Build meta_query variable based on date pieces
        if($clean_from && $clean_to)
        {
            $meta_query = array(
                array(
                    \'key\' => \'_datetime-from\',
                    \'value\' => array($clean_from, $clean_to),
                    \'compare\' => \'BETWEEN\',
                    \'type\' => \'DATE\'
                )
            );
        }
        elseif($clean_from)
        {
            $meta_query = array(
                array(
                    \'key\' => \'_datetime-from\',
                    \'value\' => $clean_from,
                    \'compare\' => \'>=\',
                    \'type\' => \'DATE\'
                )
            );
        }
        elseif($clean_to)
        {
            $meta_query = array(
                array(
                    \'key\' => \'_datetime-from\',
                    \'value\' => $clean_from,
                    \'compare\' => \'>=\',
                    \'type\' => \'DATE\'
                )
            );
        }
        else
            $meta_query = \'\';

        // Set the meta query
        $query->set(\'meta_query\', $meta_query);

        // Build tax query based on taxonomy pieces
        if($clean_type && $clean_location)
        {
            $tax_query = array(
                \'relation\' => \'AND\',
                array(
                    \'taxonomy\' => \'prefix-type\',
                    \'field\' => \'id\',
                    \'terms\' => $clean_type,
                    \'operator\' => \'IN\'
                ),
                array(
                    \'taxonomy\' => \'prefix-location\',
                    \'field\' => \'id\',
                    \'terms\' => $clean_location,
                    \'operator\' => \'IN\'
                )
            );
        }
        elseif($clean_type)
        {
            $tax_query = array(
                array(
                    \'taxonomy\' => \'prefix-type\',
                    \'field\' => \'id\',
                    \'terms\' => $clean_type,
                    \'operator\' => \'IN\'
                )
            );
        }
        elseif($clean_location)
        {
            $tax_query = array(
                array(
                    \'taxonomy\' => \'prefix-location\',
                    \'field\' => \'id\',
                    \'terms\' => $clean_location,
                    \'operator\' => \'IN\'
                )
            );
        }
        else
            $tax_query = \'\';

        // Set the tax query
        $query->set(\'tax_query\', $tax_query);
    }
}

结束

相关推荐

Custom post_type search pages

因此,我的网站上有一个专门搜索YouTube视频自定义帖子类型的部分。我完全可以搜索自定义类型。然而,我不确定如何创建一个具有针对这种类型搜索的自定义格式的搜索页面。我在youtube上创建了一个自定义循环。php并在搜索中修改。phpget_template_part( \'loop\'); 到get_template_part( \'loop\', \'youtube\'); 但是,它会全局影响搜索结果。是否有创建自定义搜索的方法。特定post\\u类型的php页面?谢谢你的帮助。