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

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

ただいまの
回答率

88.04%

WordPress 新着記事一覧に「NEW!」アイコンを付けたい

解決済

回答 8

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,133

score 0

前提・実現したいこと

HTML・CSSは、独学で読み書きできる程度ですが、PHPは書けないWordPress初心者です。

WordPressで動いている企業ホームページのトップページに表示されるブログの新着記事一覧の、5日前までの記事に「NEW!」のアイコンを付けたいと思っています。
以前、外注して作ったホームページなのですが、その会社はもうなくなってしまっているようです。
ですので、自力でカスタマイズしようと考えたのですが、上手く動かず、こちらで皆様のお知恵をお借りできればと思い投稿します。

ブログは4つのカテゴリーに分かれていて、そのすべての新着記事を投稿が新しい順に表示しています。
表示順は、「投稿日」「タイトル」「カテゴリー名」となっていて、
投稿日が5日前までの記事のタイトルの前に「NEW!」アイコンを追加し、
「投稿日」「NEW!」「タイトル」「カテゴリー名」 のようにしたいと考えています。
「NEW!」はCSSでアイコン風にするつもりです。

コードは、functions.php内にこのように記述されています。

該当のソースコード

// 最新の投稿をリンク付きタイトルで表示
function shortcode_recent_posts( $args ) {
    global $wpdb;

    $catgoires = implode(', ', array(
        2,  // ◇カテゴリーA
        7,  // ◇カテゴリーB
        19, // ◇カテゴリーC
        33, // ◇カテゴリーD
    ));

    $query = "
        SELECT 
            $wpdb->posts.ID as ID, 
            $wpdb->posts.post_title as post_title, 
            $wpdb->posts.post_date as post_date, 
            $wpdb->terms.name as category_name 
        FROM $wpdb->posts
            LEFT JOIN $wpdb->term_relationships ON
                ($wpdb->posts.ID = $wpdb->term_relationships.object_id)
            LEFT JOIN $wpdb->term_taxonomy ON
                ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
            LEFT JOIN $wpdb->terms ON
                ($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)
        WHERE $wpdb->posts.post_status = 'publish'
            AND $wpdb->term_taxonomy.taxonomy = 'category'
            AND $wpdb->term_taxonomy.term_id IN ($catgoires)
        ORDER BY post_date DESC
        LIMIT 15
    ";

    $results = $wpdb->get_results($query);

    $items_buff = array();
    foreach ( $results as $p ) {
        $items_buff []= '<li><a href="'.get_permalink( $p->ID ).'">'.
            '<span class="time">'.mysql2date( 'Y.m.d', $p->post_date, false ).'</span>'.
            //ここに「NEW!」をいれたい(<span class="new">NEW!</span>)
            '<span class="title">'.esc_html( wp_trim_words( $p->post_title, 40 ) ).'</span> - '.
            '<span class="category">'.esc_html( $p->category_name ).'</span>'.
            '</a></li>';
    }
    $items_html = implode( '', $items_buff );

    return '<ul>'.$items_html.'</ul>';
}
add_shortcode('recent_posts', 'shortcode_recent_posts');

試したこと

ググると色々の方法がありましたが、残念ながら試した全てで上手く表示されませんでした。

例えば、こちらを参考にする場合・・・

// functions.php内に
function add_new($date,$days){
$today = date_i18n('U');
$elapsed = date('U',($today - $date)) / 86400;
if( $days > $elapsed ){
echo '<span class="new">New</span>';
}}
// 該当箇所に
<?php add_new(get_the_time('U'),5); ?>
  • functions.php内のどこに書いてもよいのか?
  • 構文はこのままで良いのか?
  • 該当箇所にはどのように書けばよいのか?

などが分からなく
思いつく限り(想像で)色々試しましたが、上手く表示されないか、重大なエラーになるかのどちらかで、途方に暮れています。

補足

ついでに、<span class="category 〇〇>のように、カテゴリーごとにクラス分けして、色分けもできればと考えています。
〇〇の部分は、slug名 や slug_ID が入れば、CSSで色分けできると思っています。

初心者の不躾な質問で恐縮ですが、お力添えいただければ幸いです。
どうぞよろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 8

+3

        $items_buff []= '<li><a href="'.get_permalink( $p->ID ).'">'.
            '<span class="time">'.mysql2date( 'Y.m.d', $p->post_date, false ).'</span>'.
            add_new( get_the_time( 'U', $p ) , 5 ).
            '<span class="title">'.esc_html( wp_trim_words( $p->post_title, 40 ) ).'</span> - '.
            '<span class="category">'.esc_html( $p->category_name ).'</span>'.
            '</a></li>';
 // 未テスト
function add_new( $date, $days ){
    $res = '';
    $today = date_i18n( 'U' );
    $elapsed = date( 'U', ( $today - $date ) ) / 86400;
    if ( $days > $elapsed ) $res = '<span class="new">New</span>';
    return $res;
} // 未テスト

【get_the_time() | Function | WordPress Developer Resources】
https://developer.wordpress.org/reference/functions/get_the_time/

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/06/20 22:17

    ありがとうございます!

    上のコードの、該当箇所を書き換え
    下のコードを、functions.php内の別の場所に追記
    しました。
    残念ながら、重大なエラーでWebサイトが見れない状態になってしましました。

    キャンセル

  • 2020/06/20 22:37

    手元の環境では少なくとも提示箇所はエラーが出ないので、「別の場所に追記」が元の関数を削除していないのでは。関数名の重複はできないので。

    キャンセル

  • 2020/06/21 02:57

    わぁーー!
    できました。

    上のコードをペーストする場所を間違っていました;;
    $items_buff という文字が2つあるのに気付かず(以下略・・・

    感動してしましました。
    これから、いただいたコードを1行ずつ読み解いていきたいと思います。

    別のコードを見つけてきて、そちらを使用することで「解決済み」にしてしまったので、ベストアンサーを付けられなくてスミマセン。

    本当にありがとうございました。m(_ _)m

    キャンセル

+1

wordpressは全くの素人だけどクエリ文いじくったらだめなの?DBの種類わからんけど
5日以内なら文字列new返すようにcase文書いて

    $query = "
        SELECT 
            $wpdb->posts.ID as ID, 
            $wpdb->posts.post_title as post_title, 
            $wpdb->posts.post_date as post_date, 
            $wpdb->case when posts.post_date + 5 > CURDATE() + 0 then 'new' else 'notnew' end as is_new, 
            $wpdb->terms.name as category_name 
    (以下略)"

あとはくっつければ?class付与さえできればcssでどうにでもできそうだし。

    $items_buff = array();
    foreach ( $results as $p ) {
        $items_buff []= '<li><a href="'.get_permalink( $p->ID ).'">'.
            '<span class="time">'.mysql2date( 'Y.m.d', $p->post_date, false ).'</span>'.
            //ここに「NEW!」をいれたい(<span class="new">NEW!</span>)
            '<span class="'.esc_html( $p->is_new ).'"></span>'.
            '<span class="title">'.esc_html( wp_trim_words( $p->post_title, 40 ) ).'</span> - '.
            '<span class="category">'.esc_html( $p->category_name ).'</span>'.
            '</a></li>';
    }
    $items_html = implode( '', $items_buff );

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/06/20 22:54

    ありがとうございます!
    試してみましたが、新着情報の<div>の中が真っ白になってしまい、何も表示されませんでした。
    でも、重大なエラーにはならなかったので、一歩前進!という感じです。

    クエリ文の書き方が全く分からなかったので、
    なるほどっ!こういう感じに書けば良いんだな。というヒントになりそうです。
    あとは、FROM と WHERE の部分に何か書き足せば、表示されるかもしれませんね。

    良い勉強になります。

    キャンセル

  • 2020/06/20 23:00

    データベースやpost_dateの型が何かわからなかったのでSQLは超適当です。
    多分queryが失敗しているんでしょうね。私が言いたかったのは「SQLで文字列処理したら?」ってことです。

    キャンセル

check解決した方法

0

皆様のお力を借りながら、当方も様々なTipsを見て色々と試しているうちに、
そもそも、今使っている一連のショートコードを使わないで、
まるっと別のショートコードに変えてしまえば良いのではないか? という結論に達しました。

こちらのブログのコードを拝借し、
表示順、class名、aタグが囲む範囲を変更しました。

// 最新記事リスト
function getNewItems($atts) {
    extract(shortcode_atts(array(
        "num" => '', //最新記事リストの取得数
        "cat" => '', //表示する記事のカテゴリー指定
        "days" => '', //何日以内の記事にadd_textをつけるか指定
        "add_text" => '' //表示するテキスト
    ), $atts));
    global $post;
    $oldpost = $post;
    $myposts = get_posts('numberposts='.$num.'&order=DESC&orderby=post_date&category='.$cat);
    $retHtml='<ul class="news_list">';
    foreach($myposts as $post) :
    $cat = get_the_category();
    $catname = $cat[0]->cat_name;
    $catslug = $cat[0]->slug;
        setup_postdata($post);
        $retHtml.='<li><a href="'.get_permalink().'">';
        $retHtml.='<span class="time">'.get_post_time( get_option( 'date_format' )).'</span>';
        //指定日以内にadd_textをつける
        $today = date_i18n('U');
        $entry_day = get_the_time('U');
        $past_days = date('U',($today - $entry_day)) / 86400;
        if ( $days > $past_days ):
        $retHtml.='<span class="new">'.$add_text.'</span>';
      endif;
        $retHtml.='<span class="title">'.the_title("","",false).'</span> ─ ';
        $retHtml.='<span class="category '.$catslug.'">'.$catname.'</span>';
    $retHtml.='</a></li>';
    endforeach;
    $retHtml.='</ul>';
    $post = $oldpost;
    wp_reset_postdata();
    return $retHtml;
}
add_shortcode("newsNew", "getNewItems"); //getNewItemsは関数名、newsNewはショートコード名
/* 新着情報 */
span.new {
    background: #cf2e2e;
    padding: 0.2rem 0.4rem;
    color: #FFF;
    font-size: 0.6rem;
    border-radius: 4px;
    font-weight: 700;
    margin-right: 0.5em;
    vertical-align: 0.1em;
}
span.category.slugA {
    background: #ffeaf4;
    padding: 0.2em 0.5em;
    font-size: 0.9em;
    border-radius: 4px;
    margin-left: 0.5em;
}
span.category.slugB {
    background: #d5e5fd;
    padding: 0.2em 0.5em;
    font-size: 0.9em;
    border-radius: 4px;
    margin-left: 0.5em;
}
span.category.slugC {
    background: #e8f9da;
    padding: 0.2em 0.5em;
    font-size: 0.9em;
    border-radius: 4px;
    margin-left: 0.5em;
}
span.category.slugD {
    background: #fff5d0;
    padding: 0.2em 0.5em;
    font-size: 0.9em;
    border-radius: 4px;
    margin-left: 0.5em;
}


CSSで見た目を整えて、上手く表示することができました。
こちらのコードだと、書いてある内容も分かりやすく、今後改造もしやすいのではないかと思います。

ご協力いただきました皆様、本当にありがとうございました。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

これは試しましたか?

    foreach ( $results as $p ) {
        $items_buff []= '<li><a href="'.get_permalink( $p->ID ).'">'.
            '<span class="time">'.mysql2date( 'Y.m.d', $p->post_date, false ).'</span>'.
            '<span class="new">NEW!</span>'.
            '<span class="title">'.esc_html( wp_trim_words( $p->post_title, 40 ) ).'</span> - '.
            '<span class="category">'.esc_html( $p->category_name ).'</span>'.
            '</a></li>';
    }
    $items_html = implode( '', $items_buff );

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/06/20 03:31

    早速のご回答ありがとうございます!
    新着一覧にある全ての記事に「NEW!」が表示されてしまいます。

    私の質問の仕方が悪かったのですが、、、
    新着一覧のうち、投稿日が5日前までの記事に「NEW!」アイコンを付けたいと思っています。

    質問文も少し修正しておきます。
    引き続きよろしくお願いいたします。

    キャンセル

0

まずは、functions.php のどこに書けば?ですが

色々コードが書いている場合は
一番最後尾の行から書き足しましょう
コードによっては最後の行に ?> が有る場合とない場合がありますが
ほとんどないと思います。
?>が有る場合は、それより前にコードを書いてください。

こんな感じ

コード
?>

あとは、Windowsのメモ帳を使っているのであればすぐにやめましょう
terapadやatomなどのテキストエディタと言うモノがそれを使ってください。

NEWを出したい場所に
<?php add_new(get_the_time('U'),5); ?>
を追加してください。
single.phpかな?

カテゴリの色分けなどは、今の問題をチャント理解してから自分でトライしてまた質問してください。
丸投げはダメですよ!!(笑)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/06/20 14:50

    ご回答いただきありがとうございます!

    functions.phpの末尾にコードを追加しても、それを読み出す新着一覧の一連の指定がショートコードになっているからか、該当箇所に<?php add_new(get_the_time('U'),5); ?>を書いても、そのままの文字がコメントアウトされた状態でhtmになってしまうのです(^^;

    ① 指定するものに適当な名前を付けて
    ② <li><span>〜〜</span></li>の中にそれを読み出して
    ③ できあがったものを<ul>〜〜</ul>で囲んで、できあがり!

    という流れだと思うのですが、
    ① 指定の方法、② 読み出す呪文 をどのようにすればよいのか悩んでいます。

    似たショートコードを(https://xakuro.com/blog/wordpress/504/)がありましたので、そちらを参考に、トライ&エラーをもう少し繰り返してみようと思います。

    テキストエディタは、「mi」というものを使っています。

    カテゴリの色分けも同様に、指定と呪文のトライ&エラーを続けます。

    キャンセル

0

>そのままの文字がコメントアウトされた状態でhtmになってしまうのです(^^;
ココが重要です
<?php add_new(get_the_time('U'),5); ?>
と出ているのか?
<span class="new">New</span>
と出ているのかで大きな違いがあります。

プログラムは理屈で考えれば必ず道は開けます

上記の場合だと
色々原因や可能性を考えることができます

<?php add_new(get_the_time('U'),5); ?>

出ている場合だと、テンプレートにチャント書けていない可能性が有る

後者の<span class="new">New</span>だと
テンプレートでの実行は出来ていてfunctions.phpも動いているが
出力の仕方に問題がある?

のように、予想して1つ1つ可能性をつぶしていきましょう

で、どっちが出ています?
若しくは別の表示のされ方ですか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/06/20 16:05

    色々と書き直して試している中なので、今もう一度そのままの文字列を記述してみました。
    該当の行に「'<?php add_new(get_the_time('U'),5); ?>'.」と書き込みましたが、「重大なエラー」でWebサイト自体が表示されなくなっていまいます。
    PHP内の記述なので、最初の <?php と、最後の;?>をはずしてみたらどうだろう?と思い、それも試しましたが同様です。
    コメントアウトされた状態が今再現できなかったのですが、html内に<!-- <?php add_new(get_the_time('U'),5); ?> --> と書き出されたように覚えています。

    NEWを書き出したい場所は、「該当のソースコード」の38行目です。
    最終的に固定ページに [recent_posts] というショートコードを入れるので、その手前(functions.php内のshortcode_recent_posts)で、完結させなくてはいけないと思っています。

    キャンセル

0

'<?php add_new(get_the_time('U'),5); ?>'.
ではなく
<?php add_new(get_the_time('U'),5); ?>
で表示してみたらどうですか?

とりあえず、ほかの文字と連結したりなどの処理は
後回しにして、コードをなるべく単純化して
まずは現状のコードが正常に機能しているか?調べてください。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/06/20 16:13

    <?php add_new(get_the_time('U'),5); ?> を試してみましたが、
    残念ながら、「重大なエラー」で、Webサイトが表示されない状態になってしまいました。

    調べながら色々試して頑張ってみます(^^

    キャンセル

0

今までやり取りしていたのは、ショートコードではなく
テンプレート(single.phpなど)に追記するやり方ですが
その辺はご理解いただけていますでしょうか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/06/20 16:39

    テンプレートに追記する方法をご助言いただいているのは、理解しているつもりでした。

    でも、今回は「トップページに表示する新着一覧」に「NEW!」を表示したいので、ショートコードに指定しなくてはならないのです。

    と思い込んでいましたが、、、
    もしかして、テンプレートに追記して、記事本体に「NEW!」が表示されれば、新着一覧にも同時に反映されるということでしょうか?

    早速試してみます!!

    キャンセル

  • 2020/06/20 17:17 編集

    試してみました!
    記事本体と、カテゴリー一覧には、無事「NEW!」が表示されましたが、
    残念ながらトップページの新着記事一覧には反映されませんでした。
    追記したのは、template-parts → post → content.php の中です。
    ```PHP
    <header class="entry-header">
    <?php add_new(get_the_time('U'),3); ?> // ←ここに追記!
    <?php
    if ( is_single() ) {
    the_title( '<h1 class="entry-title">', '</h1>' );
    } elseif ( is_front_page() && is_home() ) {
    the_title( '<h3 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h3>' );
    } else {
    the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' );
    }
    ?>
    </header><!-- .entry-header -->
    ```

    キャンセル

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

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

関連した質問

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