如何创建高级过滤器搜索?

时间:2018-04-17 作者:Kirasiris

这不是一个真正的技术问题,但更像是对我想谈论的主题的介绍。

因此,这是我第一次创建高级搜索自定义页面,在该页面中,我需要根据自定义帖子类型、自定义分类法、年份和排序依据获取帖子。

问题是我真的不知道如何在这里出演。我一直在互联网上寻找教程或片段,但我找到的所有东西都无法使用下拉菜单(为什么?我不知道),我找到的所有教程都是关于使用复选框的。

你们有什么建议或函数代码可以告诉我吗?。

提前谢谢。

这是我要使用的HTML代码:

<!-- Post Type -->
<div class="col-md-3">
    <div class="form-group">
        <label for="post_type">Post Type</label>
        <select class="form-control">
            <option>Any</option>
            <option>Post</option>
            <option>Portfolio</option>
            <option>Snippet</option>
        </select>
    </div>
</div>

<!-- Taxonomy -->
<div class="col-md-3">
    <div class="form-group">
        <label for="post_type">Taxonomy</label>
        <select class="form-control" multiple>
            <option>Any</option>
            <option>category</option>
            <option>portfolio_categories</option>
            <option>snippets_categories</option>
        </select>
    </div>
</div>

<!-- Year -->
<div class="col-md-3">
    <div class="form-group">
        <label for="post_type">Year</label>
        <select class="form-control">
            <option>Any</option>
            <option>2018</option>
            <option>2017</option>
            <option>2016</option>
            <option>2015</option>
            <option>2014</option>
        </select>
    </div>
</div>

<!-- Orderby -->
<div class="col-md-3">
    <div class="form-group">
        <label for="post_type">Order by</label>
        <select class="form-control" multiple>
            <option>Any</option>
            <option>Author</option>
            <option>Popularity (# of Comments)</option>
            <option>Views post_views_count</option>
            <option>Year</option>
            <option>ASC</option>
            <option>DESC</option>
        </select>
    </div>
</div>

<!-- Search Button -->
<div class="col-md-12">
    <input type="submit" class="btn btn-primary" id="buscar_btn" value="Search">
    <noscript>&lt;b&gt;Your browser does not support Javascript, this making it unable to display the posts.&lt;/b&gt;</noscript>
    <div id="resultados"><div class="cargando_medio"></div></div>
</div>
以下是post\\u view\\u count自定义字段的函数:

// Function to display number of views.
function getPostViews($postID){
    $count_key = \'post_views_count\';
    $count = get_post_meta($postID, $count_key, true);
    if($count==\'\'){
        delete_post_meta($postID, $count_key);
        add_post_meta($postID, $count_key, \'0\');
        return "0 Views";
    }
    return $count.\' Views\';
}

// Function to count views.
function setPostViews($postID) {
    $count_key = \'post_views_count\';
    $count = get_post_meta($postID, $count_key, true);
    if($count==\'\'){
        $count = 0;
        delete_post_meta($postID, $count_key);
        add_post_meta($postID, $count_key, \'0\');
    }else{
        $count++;
        update_post_meta($postID, $count_key, $count);
    }
}


// Add it to a column in WP-Admin
function posts_column_views($defaults){
    $defaults[\'post_views\'] = __(\'Views\');
    return $defaults;
}
add_filter(\'manage_posts_columns\', \'posts_column_views\');
function posts_custom_column_views($column_name, $id){
    if($column_name === \'post_views\'){
        echo getPostViews(get_the_ID());
    }
}
add_action(\'manage_posts_custom_column\', \'posts_custom_column_views\',5,2);
功能不是很好,实际上不是很好,但它确实起作用了。我以后可能不得不更改它,特别是因为我想让它计算每个IP地址和每天的浏览量;目前,它是通过计算我在当前页面/帖子中每次刷新的浏览量来实现的。

enter image description here

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

尝试以下操作:

PHP

add_action( \'wp_ajax_my_adv_search\', \'ajax_my_adv_search\' );
add_action( \'wp_ajax_nopriv_my_adv_search\', \'ajax_my_adv_search\' );
function ajax_my_adv_search() {
    if ( ! check_ajax_referer( \'my-adv-search\', \'q_nonce\', false ) ) {
        echo \'session_expired\';
        wp_die();
    }

    $post_type = isset( $_POST[\'q_post_type\'] ) ? $_POST[\'q_post_type\'] : \'\';
    $taxonomy = isset( $_POST[\'q_taxonomy\'] ) ? $_POST[\'q_taxonomy\'] : [];
    $year = isset( $_POST[\'q_year\'] ) ? $_POST[\'q_year\'] : \'\';
    $orderby = isset( $_POST[\'q_orderby\'] ) ? $_POST[\'q_orderby\'] : [];
    $order = isset( $_POST[\'q_order\'] ) ? $_POST[\'q_order\'] : \'\';

    // Note that if $post_type is \'any\', all post statuses will be included. In
    // that case, you may want to set specific post statuses below.
    $post_status = \'\';

    $taxonomy = array_filter( (array) $taxonomy );
    if ( ! in_array( \'any\', $taxonomy ) ) {
        $taxonomy = array_unique( array_map( \'trim\', $taxonomy ) );

        add_filter( \'posts_join\', function( $c ) use ( $taxonomy ) {
            if ( ! empty( $taxonomy ) ) {
                global $wpdb;
                // 1 below is one/number and not the lowercase of L
                $c .= " INNER JOIN {$wpdb->term_relationships} AS ctr1 ON ctr1.object_id = {$wpdb->posts}.ID" .
                    " INNER JOIN {$wpdb->term_taxonomy} AS ctt1 ON ctt1.term_taxonomy_id = ctr1.term_taxonomy_id";
            }
            return $c;
        } );

        add_filter( \'posts_where\', function( $c ) use ( $taxonomy ) {
            if ( ! empty( $taxonomy ) ) {
                $tax_list = array_map( \'esc_sql\', $taxonomy );
                $tax_list = "\'" . implode( "\', \'", $tax_list ) . "\'";

                // 1 below is one/number and not the lowercase of L
                $c .= " AND ( ctt1.taxonomy IN ($tax_list) )";
            }
            return $c;
        } );
    }

    if ( ! is_numeric( $year ) ) {
        $year = \'\';
    }

    $orderby = array_filter( (array) $orderby );
    if ( in_array( \'any\', $orderby ) ) {
        // Don\'t sort by post date.
        $orderby2 = false;
    } else {
        $orderby = array_unique( array_map( \'trim\', $orderby ) );

        // TRUE if we\'re sorting by year.
        $ob_year = false;

        foreach ( $orderby as $i => $s ) {
            // Sort posts by year.
            if ( \'year\' === $s ) {
                $ob_year = true;
                unset( $orderby[ $i ] );
            }

            // Sort posts by views count. Note that this would only return
            // posts that have the custom field \'post_views_count\'.
            if ( \'views_count\' === $s ) {
                $meta_key = \'post_views_count\';
                $orderby2 = \'meta_value_num\';
                unset( $orderby[ $i ] );
            }
        }

        add_filter( \'posts_orderby\', function( $c, $q ) use ( $ob_year ) {
            if ( $ob_year ) {
                global $wpdb;

                // Use the value parsed by WP_Query.
                $order = $q->get( \'order\' );

                $c .= $c ? \', \' : \'\';
                $c .= "YEAR({$wpdb->posts}.post_date) $order";
            }
            return $c;
        }, 10, 2 );

        $ok = isset( $orderby2 );
        if ( ! $ok && empty( $orderby ) ) {
            // Don\'t sort by post date.
            $orderby2 = false;
        } elseif ( ! $ok ) {
            // Pass to WP_Query as a string.
            $orderby2 = implode( \' \', $orderby );
        }
    }

    $q = new WP_Query( [
        \'post_status\' => $post_status,
        \'post_type\'   => $post_type,
        \'year\'        => $year,
        \'meta_key\'    => isset( $meta_key ) ? $meta_key : \'\',
        \'orderby\'     => $orderby2,
        \'order\'       => $order,
    ] );

    if ( $q->have_posts() ) {
        echo \'<ul>\';
        while ( $q->have_posts() ) {
            $q->the_post();

            echo \'<li>\';
                the_title(); echo \'; ID: \'; the_ID();
            echo \'</li>\';
        }
        echo \'</ul>\';
    } else {
        echo \'<p>No posts found.</p>\';
    }

    wp_die();
}

HTML

查看下面的“表单”,确保在相应的select 元素/菜单。您还需要在“order by”列中添加“order”字段,并在提交/搜索按钮之前添加nonce字段。

<div id="my-adv-search">
<!-- Post Type -->
<div class="col-md-3">
    <div class="form-group">
        <label for="q_post_type">Post Type</label>
        <select class="form-control" id="q_post_type">
            <option value="any" selected>Any</option>
            ...
        </select>
    </div>
</div>

<!-- Taxonomy -->
<div class="col-md-3">
    <div class="form-group">
        <label for="q_taxonomy">Taxonomy</label>
        <select class="form-control" multiple id="q_taxonomy">
            <option value="any" selected>Any</option>
            ...
        </select>
    </div>
</div>

<!-- Year -->
<div class="col-md-3">
    <div class="form-group">
        <label for="q_year">Year</label>
        <select class="form-control" id="q_year">
            <option value="any" selected>Any</option>
            ...
        </select>
    </div>
</div>

<!-- Orderby -->
<div class="col-md-3">
    <div class="form-group">
        <label for="q_orderby">Order by</label>
        <select class="form-control" multiple id="q_orderby">
            <option value="any" selected>Any</option>
            <?php
            foreach ( [
              \'author\'        => \'Author\',
              \'comment_count\' => \'Popularity (# of Comments)\',
              \'year\'          => \'Year\',
              \'views_count\'   => \'Views\',
            ] as $value => $label ) {
              printf( \'<option value="%s">%s</option>\',
                esc_attr( $value ), esc_html( $label ) );
            }
            ?>
        </select>
    </div>
    <label class="radio-inline">
      <input type="radio" name="order" id="q_order-asc" value="ASC" />
      ASC
    </label>
    <label class="radio-inline">
      <input type="radio" name="order" id="q_order-desc" value="DESC" checked />
      DESC
    </label>
</div>

<!-- Nonce field. -->
<?php wp_nonce_field( \'my-adv-search\', \'q_nonce\' ); ?>

<!-- Search Button -->
<div class="col-md-12">
    <input type="submit" class="btn btn-primary" id="buscar_btn" value="Search">
    <noscript>&lt;b&gt;Your browser does not support Javascript, this making it unable to display the posts.&lt;/b&gt;</noscript>
    <div id="resultados"><div class="cargando_medio"></div></div>
</div>
</div><!-- End #my-adv-search -->

JS/jQuery/AJAX

下面是一个执行AJAX搜索的JS/jQuery脚本示例。

jQuery( function( $ ){
    var ajaxurl = \'/path/to/wp-admin/admin-ajax.php\';

    function searchPosts( btn ) {
        var _btn_text = btn.value,
            q_order;

        btn.disabled = true;
        btn.value = \'Searching..\';

        q_order = $( \'#q_order-asc\' ).is( \':checked\' ) ?
            \'ASC\' : \'DESC\';

        return $.post( ajaxurl, {
            action: \'my_adv_search\',
            q_nonce: $( \'#q_nonce\' ).val(),
            q_post_type: $( \'#q_post_type\' ).val(),
            q_taxonomy: $( \'#q_taxonomy\' ).val(),
            q_year: $( \'#q_year\' ).val(),
            q_orderby: $( \'#q_orderby\' ).val(),
            q_order: q_order,
        } ).done( function( s ){
            if ( \'session_expired\' === s ) {
                location.reload();
                return;
            }

            $( \'#resultados\' ).html( s );
        } ).always( function(){
            btn.value = _btn_text;
            btn.disabled = false;
        } );
    }

    $( \'#buscar_btn\', \'#my-adv-search\' ).on( \'click\', function( e ){
        e.preventDefault();

        // Run AJAX search.
        searchPosts( this );

        // Remove button focus.
        this.blur();
    } );
} );

Notes

<在ajax_my_adv_search() PHP函数,我没有使用tax_query 使用WP_Query 调用,因为我们正在查询位于其中一个指定分类键中的帖子(例如。category 对于标准职位类别,以及post_tags 对于标准Post标记),而不是在分类法内的术语中。因此,我使用posts_joinposts_where 钩住WP_Query 获取此类查询的正确结果。

中的ajax_my_adv_search() PHP函数,我还使用了posts_orderby 钩住WP_Query 因为默认情况下,按年度排序帖子/结果在WP_Query

结束

相关推荐

Search Issue in the theme

如果我的理解没有错的话☻search.php 负责渲染部分和serachform.php 负责触发搜索事件,对吗?示例searchform.php 可能看起来像这样→<form role=\"search\" method=\"get\" class=\"search-form\" action=\"<?php echo home_url( \'/\' ); ?>\"> <label> <span class=\"scree