• 解決済 firth

    (@firth)


    大きなサイトに、記事を絞り込む方法として
    投稿日時が
    ・1か月以内
    ・1週間以内
    ・1日以内
    という方法で絞り込むことが出来る場合がありますが、

    このような絞り込みを
    ・検索する時
    ・category.php
    ・search.php
    で出来るようにしたいと考えています。

    コードでもプラグインでも助かるのですが、
    どちらも調べたり探したりでも見つけられなかったので、
    教えてほしいです。

    少しでもいいので、情報をください

12件の返信を表示中 - 16 - 27件目 (全27件中)
  • トピック投稿者 firth

    (@firth)

    hissyさん
    丁寧に回答していただき、ありがとうございます。

    確認なのですが、
    以下のコードをfunctions.phpに

    function my_query_vars( $public_query_vars ) {
        $public_query_vars[] = 'start_date';
        return $public_query_vars;
    }
    function my_parse_query( $query ) {
        if ( $query->get('start_date') && !$query->is_category() ) {
            $query->is_search = true;
            $query->is_home = false;
        }
        return $query;
    }
    function my_search_where( $where, $query ) {
        if ( is_admin() || ! $query->is_main_query() )
            return $where;
    
        global $wpdb;
        if ( $query->is_search() || $query->is_category() ) {
            if ( $query->get('start_date') ) {
                $start_date = date('Y-m-d', strtotime($query->get('start_date')));
                $where .= " AND $wpdb->posts.post_date >= '$start_date'";
            }
        }
        return $where;
    }
    add_filter( 'query_vars', 'my_query_vars');
    add_filter( 'parse_query', 'my_parse_query');
    add_filter( 'posts_where', 'my_search_where', 10, 2 );

    以下のコードをカテゴリーアーカイブのページに

    <?php if(is_category()){
    	$cat_id = get_queried_object_id(); ?>
    	<form action="<?php echo home_url(); ?>" method="get">
    		<input type="hidden" name="cat" value="<?php echo $cat_id; ?>" />
    		<select name="start_date" onchange="submit(this.form)">
    		<option>絞り込み</option>
    		<option value="<?php echo date("Y-m-d",strtotime("-1 day")); ?>">1日前</option>
    		<option value="<?php echo date("Y-m-d",strtotime("-1 week")); ?>">1週間前</option>
    		<option value="<?php echo date("Y-m-d",strtotime("-1 month")); ?>">1月前</option>
    		<option value="<?php echo date("Y-m-d",strtotime("-1 year")); ?>">1年前</option>
    		</select>
    	</form>
    <?php } ?>

    それぞれ記述するという形で大丈夫でしょうか。

    私の作っているサイトで記述をしてみました。

    私は、<?php echo $wp_query->found_posts; ?>で
    投稿の件数を表示しているのですが、
    ここでの数字は変更されました。

    ですが、私は記事のタイトルを一覧で表示しているものの、
    一覧で表示される記事自体に変化がありませんでした。
    (説明が上手に出来なくて申し訳ありません。)

    という状況なのですが、
    他に必要な工夫などはあるのでしょうか。

    モデレーター Takuro Hishikawa

    (@hissy)

    カテゴリーアーカイブで、query_postsを使っていたりしませんか?

    トピック投稿者 firth

    (@firth)

    hissyさんがおっしゃってくださったように、
    たしかにquery_postsを使っていました。

    ただ、このquery_postsをはずすと、
    別の部分のコードが機能しなくなってしまう、
    という状況でした。

    調べてもよくわからなかったのですが、
    これは仕方のないことなのでしょうか?

    モデレーター Takuro Hishikawa

    (@hissy)

    query_postsは、WordPressがデータベースから取得するデータを完全に上書きしてしまうため、ページ送りが効かなくなる(ページ数のパラメータが無視されてしまう)などのトラブルをたびたび引き起こします。今回も同様に、start_dateのパラメータが無視されてしまっているものと思われます。query_postsを使わないのがいちばんすっきり解決できる方法ですが、いまから組み方を変えるのも難しいかと思いますので、まずは現状どのようにquery_postsが使われているか、コードを貼り付けてもらえますか?

    トピック投稿者 firth

    (@firth)

    自分のサイトで使われていたquery_postsは、
    このフォーラムのgakuseiさんとgqevu6bsizさんとのやりとりで
    作成されていました、
    記事一覧のソートをタクソノミーで出来るようにしたい
    というトピックで
    作られていた、記事一覧のソートのためのコードで
    query_postsが使われていました。

    ただ、さきほどフォーラムを見たところ、
    別のやりとりの部分で、hissyさんが作成していましたソートのコードを発見しました。
    このコードを入れて、今回の目的である日時での絞り込みを行ったところ、
    絞り込みができました。

    ただ、1点要質問というかお願いというかなのですが、
    hissyさんが作成していました、ソートのコードは
    ドロップダウンが3つ表示されるものでしたが、
    あのドロップダウンを1つにする(まとめる形というのでしょうか?)ことってできるのでしょうか?

    また、難しいようでしたら、
    gakuseiさんとgqevu6bsizさんとのやりとりで行われていたコードを
    使用したいので、
    gakuseiさんとgqevu6bsizさんとのやりとりでのコードで
    query_postsを使わないことはできるのでしょうか?

    話題がそれてしまい、申し訳ありません。

    モデレーター Takuro Hishikawa

    (@hissy)

    ドロップダウンを一つにまとめることも可能だと思いますよ。要は、URLにパラメーターを正しく渡せば、WordPressはソートして表示してくれる機能を標準で持っていますので。色々やり方はあると思いますが…。ちょっとすぐ思いつきませんが、Javascriptを使うことになると思います

    トピック投稿者 firth

    (@firth)

    hissyさんのコードをいろいろ変えてみようと思ったのですが、
    なかなか1つにすることが出来ませんでした。

    また、gakuseiさんとgqevu6bsizさんとのやりとりでのコードも
    query_postsが無い場合が分かりませんでした。

    ただ、hissyさんには何度もお答えをいただき、
    実際に投稿日時での絞り込みも出来るところまできたので、
    ぜひ、投稿日時に関するコードは使用したいと思っています。

    一方で、記事のソートも私にとっては必要な機能なので、
    使用できるようにしたいと思い、
    どちらか一方を諦める、というのを避けたいと思っています。

    なので、
    私も努力しますが、もしドロップダウンを1つにまとめ、
    query_postsのコードを使用しないような
    コードがあるようでしたら、ぜひ教えていただきたいです。

    長い期間申し訳ないですが、
    よろしくお願いします。

    firthさん

    http://ja.forums.wordpress.org/topic/21997?replies=6#post-61767
    こちらへのご質問ですが、おそらくこのトピックの延長だと思いましたので、こちらで回答することにしました。(間違いでしたらすみません)

    ドロップダウンを1つにまとめ、query_postsのコードを使用しないようなコード

    こちらについてですが、hissyさんからのコードをそのまま使用する場合、$public_query_varsにmeta_keyを追加するだけで可能ではないかと思います。

    function my_query_vars( $public_query_vars ) {
        $public_query_vars[] = 'start_date';
        $public_query_vars[] = 'meta_key';
        return $public_query_vars;
    }

    もしドロップダウンを1つにまとめ、

    こちらについては、

    • 一日前
    • 一週間前
    • カスタムフィールドA (昇順)
    • カスタムフィールドA (降順)
    • カスタムフィールドB

    のようにしたいのか、別のまとめ方なのか、ちょっと分かりませんでした。

    とりあえず、上記の場合についてのコードですが、

    <?php if(is_category()){
    	$cat_id = get_queried_object_id(); ?>
    	<form action="<?php echo home_url(); ?>" method="get" id="custom_form">
    		<input type="hidden" name="cat" value="<?php echo $cat_id; ?>" />
    
    		<select>
    			<option>絞り込み</option>
    			<option name="start_date" value="<?php echo date("Y-m-d",strtotime("-1 day")); ?>" <?php selected(get_query_var('start_date'),date("Y-m-d",strtotime("-1 day"))); ?>>1日前</option>
    			<option name="start_date" value="<?php echo date("Y-m-d",strtotime("-1 week")); ?>" <?php selected(get_query_var('start_date'),date("Y-m-d",strtotime("-1 week"))); ?>>1週間前</option>
    			<option name="orderby" data-order="asc" value="date" <?php if(get_query_var('orderby') == 'date') selected(get_query_var('order'),'asc'); ?>>日付の古い順</option>
    			<option name="orderby" data-order="desc" value="date" <?php if(get_query_var('orderby') == 'date') selected(get_query_var('order'),'desc'); ?>>日付の新しい順</option>
    			<option name="orderby" data-order="desc" value="meta_value_num" data-metakey="ratings_score" <?php if(get_query_var('orderby') == 'meta_value_num') if(get_query_var('meta_key') == 'ratings_score') selected(get_query_var('order'),'desc'); ?>>評価の高い順(総合)</option>
    			<option name="orderby" data-order="asc" value="meta_value_num" data-metakey="ratings_score" <?php if(get_query_var('orderby') == 'meta_value_num') if(get_query_var('meta_key') == 'ratings_score') selected(get_query_var('order'),'asc'); ?>>評価の低い順(総合)</option>
    		</select>
    
    	</form>
    <?php } ?>

    このようになるのではないかと思います。
    セレクトボックス選択時に動作させる機能は、このような感じで動くのではないかと思います。

    <script type="text/javascript">
    ( function() {
    
    	var form = document.getElementById( 'custom_form' ) , type , sort_type , sort_value , orderby;
    	if( ! form )
    		return;
    
    	type = form.getElementsByTagName( 'select' )[0];
    	type.onchange = function() {
    
    		var option = type.options[type.selectedIndex];
    		sort_type = option.getAttribute('name');
    		sort_value = option.value;
    
    		if( sort_type ) {
    
    			var orderby = document.createElement('input');
    			orderby.setAttribute('type', 'hidden');
    			orderby.setAttribute('name', sort_type);
    			orderby.setAttribute('value', sort_value);
    			form.appendChild( orderby );
    
    			if( sort_type != "start_date" ) {
    
    				var order = document.createElement('input');
    				order.setAttribute('type', 'hidden');
    				order.setAttribute('name', 'order');
    				order.setAttribute('value', option.getAttribute('data-order'));
    				form.appendChild( order );
    
    				if( sort_value == "meta_value_num" ) {
    
    					var meta_key = document.createElement('input');
    					meta_key.setAttribute('type', 'hidden');
    					meta_key.setAttribute('name', 'meta_key');
    					meta_key.setAttribute('value', option.getAttribute('data-metakey'));
    					form.appendChild( meta_key );
    
    				}
    
    			}
    
    			form.submit();
    
    		}
    
    	}
    
    } )();
    </script>

    ※Chromeのみ動作確認しました。

    トピック投稿者 firth

    (@firth)

    gqevu6bsizさん

    こちらの一方的かつわがままなご質問に対応していただき、
    本当にありがとうございます。
    こちらのトピックの延長です。

    追加的な質問になってしまい、申し訳ありません。

    まず、
    gqevu6bsizさんとgakuseiさんとのやりとりで
    作成されているコードで
    <?php query_posts( $args ); ?>を使用しない場合、

    function my_query_vars( $public_query_vars ) {
        $public_query_vars[] = 'start_date';
        $public_query_vars[] = 'meta_key';
        return $public_query_vars;
    }

    というコードの貼り付けで大丈夫なのでしょうか。

    また、
    「記事一覧のソートをpre_get_postsで出来るようにしたい」という
    タイトルで、以下のコードをhissyさんが紹介して下さっていましたが、

    <form action="<?php echo home_url(); ?>" method="get">
    <?php if(is_category()){
    	$cat_id = get_queried_object_id(); ?>
    	<input type="hidden" name="cat" value="<?php echo esc_attr($cat_id); ?>" />
    <?php } ?>
    <?php if(is_tag()){
    	$tag = get_query_var('tag'); ?>
    	<input type="hidden" name="tag" value="<?php echo esc_attr($tag); ?>" />
    <?php } ?>
    <?php if(is_search()){
    	$search = get_query_var('s'); ?>
    	<input type="hidden" name="s" value="<?php echo esc_attr($search); ?>" />
    <?php } ?>
    	<select name="orderby" onchange="submit(this.form)">
    		<option value="date" <?php selected(get_query_var('orderby'),'date'); ?>>日付</option>
    		<option value="title" <?php selected(get_query_var('orderby'),'title'); ?>>タイトル</option>
    		<option value="meta_value_num" <?php selected(get_query_var('orderby'),'meta_value_num'); ?>>カスタムフィールド</option>
    	</select>
    	<select name="meta_key" onchange="submit(this.form)">
    		<option value="">カスタムフィールド指定なし</option>
    		<option value="test_field_key" <?php selected(get_query_var('meta_key'),'test_field_key'); ?>>カスタムフィールド指定する</option>
    	</select>
    	<select name="order" onchange="submit(this.form)">
    		<option value="DESC" <?php selected(get_query_var('order'),'DESC'); ?>>降順</option>
    		<option value="ASC" <?php selected(get_query_var('order'),'ASC'); ?>>昇順</option>
    	</select>
    </form>

    このコードを1つにまとめたいということでした。
    自分の解釈が間違っていたら申し訳ないです。
    (このトピックでの、日付での絞りこみはまた別のドロップダウンにしたいと思っています。
     なので、日付での絞り込みと、記事一覧のソートを両方使えるようにしたいと
     いう感じです。
     そこで、gqevu6bsizさんのソートを使いたいのですが、gqevu6bsizさんの
     コードの最後のquery_postsと日時の絞り込みのコードとがぶつかってしまう、
     というところが問題のようです)

    そして、最後に記載していただいていますjavascriptは
    どこへ記載するのがよいのでしょうか?
    functions.phpに貼り付けたらエラーになってしまったので・・

    firthさん

    まず、

    というコードの貼り付けで大丈夫なのでしょうか。

    ここは少し意味が違います。正確には、

    $public_query_varsにmeta_keyを追加する

    です。

    おそらくhissyさんが書いたコード、

    function my_query_vars( $public_query_vars ) {
    $public_query_vars[] = ‘start_date’;
    return $public_query_vars;
    }
    function my_parse_query( $query ) {
    if ( $query->get(‘start_date’) && !$query->is_category() ) {
    $query->is_search = true;
    $query->is_home = false;
    }
    return $query;
    }
    function my_search_where( $where, $query ) {
    if ( is_admin() || ! $query->is_main_query() )
    return $where;

    global $wpdb;
    if ( $query->is_search() || $query->is_category() ) {
    if ( $query->get(‘start_date’) ) {
    $start_date = date(‘Y-m-d’, strtotime($query->get(‘start_date’)));
    $where .= ” AND $wpdb->posts.post_date >= ‘$start_date'”;
    }
    }
    return $where;
    }
    add_filter( ‘query_vars’, ‘my_query_vars’);
    add_filter( ‘parse_query’, ‘my_parse_query’);
    add_filter( ‘posts_where’, ‘my_search_where’, 10, 2 );

    こちらをfunctions.phpに記載していると思います。
    投稿日時での絞り込み機能と、カスタムフィールドの値等を元にしたソート機能どちらも機能させる為に、上記コードのmy_query_vars内に追加するという事でした。

    あと、ドロップダウンメニューについてですが、

    このトピックでの、日付での絞りこみはまた別のドロップダウンにしたいと思っています。
    なので、日付での絞り込みと、記事一覧のソートを両方使えるようにしたいという感じです。

    おそらくセレクトボックスは2つある。という事は分かったのですが、
    http://example.com/?cat=1&start_date=2000-01-01

    http://example.com/?cat=1&orderby=meta_value_num&order=asc&meta_key=example_key
    のような使い方を検討しているのか、

    http://example.com/?cat=1&start_date=2000-01-01&orderby=meta_value_num&order=asc&meta_key=example_key
    のような使い方を検討しているのか、”両方”という意味がどちらを指しているのかがわかりませんでした。

    とりあえず、前者と仮定した場合ですが、

    <form action="<?php echo home_url(); ?>" method="get">
    <?php if(is_category()){
    	$cat_id = get_queried_object_id(); ?>
    	<input type="hidden" name="cat" value="<?php echo esc_attr($cat_id); ?>" />
    <?php } ?>
    <?php if(is_tag()){
    	$tag = get_query_var('tag'); ?>
    	<input type="hidden" name="tag" value="<?php echo esc_attr($tag); ?>" />
    <?php } ?>
    <?php if(is_search()){
    	$search = get_query_var('s'); ?>
    	<input type="hidden" name="s" value="<?php echo esc_attr($search); ?>" />
    <?php } ?>
    	<select name="orderby" onchange="custom_sort(this.form)">
    		<option data-order="desc" value="date" <?php if(get_query_var('orderby') == 'date') selected(get_query_var('order'),'desc'); ?>>日付 (降順)</option>
    		<option data-order="asc" value="date" <?php if(get_query_var('orderby') == 'date') selected(get_query_var('order'),'asc'); ?>>日付 (昇順)</option>
    		<option data-order="desc" value="title" <?php if(get_query_var('orderby') == 'title') selected(get_query_var('order'),'desc'); ?>>タイトル (降順)</option>
    		<option data-order="asc" value="title" <?php if(get_query_var('orderby') == 'title') selected(get_query_var('order'),'asc'); ?>>タイトル (昇順)</option>
    		<option data-order="desc" value="meta_value_num" data-metakey="ratings_score" <?php if(get_query_var('meta_key') == 'ratings_score') selected(get_query_var('order'),'desc'); ?>>評価の高い順(総合)</option>
    		<option data-order="asc" value="meta_value_num" data-metakey="ratings_score" <?php if(get_query_var('meta_key') == 'ratings_score') selected(get_query_var('order'),'asc'); ?>>評価の低い順(総合)</option>
    		<option data-order="desc" value="meta_value_num" data-metakey="example_meta" <?php if(get_query_var('meta_key') == 'example_meta') selected(get_query_var('order'),'desc'); ?>>カスタムフィールド(降順)</option>
    		<option data-order="asc" value="meta_value_num" data-metakey="example_meta" <?php if(get_query_var('meta_key') == 'example_meta') selected(get_query_var('order'),'asc'); ?>>カスタムフィールド(昇順)</option>
    	</select>
    </form>

    1つにしたい場合、このようにする事もできます。この場合のjavascriptは、

    <script type="text/javascript">
    function custom_sort( form ) {
    
    	if( ! form )
    		return;
    
    	var sel = form.getElementsByTagName('select')[0];
    	var op = sel.options[sel.selectedIndex];
    
    	if( ! op.value )
    		return;
    
    	var order = document.createElement('input');
    	order.setAttribute('type', 'hidden');
    	order.setAttribute('name', 'order');
    	order.setAttribute('value', op.getAttribute('data-order'));
    	form.appendChild( order );
    
    	if( op.value == 'meta_value_num' ) {
    		var meta_key = document.createElement('input');
    		meta_key.setAttribute('type', 'hidden');
    		meta_key.setAttribute('name', 'meta_key');
    		meta_key.setAttribute('value', op.getAttribute('data-metakey'));
    		form.appendChild( meta_key );
    	}
    
    	form.submit();
    
    }
    </script>

    このようにすると機能すると思います。
    ※Chromeのみ動作確認。

    それと、

    javascriptはどこへ記載するのがよいのでしょうか?
    functions.phpに貼り付けたらエラーになってしまったので・・

    javascriptはHTMLとして出力するようにしてください。それと、ドロップダウメニューの仕組みが変わるとjavascriptも変更しないと動かない場合もあるので注意してください。

    javascript自体は、特にどこに記載しないといけないという事はなく、外部ファイルなりフッターなりいくらでも方法はあると思います。
    分からない場合は ドロップダウンメニューを貼り付けているファイル(category.php等)に貼り付けて試してみて下さい。

    トピック投稿者 firth

    (@firth)

    gqevu6bsizさん

    丁寧にご回答いただき、本当にありがとうございます。
    また、返信が遅くなってしまい、
    申し訳ありませんでした。

    $public_query_varsにmeta_keyを追加する

    ですが、私の理解力が足りなくて
    すいませんでした。
    理解して、導入することができました。ありがとうございます。

    また、ドロップダウンメニューについては、
    無事機能しました。
    1つにする、query_postsを使用しないという
    2つの大きな目標を達成できたので、
    大変感謝いたします。
    chrome以外(IEとfirefox)でも機能しました。
    javascriptは、ドロップダウンリストの下に貼り付けることにしました。

    そして、hissyさんが教えてくださいました、
    投稿日時の絞り込みも、ソートのドロップダウンリストと同時に
    機能させることが出来ました。

    gqevu6bsizさんには、突然のご質問に対応していただき、
    感謝いたします。
    また、hissyさんには、長期間にわたりまして、教えていただき
    感謝いたします。

    お2人には大変お世話になりました。
    理解力が足りず、本当に申し訳なかったです。

    トピックのタイトルの目的は達成できましたので、
    こちらの一方的な行動で申し訳ないですが、
    解決済みとさせていただきます。

    また、お世話になる場面がありましたら、
    その時は、またご迷惑をおかけするかもしれませんが、
    よろしくお願いいたします。

    今回は本当にありがとうございました。

    モデレーター Takuro Hishikawa

    (@hissy)

    お疲れさまでした。このトピックを有益なものにするためにも、最終どのようなコードで実装したか貼り付けてもらえると嬉しいです 😉

12件の返信を表示中 - 16 - 27件目 (全27件中)
  • トピック「投稿日時で絞り込みをしたい」には新たに返信することはできません。