Conversations about creating, managing, and using metafields to store and retrieve custom data for apps and themes.
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!
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.
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.
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?
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.
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 %}
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 -%}
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 %}
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 %}
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 %}