Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

Re: Blog Post Metafield Type

Blog Post Metafield Type

AWBroch
Shopify Partner
7 0 2

Does anyone know if it is possible to link to blog posts from a product (i.e., a ‘Related Articles’ section inside a product page). Metafields seem like they should work for this, but there doesn’t seem to be a ‘blog post’ metafield type—are there any workarounds?

 

I want to avoid using apps or a custom storefront.

 

Thanks!

Replies 12 (12)

AWBroch
Shopify Partner
7 0 2

I did a bit more research and decided to go with just setting the related products as a metafield on the blog post. Then, when I render the products, I can go through the blog and only render the articles that include the current product id in their related products. Just putting it here in case anyone else is looking for this question.

LIYAShop
Excursionist
30 2 2

Would you mind sharing how exactly you did that?
I need the same solution and I don't have technical knowledge to do that without instructions.

AWBroch
Shopify Partner
7 0 2
LIYAShop
Excursionist
30 2 2

This is great. I just can't figure out where to use this code. I've tried to use it in Custom Liquid as well as creating a new Section in code and neither worked for me. Could you please give me little guidance?

AWBroch
Shopify Partner
7 0 2
The code snippet from the blog post is used to get an array of the related articles, and then you need to render it in a section. Your theme should already have a section for displaying blog posts, and you can copy and paste most of the code from there, but every theme is set up a bit differently. The rendering code from your theme and the filtering code snippet to get the articles would go together in a section <>, along with the settings needed—at least the handle of the blog (`section.settings.blog`) and a post limit (`section.settings.post_limit`), plus whatever is needed for your theme.
LIYAShop
Excursionist
30 2 2

Thank you for the effort! It's a bit too complicated for me to implement.

I will focus on other issues at the moment and get back to this task a bit later.

I will update you, if I ever get it done and live to tell the tale.

LIYAShop
Excursionist
30 2 2

I've tried to use this code in a custom liquid section in a theme editor, just to see if it finds any blog posts at all, before I try to stylize them. It doesn't, is there something wrong with the code or did I set it it up wrong?

 

The definition of the metafield where I link the product to a blog post is article.metafields.custom.press_products. I was able to show the related products on the blog post page, so I know the link between the post and the article is working.

 

{%- assign blog = blogs[section.settings.blog] -%}
{%- assign limit = section.settings.post_limit -%}

{% liquid
  assign articles_to_display = 0
  assign articles = ''
  assign index = 0
  for _ in (1..50)
    for _ in (1..50)
      if blog.articles[index] and articles_to_display < limit
        for related_product in blog.articles[index].metafields.custom.press_products
          if related_product.id == product.id
            assign articles = articles | append: '-' | append: index
            assign articles_to_display = articles_to_display | plus: 1
            break
          endif
        endfor
        assign index = index | plus: 1
      else
        break
      endif
    endfor
    unless blog.articles[index] and articles_to_display < limit
      break
    endunless
  endfor
  assign articles = articles | remove_first: '-'
%}

{% if articles.size == 0 %}
  <p>Goodnight</p>
{% else %}
  {% for article_index in articles %}
    <h2><a href="{{ blog.articles[article_index].url }}">{{ blog.articles[article_index].title }}</a></h2>
  {% endfor %}
{% endif %}

 

 

 

AWBroch
Shopify Partner
7 0 2

On the first two lines of the code snippet:

 

 

{%- assign blog = blogs[section.settings.blog] -%}
{%- assign limit = section.settings.post_limit -%}

 

 

If you’re just using a custom Liquid block, you should hardcode the values instead of using section settings. Use the section settings if you put the code in it’s own section file with a schema and everything, and that way the options will show up in the admin.

 

 

{%- assign blog = blogs['handle-of-blog'] -%}
{%- assign limit = 3 -%}

 

 

LIYAShop
Excursionist
30 2 2

Did that, but I still get Goodnight

{%- assign blog = blogs['Press'] -%}
{%- assign limit = 3 -%}

{% liquid
  assign articles_to_display = 0
  assign articles = ''
  assign index = 0
  for _ in (1..50)
    for _ in (1..50)
      if blog.articles[index] and articles_to_display < limit
        for related_product_ref in blog.articles[index].metafields.custom.press_products
          if related_product_ref.id == product.id
            assign articles = articles | append: '-' | append: index
            assign articles_to_display = articles_to_display | plus: 1
            break
          endif
        endfor
        assign index = index | plus: 1
      else
        break
      endif
    endfor
    unless blog.articles[index] and articles_to_display < limit
      break
    endunless
  endfor
  assign articles = articles | remove_first: '-'
%}

{% if articles.size == 0 %}
  <p>Goodnight</p>
{% else %}
  {% for article_index in articles %}
    <h2><a href="{{ blog.articles[article_index].url }}">{{ blog.articles[article_index].title }}</a></h2>
  {% endfor %}
{% endif %}
AWBroch
Shopify Partner
7 0 2

You need to use the handle of the blog: `https://yourstore.com/blogs/this-is-the-handle`. It should be lowercase.

The other thing to check is if there’s a global `product` object. If you’re on a product page, there will be, but if you’re testing it on another page there might not be.

 

The code snippet I sent is also missing the last part. There’s no user-creatable array type in Liquid, so the indices are stores in a hyphen separated string. So, `articles` needs to be split on hyphens, and then coerced from a string to a number by adding a `| plus: 0` filter before using it to index `blog.articles`. Like this:

 

 

{%- assign blog = blogs['press'] -%}
{%- # double-check that `press` is the right handle by checking the URL of the page that lists all the blog posts -%}
{%- assign limit = 3 -%}

{% liquid
  assign articles_to_display = 0
  assign articles = ''
  assign index = 0
  for _ in (1..50)
    for _ in (1..50)
      if blog.articles[index] and articles_to_display < limit
        for related_product_ref in blog.articles[index].metafields.custom.press_products
          if related_product_ref.id == product.id
            assign articles = articles | append: '-' | append: index
            assign articles_to_display = articles_to_display | plus: 1
            break
          endif
        endfor
        assign index = index | plus: 1
      else
        break
      endif
    endfor
    unless blog.articles[index] and articles_to_display < limit
      break
    endunless
  endfor
  assign articles = articles | remove_first: '-'
  assign article_indices = articles | split: '-'
%}

{% if article_indices.size == 0 %}
  <p>Goodnight</p>
{% else %}
  {% for article_index_str in article_indices %}
    {%- assign article_index = article_index_str | plus: 0 -%}
    <h2><a href="{{ blog.articles[article_index].url }}">{{ blog.articles[article_index].title }}</a></h2>
  {% endfor %}
{% endif %}

 

LIYAShop
Excursionist
30 2 2

I got it working with this code. This might not be poetry, but it works now, while I have 3 products and 3 posts.

As far as I understand, Shopify will only pick 50 posts to go through? How do I make it go over the limit, any ideas?

 

{%- assign blog = blogs['news'] -%}
{%- assign current_product_id = product.id | remove: '"' -%}

{%- if blog.articles_count > 0 -%}
  {%- for article in blog.articles -%}
    {% assign image_url = article.image.src | img_url: 'medium' %}
    {% assign gid_parts = article.metafields.custom.press_products | split: '","' %}
    {% for gid_part in gid_parts %}
      {% assign product_blog = gid_part | split: '/' | last | remove: '"]' | remove: '"' %}
      {%- if template == 'product' and product_blog == current_product_id -%}
        <img src="{{ image_url }}" alt="{{ article.title }}" style="display: block; margin-bottom: 10px;">
        <h2>{{ article.title }}</h2>
      {%- endif %}
    {% endfor %}

    {{ article.content }}
  {%- endfor %}
{%- endif %}

 

AWBroch
Shopify Partner
7 0 2
Good, glad it’s working.

I haven’t actually tried it with that many, but I added two loops of 50, one inside the other, to hopefully be able to handle up to 2500 posts.