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

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

ただいまの
回答率

87.49%

WordPressで新着情報がある場合にメニューの表示を変更したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 455

score 1

前提

WordPressで個人サイトを作っています。
使用テンプレートは「First」です。
http://themehaus.net/ja/themes/first/
「ダッシュボード>外観>メニュー」にて
「メニュー設定>メニューの位置>ナビゲーションバー」のメニューを作成しました。

実現したいこと

メニューには4個の項目があり、
1個は固定ページ、残り3個はカテゴリーです。
各項目に新着情報がある
(固定ページなら固定ページ最終更新日が7日以内である、
カテゴリーなら、そのカテゴリー内のポスト投稿日または最終更新日が7日以内である)
場合に、そのメニュー項目にTwitterの通知バッジ風の赤い丸印を表示したいです。

発生している問題・エラーメッセージ

固定ページについては、functions.phpとstyle.cssに下記を追記することで、
実現できました。

function special_nav_class($classes, $item,$args){
     if ( $args->theme_location !== 'primary' )
        return $classes;
     if(($item->object == 'category') or ($item->object == 'page') or ($item->object == 'post' )){
         if($item->object =='page'){
         if ( ( $post = get_post( $item->object_id ) ) ) {
            $now_date = date( 'U' );
            $post_date = mysql2date( 'U', $post->post_modified ); // 投稿日なら $post->post_date
            $diff_date = date( 'U', ( $now_date - $post_date )) / 86400;
            if ( (int)$diff_date <= 7 )
             $classes[] = 'new';}
     }
     return $classes;
   }
}
add_filter('nav_menu_css_class' , 'special_nav_class' , 10 , 3);
/* Menus
------------------------------------------------------------ */

/* Navigation Bar */
.site-bar,
.menu-item.new a:after { content: "\25CF"; color: red; vertical-align: super; }

メニュー項目がカテゴリーの場合に意図する表示ができない

function special_nav_class($classes, $item,$args){
     if ( $args->theme_location !== 'primary' )
        return $classes;
     if(($item->object == 'category') or ($item->object == 'page') or ($item->object == 'post' )){
         if($item->object =='page'){
         if ( ( $post = get_post( $item->object_id ) ) ) {
            $now_date = date( 'U' );
            $post_date = mysql2date( 'U', $post->post_modified ); // 投稿日なら $post->post_date
            $diff_date = date( 'U', ( $now_date - $post_date )) / 86400;
            if ( (int)$diff_date <= 7 )
             $classes[] = 'new';}
     }
         if(($item->object == 'category')){
           $cat_id = get_category( $item->object_id );
             if(  $cat_id == 7 ) 
             $classes[] = 'new';
         }
     return $classes;
   }
}
add_filter('nav_menu_css_class' , 'special_nav_class' , 10 , 3);


固定ページのときのソースコードを真似て、
まずはカテゴリ内記事のdate関連データには関係無く、
カテゴリーIDが「7」のメニュー項目には「new」表示をする、
というテストをしてみましたが、「new」表示がされませんでした。
(メニューに表示している3個のカテゴリーのカテゴリーIDは5、6、7です)

試したこと

カテゴリーIDに関係なく、メニュー項目がカテゴリーの場合、
「new」表示をするというテストをしてみたところ、
「new」表示ができました。

function special_nav_class($classes, $item,$args){
     if ( $args->theme_location !== 'primary' )
        return $classes;
     if(($item->object == 'category') or ($item->object == 'page') or ($item->object == 'post' )){
         if($item->object =='page'){
         if ( ( $post = get_post( $item->object_id ) ) ) {
            $now_date = date( 'U' );
            $post_date = mysql2date( 'U', $post->post_modified ); // 投稿日なら $post->post_date
            $diff_date = date( 'U', ( $now_date - $post_date )) / 86400;
            if ( (int)$diff_date <= 7 )
             $classes[] = 'new';}
     }
         if(($item->object == 'category')){
             $classes[] = 'new';}
     return $classes;
   }
}
add_filter('nav_menu_css_class' , 'special_nav_class' , 10 , 3);

補足情報(FW/ツールのバージョンなど)

カテゴリーIDは、ブラウザ(グーグルクローム)の編集画面から読み取りました。
https://open-cage.com/wp-category_id-investigate/

WordPress・PHPともに初心者のため、かなり回り道をしているかもしれません。
お手数をお掛けしますが、修正点を教えていただけますでしょうか。
以上、よろしくお願いいたします。

追加の質問(2020/11/27)

困っていること

「実現したいこと」は実現できましたが、下記エラーメッセージが出ます。
Warning: Creating default object from empty value in functions.php on line 583
エラーメッセージを解消するために必要な情報を教えていただきたく質問しています。

ソースコード

date関連データでソートするために、下記、二つの独自関数を記述しました。

function return_latest_id($cat_id=null) {
    global $wpdb;

    if(empty($cat_id)) {
        // 最新記事idの取得
        $row = $wpdb->get_row("SELECT ID FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish' ORDER BY post_modified DESC");
    } else {
        // カテゴリを指定した最新記事idの取得
        $cat_id = intval($cat_id);
        $row = $wpdb->get_row("SELECT p.ID FROM $wpdb->posts p LEFT JOIN $wpdb->term_relationships r ON p.ID=r.object_id WHERE p.post_type = 'post' AND p.post_status = 'publish' AND r.term_taxonomy_id = '$cat_id' ORDER BY p.post_modified DESC");
    }
    return !empty( $row ) ? $row->ID : '0';
}

function sort_by_postdate($a, $b) {
    // 2つのカテゴリの最新の投稿(newest_postメンバ)の日付の大小関係を返す
    return ($a->newest_post->post_modified == $b->newest_post->post_modified) ? 0 :
           ($a->newest_post->post_modified < $b->newest_post->post_modified) ? 1 : -1;
}

以上の独自関数の後に、先日カテゴリIDの取得で躓いていた関数を大幅に追記しました。

function special_nav_class($classes, $item,$args){
     if ( $args->theme_location !== 'primary' )
        return $classes;
     if(($item->object == 'category') or ($item->object == 'page') or ($item->object == 'post' )){
         if($item->object =='page'){
            if ( ( $post = get_post( $item->object_id ) ) ) {
                $now_date = date( 'U' );
                $post_date = mysql2date( 'U', $post->post_modified ); // 投稿日なら $post->post_date
                 $diff_date = date( 'U', ( $now_date - $post_date )) / 86400;
                     if ( (int)$diff_date <= 30 )
                     $classes[] = 'new';
            }
         }
         if(($item->object == 'category')){
             if( $cat_id =  $item->object_id ){
                 $cat_data = get_category( $cat_id );
                     $cat_data->category_parent;
                       $parent_id = $cat_data->category_parent;
                        if( empty($parent_id)==false ){
                            if( $post_id = return_latest_id( $cat_id ) ){
                                  if ( ( $post = get_post( $post_id ) ) ) {
                                        $now_date = date( 'U' );
                                        $post_date = mysql2date( 'U', $post->post_modified ); // 投稿日なら $post->post_date
                                        $diff_date = date( 'U', ( $now_date - $post_date )) / 86400;
                                     if ( (int)$diff_date <= 30 )
                                        $classes[] = 'new';
                                 }
                            }
                          }
                        if( empty($parent_id)==true ){
                                // 投稿があるカテゴリをすべて読み込む
                                 $cats = get_categories($parent_id);
                                // カテゴリの数を得る
                                 $count = count($cats);
                                // カテゴリの数だけ繰り返す
                                   for ($i = 0; $i < $count; $i++) {
                                       // 各カテゴリの最も新しい投稿を読み込む
                                       $where = array('category' => $cats[$i]->term_id, 'orderby' => 'post_modified', 'order' => 'desc', 'numberposts' => 1);
                                       $newest_posts = get_posts($where);
                                       // カテゴリのオブジェクトに「newest_post」というメンバを追加して、最新の投稿を代入する
                                       $cats[$i]->newest_post = $newest_posts[0];  //エラーが出ている「line 583」はこの行です
                                       // 各カテゴリの最も古い投稿を読み込む
                                       $where['order'] = 'asc';
                                       $oldest_posts = get_posts($where);
                                       // カテゴリのオブジェクトに「oldest_post」というメンバを追加して、最新の投稿を代入する
                                       $cats[$i]->oldest_post = $oldest_posts[0];
                                   }
                            // カテゴリを、最新の投稿の日付が新しい順に並べ替える
                            usort($cats, 'sort_by_postdate');
                            // 結果を返す
                            $newest_child_cat_id = $cats[0]->object_id;
                                   }
                                   if( $post_id = return_latest_id( $newest_child_cat_id ) ){
                                       if ( ( $post = get_post( $post_id ) ) ) {
                                             $now_date = date( 'U' );
                                             $post_date = mysql2date( 'U', $post->post_modified ); // 投稿日なら $post->post_date
                                             $diff_date = date( 'U', ( $now_date - $post_date )) / 86400;
                                        if ( (int)$diff_date <= 30 )
                                            $classes[] = 'new';
                                      }
                                   }
             }
         }
        return $classes;
     }
}
add_filter('nav_menu_css_class' , 'special_nav_class' , 10 , 3);

試したこと

エラーメッセージで検索したところ、「new stdClassで初期化してあげると解消します。」という記事を見付けたのですが、

$cats = new stdClass;


を追記してみたのですが、解消できませんでした。

恐れ入りますが、修正方法を教えていただけましたら幸いです。
以上、よろしくお願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

$classes[] = 'new';}


この波括弧で見通しが悪くなっていると思います。
インデントを揃えると問題点が見つかりやすいです。

それと

$cat_id = get_category( $item->object_id );


get_category()はカテゴリーのオブジェクトを持ってくるので、
その次のIDの判定が失敗しています。

$item->object_id


ここにstring型のカテゴリIDがセットされているので get_category() まではしなくて良いのかなと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/11/22 23:33

    大変わかりやすいご回答ありがとうございます。
    コメントが遅くなり申し訳ございません。

    kazwedaさまのご回答の通りに修正したところ、テスト表示がうまくいきました!
    (カテゴリーIDが7のメニュー項目にのみ、「new」表示がされました)
    あとはdate関連データでの条件分岐を付けてまいります。現状、date関連データでの条件分岐は、独自関数を別途記述することで実現していますが、「メニュー項目のカテゴリーが子カテゴリーを持つ場合」の表示が意図した通りになりません。もう少し自分で試行錯誤してみようと思います。

    キャンセル

0

エラーメッセージの回避方法

for文の前に

if (!(int)$count === 0)


を記述することで、エラーメッセージが出なくなりました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る