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

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

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

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

PHP

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

Q&A

解決済

1回答

1339閲覧

カスタムフィールドの値から関連記事を表示する方法

退会済みユーザー

退会済みユーザー

総合スコア0

WordPress

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

PHP

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

0グッド

0クリップ

投稿2018/05/13 23:12

編集2018/05/14 08:11

###前提と目的
プラグイン「smart custom field」でカスタムフィールドを作りました。

tag_singleというフィールド名のチェックボックスです。

このチェックボックスをタグのように扱い、同じチェックがある記事を関連記事として表示させたいです。
イメージ説明

###やってみたこと
次のコードを書いてみたのですが、なぜか「同じチェックの記事」でなく、全ての記事がなんでもかんでも表示されてしまう状況です。

どのように修正したらいいでしょうか?

php

1<!--ここがあやしい--> 2<?php 3$hastag = get_post_meta( $post->ID, 'tag_single', true ); 4if( !empty( $hastag ) ) { 5 $tags = SCF::get( 'tag_single' ); 6 foreach( $tags as $tag ) { 7 $tagkwds[] = $tag->post_name; 8 } 9} ?> 10 11<!--以下からは大丈夫なはず--> 12<?php 13$myposts = get_posts( array( 14 'post_type' => 'post', 15 'posts_per_page' => '8', 16 'post__not_in' => array( $post->ID ), 17 'category__in' => $catkwds, 18 'orderby' => 'rand' 19) ); ?> 20 21<?php if( $myposts ): ?> 22 23<section class="related-section"> 24 <div id="content-wrap"> 25 <div class="content"> 26 <?php foreach($myposts as $post): 27 setup_postdata($post); ?> 28 29 <?php get_template_part( 'template-parts/list', 'single' ); ?> 30 31 <?php endforeach; ?> 32 </div> 33 </div> 34</section> 35 36<?php wp_reset_postdata(); ?> 37 38<?php endif; ?>

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

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

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

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

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

KazuhiroHatano

2018/05/14 07:45

tag_singleって「関連投稿」のカスタムフィールド?
退会済みユーザー

退会済みユーザー

2018/05/14 07:48

はい。カスタムフィールド名です。事情があってカテゴリやタームでなく、カスタムフィールドのチェックボックスで関連記事として扱いたいのです。
KazuhiroHatano

2018/05/14 07:56

なんか誤解がありそうなので詰めます。「関連投稿」のカスタムフィールド、つまりSCFにおいてはtag_singleの入力欄には「指定した条件に適合した他の投稿のタイトル」が一覧されるのでしょうか?
退会済みユーザー

退会済みユーザー

2018/05/14 08:13

わかりにくくて申し訳ございません。tag_singleの入力欄には「チェックボックス」が表示されています。質問文にその画像を追記いたしました。そして、条件に合う記事(同じチェックがある記事)を一覧として8件出力するためのコードが、質問にあるものです。
KazuhiroHatano

2018/05/14 08:27

多分この感じは「関連投稿」のフィールドではないですよね、そして質問文のコードは多分SCFの「関連投稿」の機能を利用した際のコードを流用してますね
退会済みユーザー

退会済みユーザー

2018/05/14 08:35

はい、本来は例えば不動産さんサイトで「新築・築5年・築10年」とチェックしたり、お土産屋さんサイトで「女性向け・男性向け」とチェックしたり、など、記事作成時の利便性を高めるため。という目的で設置されるフィールドだと思います。
KazuhiroHatano

2018/05/14 08:47

理解していないコードをコピペするのは避けましょう
guest

回答1

0

ベストアンサー

以下からも全然大丈夫じゃない

SCFのことはよく知らんがsmart custom fieldなんて名前なんだから
SCF::get()が返しているのはpost_metaの値だろう

使うのはcategory__inじゃなくmeta_query

なんか色々ごっちゃになってそうなのでついでにこれも貼っときます
WPデータベース構造
カスタムフィールドはwp_postmetaテーブルに
tagやcategoryはwp_termsに入ってます
入ってるとこから違います


追記

SCFのことよく知らないので、一つ確認したいことがあります

php

1$hastag = get_post_meta( $post->ID, 'tag_single', true );

複数にチェックを入れた場合にこの$hastagはもしかしてarrayですか?
それともチェックした項目のうちどれかひとつの値でしょうか?
var_dumpしてみてください


複数の値をシリアライズして一つのフィールドに入れるタイプのやつだと
検索はかなりしんどいので確認でした

さて

php

1$hastag = get_post_meta( $post->ID, 'tag_single', true ); 2if( !empty( $hastag ) ) { 3 $tags = SCF::get( 'tag_single' ); 4 foreach( $tags as $tag ) { 5 $tagkwds[] = $tag->post_name; 6 } 7}

ここら辺まるっと要りません

「同じカスタムフィールドの値」を持ってるものを検索したいんだから
値をそのまま取り出して検索に使えばいいだけです

php

1$tags = get_post_meta( $post->ID, 'tag_single');

これでmeta_queryのvalueに使う値は取れました
あとはこれを使ってget_postsすればいいだけです

投稿2018/05/14 07:35

編集2018/05/14 08:41
KazuhiroHatano

総合スコア7802

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

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

退会済みユーザー

退会済みユーザー

2018/05/14 08:31

ご検討ありがとうございます。 「チェックした項目のうちどれかひとつの値」でした。 例えば全てにチェックしたらfluitsだけが出力されます。 もちろんチェックが1つだけならそれが出力されます。
退会済みユーザー

退会済みユーザー

2018/05/14 09:21 編集

下記の【1】【2】【3】の方法を試してみましたけれど、全てチェックの有無にかかわらずいろんな記事が表示されてしまいました。 ただ、【3】だけはチェックした値が出力されました。
退会済みユーザー

退会済みユーザー

2018/05/14 09:20 編集

【1】ご回答のバージョン →「#test1」はArrayでした…(>_<) <?php $tags = get_post_meta( $post->ID, 'tag_single'); echo '<p id="test1">'.$tags.'<p>'; ?> <?php $myposts = get_posts( array( 'post_type' => 'post', 'posts_per_page' => '8', 'post__not_in' => array( $post->ID ), 'meta_query' => $tags, 'orderby' => 'rand' ) ); ?> 以下同じ
退会済みユーザー

退会済みユーザー

2018/05/14 09:28 編集

【2】SCF向けにしたバージョン →「#test2」はArrayでした…(>_<) <?php $tags = SCF::get('tag_single'); echo '<p id="test2">'.$tags.'<p>'; ?> <?php $myposts = get_posts( array( 'post_type' => 'post', 'posts_per_page' => '8', 'post__not_in' => array( $post->ID ), 'meta_query' => $tag, 'orderby' => 'rand' ) ); ?> 以下同じ
退会済みユーザー

退会済みユーザー

2018/05/14 09:21 編集

【3】SCF向けにしてループしたバージョン →「#test3」はチェックした値が全て出力されました…(^^) <?php $tags = SCF::get('tag_single'); foreach ($tags as $tag) { echo '<p id="test3">'.$tag.'<p>'; } ?> <?php $myposts = get_posts( array( 'post_type' => 'post', 'posts_per_page' => '8', 'post__not_in' => array( $post->ID ), 'meta_query' => $tag, 'orderby' => 'rand' ) ); ?> 以下同じ
退会済みユーザー

退会済みユーザー

2018/05/14 09:30

このサイトによるとチェックボックスの出力は【3】の方法のようです。 https://www.akecre.com/wordpress/display_scf/#i-5 あとは 'meta_query' => $tag, がおかしいのですよね。 うーん。。
KazuhiroHatano

2018/05/14 09:34

さて、meta_queryのvalueに使う値は用意できました あとはkeyとcompareですね
退会済みユーザー

退会済みユーザー

2018/05/14 11:23

ありがとうございます。かなり迫ってこれました。最後に1つだけ教えてください(>_<) あと出来ないのが、「1つでも一致したら」という'compare'です。 下記【現在のコード】のように「LIKE」を使うのが一番近い表示になりました。ですがこれだと、 ・記事Xのチェック:fluits ・記事Yのチェック:fluits、dlink というときに、Xの関連記事としてYは出るのですが、逆にYの関連記事としてXが出ないのです。 かといって「LIKE」でなく「=」や「IN」でもダメでした。 ほかに「1つでも一致したら」という条件の'compare'はないのでしょうか? 【現在のコード】 <?php $myposts = get_posts( array( 'post_type' => 'post', 'posts_per_page' => '8', 'post__not_in' => array( $post->ID ), 'meta_query' => array( array( 'key' => 'tag_single', 'value' => $tag, 'compare' => 'LIKE' ) ), 'orderby' => 'rand' ) ); ?>
KazuhiroHatano

2018/05/14 11:27

そこはINでok、valueは値の配列、つまりget_post_meta( $post->ID, 'tag_single',false);で取得した値そのまま
退会済みユーザー

退会済みユーザー

2018/05/14 11:42 編集

んっと、それだと何も表示されないのです。 【INバージョン】 →「#var_IN]の値はArrayになる。何も表示されない。 <?php $tags = get_post_meta( $post->ID, 'tag_single' ); foreach ($tags as $tag); echo '<p id="var_IN">'.$tag.'</p>'; ?> <?php $myposts = get_posts( array( 'post_type' => 'post', 'posts_per_page' => '8', 'post__not_in' => array( $post->ID ), 'meta_query' => array( array( 'key' => 'tag_single', 'value' => $tag, 'compare' => 'IN' ) ), 'orderby' => 'rand' ) ); ?> 【LIKEバージョン】 →「#var_LIKE]の値はチェック全てが出る。しかし、Xの関連記事としてYは出るのですが、逆にYの関連記事としてXが出ない。 <?php $tags = get_post_meta( $post->ID, 'tag_single' ); foreach ($tags as $tag); echo '<p id="var_LIKE">'.$tag.'</p>'; ?> <?php $myposts = get_posts( array( 'post_type' => 'post', 'posts_per_page' => '8', 'post__not_in' => array( $post->ID ), 'meta_query' => array( array( 'key' => 'tag_single', 'value' => $tag, 'compare' => 'LIKE' ) ), 'orderby' => 'rand' ) ); ?>
KazuhiroHatano

2018/05/14 11:45

'value' => $tag, ↓ 'value' => $tags, get_post_meta( $post->ID, 'tag_single' )の値はそのまま そのまま渡す
退会済みユーザー

退会済みユーザー

2018/05/14 11:51

うーん。こう↓ですよね…? これですと「#var_IN2」はArrayが表示されてしまいます。 【INバージョンその2】 <?php $tags = get_post_meta( $post->ID, 'tag_single' ); echo '<p id="var_IN2">'.$tags.'</p>'; ?> <?php $myposts = get_posts( array( 'post_type' => 'post', 'posts_per_page' => '8', 'post__not_in' => array( $post->ID ), 'meta_query' => array( array( 'key' => 'tag_single', 'value' => $tags, 'compare' => 'IN' ) ), 'orderby' => 'rand' ) ); ?>
KazuhiroHatano

2018/05/14 13:45

そりゃ$tagsはArrayですからねぇ implodeするなりせんと文字列にはなりませんねぇ get_post_meta( $post->ID, 'tag_single', true )が Arrayじゃないか確かめたのが引っかかってるんだと思いますが あそこで確かめたのはDBの一つのカラムにまとめて 値が入れられてないかということです 検索に使う値としてどうかとかではないです
退会済みユーザー

退会済みユーザー

2018/05/14 14:03

ギブアップです。どう書けばいいのか教えていただけませんでしょうか…?
KazuhiroHatano

2018/05/14 14:24

投稿の取得はできましたか?まだそこからできてないですか?
退会済みユーザー

退会済みユーザー

2018/05/14 14:29

>implodeするなりせんと文字列にはなりませんねぇ とのこと。implodeというのをあれこれ使ってみたのですが、うまくいかず。 そこで文字列にするための方法としてtrueを入れればいいとわかり、やってみました。すると、Arrayでなくチェックボックスの値が出るようにはなりました。こうです。しかし、関連記事は表示されない様子です…。泣きそうです。笑 <?php $tags = get_post_meta( $post->ID, 'tag_single',true ); echo '<p id="var_TRUE">'.$tags.'</p>'; ?> <?php $myposts = get_posts( array( 'post_type' => 'single', 'posts_per_page' => '8', 'post__not_in' => array( $post->ID ), 'meta_query' => array( array( 'key' => 'tag_single', 'value' => $tags, 'compare' => 'IN' ) ), 'orderby' => 'rand' ) ); ?>
KazuhiroHatano

2018/05/14 14:56

meta_queryのvalueに使いたいのは配列です get_post_meta( $post->ID, 'tag_single',true )の戻り値は配列ではありません get_post_meta( $post->ID, 'tag_single')の戻り値が欲しい配列です get_post_meta( $post->ID, 'tag_single')の値だったら投稿の取得はできましたか?
退会済みユーザー

退会済みユーザー

2018/05/14 15:04 編集

それで投稿の取得(関連記事として表示することですよね?)ができるのは、上の20:42に書いた【LIKEバージョン】だけでした。 $tagsでなく$tagですが、うーん。$tagsであってるのでしょうか? ほんっと~うにわからないので教えて頂くわけにはいきませんでしょうか? 再掲ですみません↓ 【LIKEバージョン】 →「#var_LIKE]の値はチェック全てが出る。しかし、Xの関連記事としてYは出るのですが、逆にYの関連記事としてXが出ない。 <?php $tags = get_post_meta( $post->ID, 'tag_single' ); foreach ($tags as $tag); echo '<p id="var_LIKE">'.$tag.'</p>'; ?> <?php $myposts = get_posts( array( 'post_type' => 'post', 'posts_per_page' => '8', 'post__not_in' => array( $post->ID ), 'meta_query' => array( array( 'key' => 'tag_single', 'value' => $tag, 'compare' => 'LIKE' ) ), 'orderby' => 'rand' ) ); ?>
KazuhiroHatano

2018/05/14 15:26

【INバージョンその2】でも結局投稿の取得もできなかったんですか? それでLIKEなら通るとなるとやっぱりSCFは複数の値を 一つのカラムに全部まとめて入れてるんじゃないかって疑惑があるんですが 本当にget_post_meta( $post->ID, 'tag_single',true )なら 複数の値のうち一つだけしか返らなかったんですか? 最悪relationをorにして$tagの数だけLIKEでmeta_queryを書くという手もありますが get_post_meta( $post->ID, 'tag_single',true )なら配列は返らなかった というのを信用するなら【INバージョンその2】は投稿の取得はできるはずです
KazuhiroHatano

2018/05/14 15:51

もう一つ可能性があるのは、SCFが値はが配列であるかないかに関わらずシリアライズしてDBに値を入れているという可能性でしょうか、あまりないとは思いますが
退会済みユーザー

退会済みユーザー

2018/05/14 16:30 編集

>【INバージョンその2】でも結局投稿の取得もできなかったんですか? それでLIKEなら通るとなると あ、誤解があるかもしれません。 【INバージョンその2】は 'value' => $tags, ですが、 【LIKEバージョン】は 'value' => $tag, です。 なので、「それでLIKEなら通るとなると」というより、「LIKEにしてtagにしたら通るとなると」という感じです。 これをもし、「LIKEにしただけでtagsのまま」だと、「wp-includes/class-wp-meta-query.php on line 577」というエラーが返ってきます。 で、、、、 >本当にget_post_meta( $post->ID, 'tag_single',true )なら 複数の値のうち一つだけしか返らなかったんですか? ですが、もう一度調べましたが、『『大っっっ変申し訳ございません!!』』 複数の場合、複数が出力されました。出力結果は 値A| 値B という感じです。 蛇足ですがこうなった経緯をご説明します。 実は、質問時はSCFを利用しており、その場合は $tags = get_post_meta( $post->ID, 'tag_single',true ); だと一つだけしか返りませんでした。 正しくは $tags = SCF::get('tag_single'); としなければならなかったからだと思います。 そしてこちらは「IN」で仰るようにできました。 問題はその後、20:23 以降はSCFを使わない、普通のカスタムフィールドのチェックボックスで関連記事を設置する目的にコッソリすり替えておりました。実はSCFを使った 'tag_single' と、使わない 'tag_single' で実験していたのです。 そしてこの場合、 get_post_meta( $post->ID, 'tag_single',true ); だと複数返るようでした。 この場合は一つだけか複数かを確認するのを怠ったせいで、上述の『『大っっっ変申し訳ございません!!』』が起こってしまったという次第でございます。 ほんとうにごめんなさい。。心からお詫びいたします。
KazuhiroHatano

2018/05/14 16:56

SCFは結局、複数の値を一つのフィールドにまとめて入れるタイプだったみたいですね しかも区切り文字で区切って分ける奴ですか、面倒ですね… 配列かどうかと聞いてしまったのは、ちょっとその可能性を想定できてなかったです 正直検索に使うことを考えるとまだシリアライズされてた方がマシなんですよ 複数の値が一つのフィールドにまとめられてると、LIKEを使わざるを得ないわけなんですが そうなると、「ear」を検索すると「year」も「earth」も引っかかるって感じになっちゃう シリアライズされていればs:[文字数]:[文字列]で入っているので 検索キーワードをシリアライズして検索すれば単語内での一致に引っ掛けてしまうことがないのです まあ、そうなってしまっている以上、先に書いたように relationをorにして$tagの数だけLIKEでmeta_queryを書く というように対応するしかないですね 単語内に別の単語が内包されるケースを想定して書くなら 区切り文字、先頭、終端を交えてRLIKEで書く感じでしょうかね 処理重そう…
退会済みユーザー

退会済みユーザー

2018/05/14 17:08

>区切り文字で区切って分ける奴 区切り文字で出てくるのは、普通のカスタムフィールドのチェックボックスを get_post_meta( $post->ID, 'tag_single',true ); で出力した場合です。 あ、ひょっとして、これ、普通のカスタムフィールドじゃないかもしれません。「WP user fronted」(WPUF)というプラグインで「ユーザー投稿時にチェックするカスタムフィールド」なのです。 なので正確には「SCFのカスタムフィールド」と「WPUFのカスタムフィールド」のそれぞれで実験していて、SCFはINで出来たけど、WPUFは出来ない。という状況でした。 まぁそれはいいですね。いずれにせよ、下記の解決策を示して頂いて感謝です。 >relationをorにして$tagの数だけLIKEでmeta_queryを書く なるほどなるほど。ありがとうございます。タグは幸い6つなので、ぎりちょんで許容範囲です。(;'∀') なんとか今夜中にトライしてみます。(ネムイ…笑) 夜分までお付き合い頂きまして、誠にありがとうございますっ!
退会済みユーザー

退会済みユーザー

2018/05/14 17:59 編集

あれ?でも、「fluits、cake、vegetables、dlink、desert、alcohol」と6種類あるとします。 次のようにすると、「fluitsにチェックが入った記事では、fluitsにチェックが入った記事を表示」などを6通りはできます。 けれど、「fluitsとcakeにチェックが入ってるとき、fluitsにチェックが入った記事と、cakeにチェックが入った記事を表示」というのはできないのではないでしょうか? 'meta_query' => array( 'relation' => 'OR', array( 'key' => 'tag_single', 'value' => 'fluits' 'compare' => 'LIKE' ) array( 'key' => 'tag_single', 'value' => 'cake' 'compare' => 'LIKE' ) array( 'key' => 'tag_single', 'value' => 'vegetables' 'compare' => 'LIKE' ) array( 'key' => 'tag_single', 'value' => 'dlink' 'compare' => 'LIKE' ) array( 'key' => 'tag_single', 'value' => 'desert' 'compare' => 'LIKE' ) array( 'key' => 'tag_single', 'value' => 'alcohol' 'compare' => 'LIKE' ) ),
退会済みユーザー

退会済みユーザー

2018/05/14 18:40

思ったのですが、縦棒で区切っているのを、配列に入れなおす。という方法ではいかがでしょうか? このようなイメージです↓(これではできませんでしたが笑) <?php $tag_single = get_post_meta(get_the_ID(),'tag_single',false); foreach($tag_single as $tag_single1) { foreach (explode('|', $tag_single1) as $val) { $tags = array(trim($val)); //1つずつ配列に戻れ! } } ?> <?php $myposts = get_posts( array( 'post_type' => 'post', 'posts_per_page' => '8', 'post__not_in' => array( $post->ID ), 'meta_query' => array( array( 'key' => 'tag_single', 'value' => $tags, 'compare' => 'IN' ) ), 'orderby' => 'rand' ) ); ?>
KazuhiroHatano

2018/05/15 00:31

複数の値をまとめるやつと、まとめないやつが 混在してるのはよろしくありません 使うのをどっちかだけにしてください 入力値に互換性がないはずです 検索に使うなら一つにまとめない方にした方がいいです
退会済みユーザー

退会済みユーザー

2018/05/15 01:11

なるほど。考えておりませんでした。仰る通りですね。わかった風な口を聞いてしまってすみません。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問