サポート » 使い方全般 » 個別記事について

  • 初めて質問させていただきます。
    現在wordpressを使ってサイトを制作しております。
    プラグインの「Advance Custom Field」というのを使用しているのですが、個別記事の値が取得できません。下記はsingle.phpの一部なのですがおそらく上部でpost type=normalを指定してしまっているので<h2><?php the_title(); ?></h2>と<?php the_content(); ?>で個別的な内容を取得できないと思われます。
    どうすればいいのでしょうか。わかりにくくて申し訳ありませんがご教授いただければ幸いです。

    <?php query_posts('post_type=normal');?>
     <?php if(have_posts()): while(have_posts()): the_post(); ?>
    <p>営業時間 : 平日<?php echo get_post_meta($post->ID, 'time', true); ?></p>
    <img src="<?php bloginfo('template_url'); ?>/img/tell.png" width="15" height="15" alt="電話番号" id="tel"/><p class="tell"><?php echo get_post_meta($post->ID, 'tel', true); ?></p>
    <p><?php echo get_post_meta($post->ID, 'address', true); ?></p>
    <?php endwhile; endif; ?>
     <div class="right">
    <h2><?php the_title(); ?></h2>
      <?php the_content(); ?>

13件の返信を表示中 - 1 - 13件目 (全13件中)
  • kenta12240420さんこんにちは
    まず、問題の切り分けをしたいと思います。

    ・カスタムポストタイプにnormalを作っているのかどうか
     (デフォルトの投稿タイプはpostとなります)

    ・テンプレートの個別記事表示用ファイルはsingle.phpだけかどうか
     (実はsingle-normal.phpが存在していた)

    ・提示されたコード以外で別の記事の表示はされていないか
     (提示されているコード以前にデフォルトで読み込まれている可能性
      カスタムフィールドに言及されていないので。’address’などが表示されている場合は
      query_postsでの取得の仕方がまずい)

    ・advanced custom fieldsのフィールド対応で投稿オブジェクトをしていしたものを表示しようとしているのかどうか
     (この場合はフィールドには投稿IDのみが保存されているので別にちゃんと取得するか
      advanced custom fieldsの関数を使ってカスタムフィールドを表示するようにする)

    このあたりが原因となると思います。
    まず、どこに原因があるかオープン前ならvar_dump print_rなどで
    どの部分でおかしくなっているのか問題を絞り込んでみてください。

    トピック投稿者 kenta12240420

    (@kenta12240420)

    お返事ありがとうございます。

    ・カスタムポストタイプにnormalを作っているのかどうか
     (デフォルトの投稿タイプはpostとなります)
    →normalを作っています。
    ・テンプレートの個別記事表示用ファイルはsingle.phpだけかどうか
     (実はsingle-normal.phpが存在していた)
    →single-◯◯というファイルは存在していません。
    ・提示されたコード以外で別の記事の表示はされていないか
     (提示されているコード以前にデフォルトで読み込まれている可能性
      カスタムフィールドに言及されていないので。’address’などが表示されている場合は
      query_postsでの取得の仕方がまずい)
    →post_type=normalのタイトルが<?php the_title(); ?>で読み込まれていますのでこの辺りなのでしょうか。

    <div class="right">
    <h2><?php the_title(); ?></h2>
      <?php the_content(); ?>

    の部分を
    `<div class=”right”>
    <?php query_posts(‘post_type=news’);?>
    <?php if(have_posts()): while(have_posts()): the_post(); ?>
    <h2><?php the_title(); ?></h2>
    <?php the_content(); ?>
    <?php endwhile; endif; ?>
    <!–.right–></div>`
    に変更するとpost_type=newsの値は取れるのですが、全ての投稿が表示されてしまいます。
    初心者で頭の中がぐしゃぐしゃになっておりますがアドバイスを引き続きいただければありがたいです。お願い致します!!

    すみません。私もどうやら書いているうちにごちゃごちゃになっていました。
    まず、single.phpで表示される記事についてはurlがidだったりスラッグだったりで
    カスタム投稿タイプにかかわらずすでに確定されております。

    その投稿タイプを表示するテンプレートはsingle.php

    ということであれば特にquery_postをいじる必要はなく
    <?php query_posts('post_type=news');?>
    の部分をごっそりと取ってしまえば本来であればそのまま
    the_titleやthe_contentなどで表示されるかと思います。

    トピック投稿者 kenta12240420

    (@kenta12240420)

    さっそくのご返信ありがとうございます!
    <?php query_posts(‘post_type=news’);?>の部分を取れば表示されると思い、僕もやってはみたのですが、上部で記述している<?php query_posts(‘post_type=normal’);?>のthe_titleやthe_contentが読み込まれるんですよね。
    なぜなんでしょうか。
    お手が空いてる時で大丈夫なのでご返信いただければ幸いです。
    お願いします。

    つまり
    normalの記事を表示する画面で、normalの記事とは別枠で
    newsの記事も別枠で表示したいということでしょうか?

    トピック投稿者 kenta12240420

    (@kenta12240420)

    はい。その通りです!
    簡単にいうとnormal部分でサイドバーを作っていて、newsの記事をメイン部分で表示したいのです。

    そういうことですね。
    それでnormalの記事の投稿時にnewsのカスタムフィールド部分を
    フィールドタイプで投稿オブジェクトで指定しているという形でしょうか。

    それでしたら
    http://www.advancedcustomfields.com/docs/field-types/post-object/
    この部分をそのまま使ってget_fieldやthe_fieldの中身を
    作ったフィールド名に変えてやってやればいいかと思います。

    使いやすさでいえばこの部分でしょうか

    <?php $post_objects = get_field('post_objects');
    if( $post_objects ): ?>
        <ul>
        <?php foreach( $post_objects as $post): // variable must be called $post (IMPORTANT) ?>
            <?php setup_postdata($post); ?>
            <li>
                <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
                <span>Post Object Custom Field: <?php the_field('field_name'); ?></span>
            </li>
        <?php endforeach; ?>
        </ul>
        <?php wp_reset_postdata(); // IMPORTANT - reset the $post object so the rest of the page works correctly ?>
    <?php endif; ?>
    トピック投稿者 kenta12240420

    (@kenta12240420)

    それでnormalの記事の投稿時にnewsのカスタムフィールド部分を
    フィールドタイプで投稿オブジェクトで指定しているという形でしょうか。
    newsに関してはニュースという部分から新規追加で入れています。
    normalは基本情報という部分からいれており別々です。

    <?php
    //ニュース
    register_post_type(
      'news',
      array(
        'label' => 'ニュース',
        'hierarchical' => false,
        'public' => true,
        'query_var' => true,
    	'publicly_queryable' => true,
        'menu_icon' => get_bloginfo('template_url').'/img/info.png',
    	'has_archive' => true,
    	'with_front' => false,
        'supports' => array(
                         'title',  )
       )
    );
    ?>
    <?php
    //基本登録事項
    register_post_type(
      'normal',
      array(
        'label' => '基本登録事項',
        'hierarchical' => false,
        'public' => true,
        'query_var' => true,
    	'publicly_queryable' => true,
        'menu_icon' => get_bloginfo('template_url').'/img/info.png',
    	'has_archive' => true,
    	'with_front' => false,
        'supports' => array(
                         'title',  )
       )
    )
    
    ?>

    といった感じでfunctions.phpで分けております。

    normalの個別記事に表示するnewsの記事はどのようなものを表示するのでしょうか。
    最新のものを表示するだけでしたら。

    <?php $args = array();
    $args = array(
      'post_type' => array('news'),
      'posts_per_page' => 5
    );
    $news_posts = get_posts($args);
    foreach($news_posts as $np): ?>
    <p>営業時間 : 平日<?php the_field('time',$np->ID); ?></p>
    <img src="<?php bloginfo('template_url'); ?>/img/tell.png" width="15" height="15" alt="電話番号" id="tel"/><p class="tell"><?php the_field('tel',$np->ID); ?></p>
    <p><?php the_field('address',$np->ID) ?></p>
    <?php endforeach; ?>

    で表示はできると思います。

    トピック投稿者 kenta12240420

    (@kenta12240420)

    色々ありがとうございます。
    自分でも調べてた所、newsの前にループを
    <?php query_posts(‘post_type=normal’);?>で指定していたのが原因らしく、
    <?php wp_reset_query(); ?>でリセットすることによりニュースは表示されました。
    しかし、情報によると、<?php query_posts(‘post_type=”);?>のタグはメインループ以外には使わないルールみたいですね。
    表示されていてもまずいのでしょうか??

    お役に立てずに申し訳ないです。
    おっしゃるとおり<?php wp_reset_query(); ?>でもとに戻せますが
    今回のように別のループを回したい場合等で
    上書きされてしまったり色々と細かいところで面倒になったりするので
    できれば本来以外の記事を「同時に」使用したい場合はquery_postsを使わずに
    別の方法で取得・表示したほうが何かと都合がいいと私は解釈しています。(何かもっとちゃんとした理由があるかもしれませんが・・・)

    また、「同時に」を強調したのは本来表示されれる記事は使用せずに別の記事だけを表示するには
    is_main_queryでデフォルトの取得内容を変更したほうが更に都合がよくなります。

    トピック投稿者 kenta12240420

    (@kenta12240420)

    ありがとうございます。聞ける人がいない環境だったので、回答をいただきすごく感謝しています。
    やはり、使わないほうが無難なのですね。
    ちなみに同時に使う場合に代用できるのとかわかりますか??
    何個か調べてあったのでやってみたのですが、上手く行かなくて…。

    モデレーター gatespace

    (@gatespace)

    WordPressのループに関してはCodexをお読みください。
    http://wpdocs.sourceforge.jp/The_Loop

    端的に言うと

    • 標準クエリ(メインクエリ、メインループ)を改変したいときは、query_posts
    • 標準クエリと別にループを用意したい場合は WP_Query または get_posts

    です。
    たとえば、サイドバーなどにウィジェットで「最新の投稿」を表示するものがあります。
    この場合、ウィジェットの「最新の投稿」はメインではない別のループになるので、WP_Queryを使って、投稿を取得しています。

    こちらのブログも参考になります。
    「query_postsとget_postsの違い」
    http://notnil-creative.com/blog/archives/1384

    いずれの場合もクエリ改変(取得)後はリセットした方がよいでしょう。
    どの関数を選択したか、でリセットの関数も異なります。

    ループの書き方の具体例はこちらのブログが参考になります。
    「WordPress ループ&クエリーのモヤモヤを解消しよう!」
    http://wpxtreme.jp/understanding-wordpress-loops-and-queries

    また、jdbbさんの書かれた is_main_query について補足すると
    テーマのfunctions.phpに pre_get_posts にフックする関数を作り、
    その中でis_main_queryを使って、クエリの取得条件を変えるものです。

    言葉にすると分かりづらいのですが、
    query_posts はテンプレートがファイルが呼び出されたに既に呼び出していたクエリを改変するのに対し、pre_get_posts にフックする方法はテンプレートファイルを呼び出すにクエリを改変します。

    例えば「カテゴリーアーカイブのみ表示件数を変えたい」という場合、
    カテゴリーアーカイブ用のテンプレートで query_posts を呼び出すよりも、
    functions.php で pre_get_posts にフックする様にクエリを改変した方が2回クエリを呼び出さなくて良いと言うメリットがあります。
    また、ニッチな例ですが、RSSフィードにカスタム投稿タイプを含めたい場合なども、有効です(通常は投稿のみな上、フィード用のテンプレートは用意されていないので)

    少し長くなりましたが、こちらのブログと、私のブログでも解説していますので、ご参照ください。

    「3.3の新しい関数 is_main_query を使おう」
    http://www.warna.info/archives/1964/
    「WordPressでホームやアーカイブ毎に表示条件を変える(is_main_query と pre_get_posts フック)」
    http://gatespace.wordpress.com/2012/09/10/modify_main_queries/

13件の返信を表示中 - 1 - 13件目 (全13件中)
  • トピック「個別記事について」には新たに返信することはできません。