Discuss and resolve questions on Liquid, JavaScript, themes, sales channels, and site speed enhancements.
I'm trying to list all blogs on my site with liquid, something like:
{% for blog in blogs %} <h2>{{ blog.title }}</h2> {% endfor %}
But this doesn't seem to work. Is there any way to do this?
Code looks fine.
Do you have any blog in your shop? Is that code inside a visible section?
Blogs in liquid are all shop's blog topics.
Each blog topic has it's own name, articles etc. See liquid blogs object https://shopify.dev/docs/api/liquid/objects/blogs
Doesn't work… the blogs object only allows you to retrieve a blog by specific handle. It won't allow me to loop through them.
Hi @Leoster
I don't think, there is a blogs object in shopify that you can use
But you can use it by passing a blog handle like if you want to show blog articles under a blog, the you can use a code like this
{% for article in blogs["news"].articles %}
<h2>{{ article.title }}</h2>
{% endfor %}
Here "news" is blog handle, when you go to Online store --> Blog Posts --> Manage Blogs
and then view a blog on frontend then last part of the url (after blogs/) like yourstore/blogs/news is blogs handle
I think, it will help you to get an idea
Thanks!
This doesn't solve the problem, which is to show all blogs programatically. Without being able to iterate all blogs, it means every time I add a blog I would have to go update templates manually.
I assume Shopify intended this to be something you'd set once while setting up a shop and rarely if ever touch again… but I am using blogs to separate out content categories, which are currently around 25 and will scale to at least 100.
Hi @Leoster
I don't think, there is some other way for this till now
Either you can use a static blogs list like this:
{% assign blog_handles = "blog1,blog2,blog3" | split: "," %}
{% for handle in blog_handles %}
{% for article in blogs[handle].articles %}
<h2><a href="{{ article.url }}">{{ article.title }}</a></h2>
{% endfor %}
{% endfor %}
Or Use a linked list and iterate like this
{% for link in linklists.blogs.links %}
{% assign blog = link.object %}
{% for article in blog.articles %}
<h2><a href="{{ article.url }}">{{ article.title }}</a></h2>
{% endfor %}
{% endfor %}
The other way is you can use shopify api and create an app for this
Rest API Reference: https://shopify.dev/docs/api/admin-rest/2024-04/resources/blog#get-blogs
Thanks!
This still seems to be the case (can't iterate over the `blogs` object). Something else to watch out for: you're limited to 50 items when looping over `blog.articles` - it's mentioned in the docs that you need to paginate to cater for more. One thing that wasn't obvious to me is this limit seems to apply at the point you get the articles, so trying to find a specific one using e.g. `
@Leoster Another solution is to use liquid to get all the blog data, pass it to js, and then render the layout using js code.
Get data using liquid
{% assign blog_handles = "handle1,handle2,handle3,handle4" | split: "," %}
{% for handle in blog_handles %}
{% paginate blogs[handle].articles by 100 %}
{% for article in blogs[handle].articles %}
{% assign article_data = article | json | remove_last: '}'
| append: ',category_handle: "'
| append: handle | append: '"' | append: ',category: "'
| append: blogs[handle].title | append: '"'
| append: '}'
| append: ','
| append: article_data %}
{% endfor %}
{% endpaginate %}
{% endfor %}
Transfer data to JS.
Note: add this script to the bottom of the page(section)
<script>
// article data
const articlesData = [{{article_data | remove_last: ',' }}];
// article wrapper
const articleWrapper = document.querySelector('.blog-articles');
// sort posts by published date
articlesData.sort((a,b) => new Date(a.updated_at).getTime() - new Date(b.updated_at).getTime());
articlesData.reverse();
console.log(articlesData);
// create your js logic to render blog posts
const articleTemplate = (article) => {
return `<div class="article">
<h1>${article.title}</h1>
<div>Category: ${article.category}</div>
<div>${article.summary_html}</div>
<div>Created at: ${article.created_at}</div>
</div>`;
};
let articleHTML = '';
articlesData.forEach((article) => {
articleHTML += articleTemplate(article);
});
// render articles
articleWrapper.innerHTML = articleHTML;
</script>
You can improve the code and add logic for pagination etc...
NOTE: This script will only work if the blog has less than 100 posts. If it exceeds 100 posts per blog you need to modify and add more logic to the code so it will not break.
CC: @Serj94 @pawankumar
Leysam | The Shopify Guy
- Was my reply helpful? Click Like to let me know!Hey Community! As the holiday season unfolds, we want to extend heartfelt thanks to a...
By JasonH Dec 6, 2024Dropshipping, a high-growth, $226 billion-dollar industry, remains a highly dynamic bus...
By JasonH Nov 27, 2024Hey Community! It’s time to share some appreciation and celebrate what we have accomplis...
By JasonH Nov 14, 2024