1つのブログ内でタグ別に記事を出し分けたい

1ブログテンプレートのなかで、mediaというハンドル名のブログ内のタグ1とタグ2のブログ記事を5つずつ出力したいと思っております。

以下のようなlimitを付けて5つずつ、タグ1とタグ2の記事をそれぞれ表示させようとしたときにfor文で分けているにも関わらず、タグ1とタグ2あわせて5つのブログ記事を出力されてしまいます。

様々な方法を試してみたのですが、どうしてもこちら思ったように出力されません。

お手すきでご教授いただけますと幸いです。


										{% for article in blogs['media'].articles limit: 5 %}
											{% for tag1 in article.tags  %}
												{% if tag1 == 'タグ1' %}
										
											

												
											

											
												
{{ article.created_at | date: '%Y年 %-m月 %d日' }}

												{{ article.title }}

											

										
												{% endif %}
											{% endfor %}
										{% endfor %}

									

									

										{% for article in blogs['media'].articles limit: 5 %}
											{% for tag1 in article.tags  %}
												{% if tag1 == 'タグ2' %}
										
											

												
											

											
												
{{ article.created_at | date: '%Y年 %-m月 %d日' }}

												{{ article.title }}

											

										
												{% endif %}
											{% endfor %}
										{% endfor %}

									

limt:5の箇所が原因かと思います。

記述されている内容では以下の動作となるためご要望の動作にはならないはずです。

  1. mediaのブログから5つ取り出す
  2. 取り出した5記事のうち、該当のタグのある記事だけを取り出す

この状態で合計5記事になる理由としては、おそらく偶然取得した5記事の中にそれぞれのタグの記事が含まれていたためではと推測しています。

whereフィルターが使えるのでは、と思ったのですが試したところ動かず、興味も出てきましたので以下のコードを試作してみました。

{% comment %} 指定タグを持ったブログのhandleをカンマ区切りで変数に追加 {% endcomment %}
{% assign article_handles1 = '' %}{% comment %} 指定タグ1 {% endcomment %}
{% assign article_handles2 = '' %}{% comment %} 指定タグ2 {% endcomment %}
{% for article in blogs['media'].articles %}
  {% for tag in article.tags %}
    {% if tag == 'red' %}
      {% assign article_handles1 = article_handles1 | append: ',' | append: article.handle  %}
    {% elsif tag == 'ss' %}
      {% assign article_handles2 = article_handles2 | append: ',' | append: article.handle  %}
    {% endif %}
  {% endfor %}
{% endfor %}

{% comment %} 指定タグ1用 {% endcomment %}
{% if article_handles1 != '' %}
{% comment %} カンマ区切りの変数を配列に変換 {% endcomment %}
  {% assign article_handles_array1 =  article_handles1 | remove_first: "," | split: ',' %}
  
  {% comment %} handleの配列をforでひとつづつ取り出して実行 {% endcomment %}
  {% for article_handle in article_handles_array1 limit:5 %}
    - {{ articles[article_handle].title }}
  {{ articles[article_handle].created_at | date: '%Y年 %-m月 %d日' }}
  {% endfor %}
  

{% endif %}

{% comment %} 指定タグ2用 {% endcomment %}
{% if article_handles2 != '' %}
  {% assign article_handles_array2 =  article_handles2 | remove_first: "," | split: ',' %}
  
  {% for article_handle in article_handles_array2 limit:5 %}
    - {{ articles[article_handle].title }}
  {{ articles[article_handle].created_at | date: '%Y年 %-m月 %d日' }}
  {% endfor %}
  

{% endif %}

不足している部分は上記のコードを参照していただければ出力できると思います。

基本的には各for文の中で以下のような形に記述すれば値を取り出せるはずですので。

{{ articles[article_handle].title }}
{{ articles[article_handle].handle }}
{{ articles[article_handle].url }}

■概要

多少コメント部分に書きましたのであまり詳細な説明はしませんが、概ね以下のようなことを行っています。

  1. ブログ内の全記事から、対象となるタグを持つ記事のハンドルだけの一覧を作成し、配列に変換する
  2. 作成した配列からハンドルを取り出し、articlesオブジェクトに直接設定して値を取得する

以上です。
一応動作は確認していますが、問題があるかもしれませんのでその際は申し訳ありません。

なお、他にもっとスマートな方法があるのではとも思いますので申し少し他の方の回答を待っていただくのがよいかなと思います。
(私のサンプルコードの問題点を指摘いただけるかもしれません)

2 Likes

ありがとうございます!!
どうしても上手くいかず、blogsを全て分けて対応するかなど考えていたところでした。。

早速、こちら対応してみます!

こちら思った通りに1つのブログ内のタグ毎にリストを5つずつ出し分けをすることが成功したのですが、、なぜか必ず1つ目に空のリストが作られてしまいます。。
Ishigaki様のほうでは1つ目に空の箱は生成されませんか?少しカスタマイズしてみたりしたのですが、、どうしても1つ目のリストが空になる現象を解決できず。。

この問題だけ解決できれば思ったような形となるので…大変恐縮ですがこちらの解決方法をご教授いただけますと幸いです。

確認いただきありがとうございます。

私の方ではそのような状態にはなっておらず再現もできませんでした。

こういう場合、まずは値が取れているかどうかを確認することが有効なので、コードの最後あたりに以下を記載していただけますか?


{{ article_handles1 | json }}

{{ article_handles_array1 | json }}

{{ article_handles2 | json }}

{{ article_handles_array2 | json }}

私が確認している範囲では以下のように表示されるはずです。「ハンドル1」や「ハンドル2」は適当ですが、取得した記事のハンドルが順に最大で5つ並ぶ想定です。

",media\/ハンドル1,media\/ハンドル2,media\/ハンドル3"
["media\/ハンドル1","media\/ハンドル2","media\/ハンドル3"]
",media\/ハンドル4,media\/ハンドル5,media\/ハンドル6"
["media\/ハンドル4","media\/ハンドル5","media\/ハンドル6"]

上記の様になっていなければ、取得時に何かしら問題があるように思います。指定するタグを変更したり、別のブログに別のタグを設定して試すなどで、表示が変化するかを確認してください。

また「空の箱」という部分で実際には何が出力されているのかも確認してください。
開発者ツールを使って該当箇所を確認し、

  • だけなのか、間に何か表示されているのか、liタグ自体もないのか、などです。

    1 Like
    Show More

    迅速なご対応ありがとうございます。。
    mediaというブログのなかでタグは「種類」と「資格」の2種類ありまして、それを頂いたソースコードの各指定タグを入れる項目に入れております。

    {% comment %} 指定タグを持ったブログのhandleをカンマ区切りで変数に追加 {% endcomment %}
    {% assign article_handles1 = '種類' %}{% comment %} 指定タグ1 {% endcomment %}
    {% assign article_handles2 = '資格' %}{% comment %} 指定タグ2 {% endcomment %}
    
    {% for article in blogs['media'].articles %}
      {% for tag in article.tags %}
        {% if tag == '種類' %}
          {% assign article_handles1 = article_handles1 | append: ',' | append: article.handle  %}
    
        {% elsif tag == '資格' %}
          {% assign article_handles2 = article_handles2 | append: ',' | append: article.handle  %}
    
        {% endif %}
      {% endfor %}
    {% endfor %}
    
    {% comment %} 指定タグ1用 {% endcomment %}
    {% if article_handles1 != '種類' %}
    {% comment %} カンマ区切りの変数を配列に変換 {% endcomment %}
      {% assign article_handles_array1 =  article_handles1 | remove_first: "," | split: ',' %}
    
      {% comment %} handleの配列をforでひとつづつ取り出して実行 {% endcomment %}
      {% for article_handle in article_handles_array1 limit:5 %}
    
    {% comment %} 画像自体のパスしか生成されないから一時的に絶対パスを入れておく {% endcomment %}
    
    {{ articles[article_handle].created_at | date: '%Y年 %-m月 %d日' }}
    
    {{ articles[article_handle].title }}
    
      {% endfor %}
    
    {% endif %}
    
    {% comment %} 指定タグ2用 {% endcomment %}
    {% if article_handles2 != '資格' %}
      {% assign article_handles_array2 =  article_handles2 | remove_first: "," | split: ',' %}
    
      {% comment %} handleの配列をforでひとつづつ取り出して実行 {% endcomment %}
      {% for article_handle in article_handles_array2 limit:5 %}
    
    {{ articles[article_handle].created_at | date: '%Y年 %-m月 %d日' }}
    
    {{ articles[article_handle].title }}
    
      {% endfor %}
    
    {% endif %}
    
    現在、両タグはそれぞれ3つずつテスト記事を入れ込んでいる状態ですが、出力すると最新の3つ目の記事が以下のようにデータ自体が取得できません。。
    
      
    
    2021年 6月 25日
    
    テストA2
    
      
    
    2021年 6月 25日
    
    テストA1
    
      
    
    2021年 6月 25日
    
    テストB2
    
      
    
    2021年 6月 25日
    
    テストB1
    
    

    頂いたコードを最下部へ設置したところ

    "種類,media\/テストa3,media\/テストa2,media\/テストa1"
    ["種類media\/テストa3","media\/テストa2","media\/テストa1"]
    "資格,media\/テストb3,media\/テストb2,media\/テストb1"
    ["資格media\/テストb3","media\/テストb2","media\/テストb1"]
    

    このように出力されます!
    jsonで出力すると問題なく最新のa3とb3が取得できているということは、、私の記述ミスですかね…?

    お忙しいなか真摯にご対応いただき有難うございます。

    私のコメントと説明に問題がったのが原因ですが、コードに不要な記述が追加されているために不具合が発生しています。

    具体的には、配列にするために作成する一覧の先頭に「種類」と「資格」という文字列が入る指定になっています。
    この「種類」と「資格」はハンドルではないでブログの記事が取得できなかった、という状態です。

    {% assign article_handles1 = '種類' %}{% comment %} 指定タグ1 {% endcomment %}
    {% assign article_handles2 = '資格' %}{% comment %} 指定タグ2 {% endcomment %}
    
    ↓以下のようにしてください
    
    {% assign article_handles1 = '' %}
    {% assign article_handles2 = '' %}
    

    上記がコメントを書き間違っていた部分でして、ややこしくしてしまい申し訳ありません。
    これは変数の初期化のなので値は入れません。

    {% if article_handles1 != '種類' %}
    
    ↓以下のようにしてください
    
    {% if article_handles1 != '' %}
    

    上記も同様に値を入れないで下さい。
    ここはハンドルが一つも取れなかった時、つまり指定のタグが一つ付与されていない場合に表示用コードを実行しないようにするための記述です。

    {% if article_handles2 != '種類' %}
    
    ↓以下のようにしてください
    
    {% if article_handles2 != '' %}
    

    上記も前項と同様です。

    つまり、前回私が記載しましたコードで変更する箇所は以下の2点のみです。

    {% if tag == 'red' %}
    
    {% if tag == 'ss' %}
    

    上記の「red」と「ss」を任意のタグで書き換えていただくだけで動作します。
    コメントで書いたつもりだったのですが、そもそもこの点の説明が抜けていましたね…。

    説明が不足しており申し訳ありませんでした。

    なお、書いてもややこしくなるのでこちらに投稿しませんでしたが、私のブログの方でブラッシュアップ版のコードを載せていますので一応お知らせします(後ほど時間ができたらもう少し触るかもしれませんが)。

    https://webutubutu.com/webdesign/9748

    上記記事内のコードであれば、最上部のコメントで「初期設定」と書いている下の4行のみが変更箇所なので、初期案から比べると分かりやすいかと思います。

    2 Likes

    なるほどですね…!

    ありがとうございます!ご指摘をいただいた内容でクリアとなりました!

    とても助かりました。。
    初心者に対して長くお付き合いくださり誠にありがとうございます!