O caminho certo para criar uma página de pesquisa personalizada para tipos de postagem personalizados complexos

4

Estou tentando criar uma página de pesquisa personalizada para mostrar apenas os tipos de postagens personalizadas que atendem a critérios de pesquisa específicos. Eu tenho um formulário complexo que envolve diferentes seleções, botões de opção e campos de entrada de texto. Fico à vontade ao usar a classe WP_Query para consultar as postagens identificadas por meio do formulário de pesquisa, mas não tenho certeza se devo criar modelos adicionais ou usar a página de pesquisa incorporada.

Deixe-me dar-lhe um exemplo para ajudar a comunicar meu enigma. Imagine que você tenha o CPT "Person". Para cada pessoa, você tem "Data de Nascimento", "Sexo", "Altura" e "Peso". Você quer procurar por todos os machos nascidos após 1972, que são mais altos do que 6 pés de altura. Como você trabalharia com essa pesquisa? Mais uma vez, posso facilmente juntar $args para a classe WP_Query para obter essas mensagens. Eu preciso saber a melhor maneira de integrar isso com o WordPress.

Por fim, preciso de uma solução que satisfaça o seguinte:

1) Preserva a paginação na página de pesquisa 2) Só procura o CPT específico, não outros CPTs

E eu tenho as seguintes perguntas

1) Devo ter um modelo separado para isso, ou posso integrar isso diretamente com search.php ? Minha solução atual parece hacky e eu gostaria de desenvolver uma alternativa. Eu criei uma nova página no administrador do WP. Eu uso o URL desta página como o atributo action no formulário de pesquisa. Em seguida, uso um modelo personalizado para exibir os resultados dessa página. Isso parece errado para mim.

2) Se eu integrar isso com search.php , como preservo os resultados de pesquisa regulares, além de ter esses resultados de pesquisa personalizados incríveis?

Muito obrigado pela sua ajuda!

EDIT: Em uma investigação mais aprofundada, estou começando a pensar que pre_get_posts provavelmente estará envolvido em uma "maneira melhor" de fazer isso.

    
por tollmanz 14.08.2011 / 21:19

1 resposta

3

Eu encontrei uma maneira de fazer isso funcionar. Eu estava certo com o pensamento de que pre_get_posts era o caminho a percorrer. Primeiro, adicionei uma ação:

// Filter the search page
add_filter('pre_get_posts', 'search_pre_get_posts');

Então eu adicionei a função. Esta função primeiro verifica se o contexto está correto. No meu formulário de pesquisa personalizado, uso um nonce. O nonce me ajuda a verificar se a minha pesquisa personalizada está sendo executada, e não a pesquisa integrada. Eu então manipulo as variáveis de consulta que serão enviadas para a consulta. Estou mostrando minha função completa aqui, que inclui toda a validação e sanitização de variáveis, bem como a forma como a consulta é manipulada:

/**
 * 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);
    }
}
    
por tollmanz 22.08.2011 / 06:53