質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

2458閲覧

カスタムフィールドに入力した日付で月別アーカイブ(date.php)をつくりたい

shimuken0104

総合スコア4

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2021/10/05 08:00

したいこと

WordPressでカスタムフィールド(ACF使用)をつくり、
その値を用いて月別アーカイブを作ろうと考えています。

最終的な仕様は以下のサイトをイメージしています。
参考サイト:https://oku-log.com/blog/ctm-archive/

具体的には、イベント開催日をフィールドタイプ(デイトピッカー)を使い、
イベント開催月ごとの月別アーカイブを作ろうとしています。

かれこれ15時間ほど格闘していますが、自力ではどうにもならなかったので、
どなたか分かる方お助けください。。。

## 前提
投稿タイプ:post
フィールド名:event_date
カスタムフィールド内表示フォーマット:Y/m/d
カスタムフィールド内返り値フォーマット:Y/m/d

問題点

参考サイト通りに試してみたが、リンク先が404エラーになる。

具体的には、セレクトボックスは表示されるが、
セレクトボックスのリンク先が404エラーとなってしまいます。

イベントURLは、現在以下のようになっています。(10月イベントの場合)
https://xxxxxx/2021/10/?meta_key=event_date

参考サイト
https://oku-log.com/blog/ctm-archive/

仮説

$meta_queryのvalueが機能していない為、
date.phpが、月別記事を見つけられず404エラーとなっている。

記載コードを1つずつ、var_dumpで確認していった所、
おそらく、$meta_queryの設定に問題があると考えています。

以下のコード部分を削除すると、イベント開催日ではなく、
ブログ投稿日で一覧が並ぶ状態となりました。(date.php)

html

1'value' => $query->get('year'). '.' .sprintf('%02d', $query->get('monthnum')),

##コード一覧
該当するコードをファイル別で記載させていただきました。
長くなってしまいますが、どなたか回答いただけましたら幸いです。

ファイルは3つになります。

  • functions.php
  • date.php
  • tmp/c-card.php(イベントカードテンプレート)

①コード(functions.php)

html

1 2/* ======================================== 3/* カスタムフィールド値でのセレクトボックス 4======================================== */ 5 6function my_get_month_archives($args = '') 7{ 8 global $wpdb, $wp_locale; 9 10 $defaults = array( 11 'date_field' => 'event_date', //カスタムフィールドのフィールド名を記述 12 'format' => 'html', 13 'echo' => true, 14 'limit' => '', 15 'before' => '', 16 'after' => '', 17 'show_post_count' => true, 18 ); 19 20 /** 21 * 与えられた $args を解析して配列に入れ、$defaults と結合 22 */ 23 $r = wp_parse_args($args, $defaults); 24 25 // 配列からシンボルテーブルに変数のインポート 26 extract($r, EXTR_SKIP); 27 28 //$limitが空じゃなければ 29 if ('' != $limit) { 30 // 値を負ではない整数に変換します。 31 $limit = absint($limit); 32 $limit = ' LIMIT ' . $limit; 33 } 34 35 $field = 'm.meta_value'; 36 37 // $fieledの1~4文字までを切り取り カラム名はyearに 38 // $fieledの5~2文字分を切り取り カラム名はmonthに 39 // pのID数を数えカラム名postsで管理する 40 $select = "SELECT SUBSTRING($field,1,4) AS `year`, SUBSTRING($field,5,2) AS `month`, count(p.ID) AS posts"; 41 42 // ポストタイプ=post かつ、公開状態のpost 43 $where = "WHERE p.post_type = 'post' AND p.post_status = 'publish'"; 44 45 // $where + クエリ内のパラメーターを変更 46 $where .= $wpdb->prepare('AND m.meta_key = %s', $date_field); 47 48 // postmetaとm.post_idを内部結合 結合条件p.id 49 $join = " INNER JOIN $wpdb->postmeta AS m ON m.post_id = p.ID"; 50 51 // フィルター関数が$whereに$rを渡す 52 $where = apply_filters('getarchives_where', $where, $r); 53 // フィルター関数が$joinに$rを渡す 54 $join = apply_filters('getarchives_join', $join, $r); 55 56 $output = ''; 57 58 //wpdbポスト(p) 59 $query = "$select FROM $wpdb->posts AS p $join $where GROUP BY SUBSTRING($field,1,4), SUBSTRING($field,5,2) ORDER BY $field ASC $limit"; 60 61 // クエリのハッシュ値を$keyに代入 62 $key = md5($query); 63 64 // キャッシュからデータ取得 65 $cache = wp_cache_get('my_get_month_archives', 'general'); 66 67 if (!isset($cache[ $key ])) { 68 $arcresults = $wpdb->get_results($query); 69 $cache[ $key ] = $arcresults; 70 wp_cache_set('my_get_month_archives', $cache, 'general'); 71 } else { 72 $arcresults = $cache[ $key ]; 73 } 74 if ($arcresults) { 75 $afterafter = $after; 76 foreach ((array) $arcresults as $arcresult) { 77 $url = add_query_arg( array( 'meta_key' => $date_field ), get_month_link( $arcresult->year, $arcresult->month) ); 78 79 $text = sprintf('%d', $arcresult->year).'年'.sprintf('%d', $arcresult->month).'月'; 80 81 $output .= '<option value="'.$url.'">'.$text.'</option>'; 82 } 83 } 84 if ($echo) { 85 echo $output; 86 } else { 87 return $output; 88 } 89} 90 91 92/* ======================================== 93/* //アーカイブページの出力調整 94======================================== */ 95 96add_action('init', 'my_init'); 97// リクエストパラメータにmeta_keyフィールドを追加 98function my_init() 99{ 100 global $wp; 101 $wp->add_query_var('meta_key'); 102} 103 104function change_sort_order($query) 105{ 106 // 日付書式の設定 107 $currnet_date = date_i18n('y/m/d'); 108 109 // 管理ページor、メインクエリならリターン 110 if (is_admin() || ! $query->is_main_query()) { 111 return; 112 } 113 114 115 // もし、クエリ内に「月」があれば 116 if ($query->is_month()) { 117 $meta_query = array( 118 array( 119 // キーにmeta_keyを設定 120 'key' => $query->get('meta_key'), 121 // バリューに年、月を設定 122 // 最低2桁のint、1桁の場合、左に0詰 123 'value' => $query->get('year'). '.' .sprintf('%02d', $query->get('monthnum')), 124 // 含んだら表示 125 'compare' => 'LIKE', 126 ), 127 ); 128 129 // 今年の取得 130 $thisyear = get_query_var('year'); 131 // 今月の取得 132 $thismon = get_query_var('monthnum'); 133 $query->set('year', ''); 134 $query->set('monthnum', ''); 135 $query->set('orderby', 'meta_value'); 136 $query->set('meta_key', 'event_date'); 137 $query->set('post_type', 'post'); 138 $query->set('meta_query', $meta_query); 139 $query->set('thisyear', $thisyear); 140 $query->set('thismon', $thismon); 141 142 } 143} 144add_action('pre_get_posts', 'change_sort_order'); 145

②コード(date.php)該当箇所のみ

html

1 <div class="custom-archive__wrap"> 2 <select name="archive-dropdown" onChange='document.location.href=this.options[this.selectedIndex].value;'> 3 <option value="">年代から絞り込む</option> 4 <?php 5 my_get_month_archives( array( 6 'date_field' => 'event_date', //カスタムフィールドのフィールド名を記述 7 ) ); 8 ?> 9 </select> 10 </div><!-- .custom-archive__wrap --> 11 12 <div class="c-card__groups u-padding--bottom"> 13 <?php if (have_posts()) : 14 while (have_posts()) : 15 the_post(); 16 get_template_part('tmp/c-card'); 17 endwhile; 18 endif; 19 ?> 20 <?php wp_reset_postdata(); ?> 21 </div><!-- .c-card__groups -->

③イベントカードコード(tmp/c-card.php)

html

1<article class="c-card"> 2 <a href="<?php the_permalink(); ?>"> 3 <div class="c-card__img-wrap"> 4 <div class="c-card__bg"> 5 <?php $cardimg = get_field('event_img');?> 6 <img src="<?php echo $cardimg; ?>" alt="<?php the_title(); ?>"> 7 </div><!-- .c-card__bg --> 8 <div class="c-card__img"> 9 <img src="<?php echo $cardimg; ?>" alt="<?php the_title(); ?>"> 10 </div><!-- .c-card__img --> 11 </div><!-- .c-card__img-wrap --> 12 <div class="c-card__body"> 13 <div class="c-card__date-box"> 14 <span class="u-font--l"> 15 <?php 16 // 日付の表示 17 $date = get_field('event_date'); 18 $hiduke = new DateTime($date); 19 echo $hiduke->format('n.j'); 20 ?> 21 </span> 22 <span> 23 <?php 24 // 曜日の表示 25 $date = get_field('event_date'); 26 $youbi = new DateTime($date); 27 $youbi = $youbi->format('D'); 28 $replace = [ 29 'Sun' => 'SUN', 30 'Mon' => 'MON', 31 'Tue' => 'TUE', 32 'Wed' => 'WED', 33 'Thu' => 'THU', 34 'Fri' => 'FRI', 35 'Sat' => 'SAT', 36 ]; 37 echo str_replace(array_keys($replace), array_values($replace), $youbi); 38 ?> 39 </span> 40 </div><!-- .c-card__date-box --> 41 <div class="c-card__ttl-box"> 42 <p><?php the_title(); ?></p> 43 </div><!-- .c-card__ttl-box --> 44 </div><!-- .c-card__body --> 45 </a> 46</article><!-- .c-card --> 47

以上になります。
もし、足りない情報などあれば提供させていただきます。

長くなりましたが、わかる方ぜひ回答いただけますと幸いです。
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

php

1//元のコード 2 'value' => $query->get('year'). '.' .sprintf('%02d', $query->get('monthnum')),

php

1//変更後コード 2'value' => $query->get('year') . sprintf('%02d', $query->get('monthnum')),

上記に変更したところ、無事表示されました。

投稿2021/10/06 00:20

shimuken0104

総合スコア4

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問