これは実際にはあまり技術的な問題ではありませんが、私が話したいトピックへのイントロのようなものです。
そのため、カスタム投稿タイプ、カスタム分類法、年数、および順序に従って投稿を取得する必要があるアドバンストサーチカスタムページを作成するのは今回が初めてです。
問題は、ここにスターを付ける方法が私には本当にわかっていないということです。私はインターネットでチュートリアルやスニペットを探していましたが、どうにかしてドロップダウンで動作することはできません(なぜなのかわかりません)。
それで、あなたがどんな推薦または機能コードで私に言うことができるか。
前もって感謝します。
これは私が使いたい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><b>Your browser does not support Javascript, this making it unable to display the posts.</b></noscript>
<div id="resultados"><div class="cargando_medio"></div></div>
</div>
以下はpost_view_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アドレスごとと1日ごとにビューを数えたいと思うので。現在のところ、現在のページや投稿で行った更新ごとにビューを数えることで実行しています。
これを試して:
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
要素/メニューに適切なIDを設定してください。また、「注文」列に「注文」フィールドを追加し、送信/検索ボタンの前に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><b>Your browser does not support Javascript, this making it unable to display the posts.</b></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();
} );
} );
注
ajax_my_adv_search()
PHP関数では、tax_query
をWP_Query
呼び出しで使用しませんでした。これは、指定された分類キー(たとえば、標準投稿カテゴリの場合はcategory
、標準投稿タグの場合はpost_tags
であり、分類内のtermには含まれません。したがって、posts_join
のposts_where
およびWP_Query
フックを使用して、このような種類のクエリに対して適切な結果を取得しました。
ajax_my_adv_search()
PHP関数では、posts_orderby
でWP_Query
フックも使用しました。なぜなら、sorting年ごとの投稿/結果は、デフォルトでWP_Query
クラスでは利用できません。