Shopify liquid get related blog posts - html

In shopify I am using liquid templating to get blog posts which are related to products by their tags, like so:
<ul>
{% for article in blogs.blog.articles %}
{% if article.tags contains product.handle %}
<li><p>{{ article.title }}</p></li>
{% endif %}
{% endfor %}
</ul>
However, if there are no related posts, I would like to display a message such as "No related posts!"
My question is how would I do that? I have contemplated trying to get the articles into an array and testing if it is empty, but I am having difficulty finding out how this is done.
Thanks!

Try something like this:
{% assign related_posts = "" %}
{% for article in blogs.blog.articles %}
{% if article.tags contains product.handle %}
{% capture post %}
<li><p>{{ article.title }}</p></li>
{% endcapture %}
{% assign related_posts = related_posts | append:post %}
{% endif %}
{% endfor %}
{% if related_posts.size > 0 %}
<ul> {{ related_posts }} </ul>
{% else %}
No related posts!
{% endif %}

<ul>
{% for article in blogs.blog.articles %}
{% if article.tags contains product.handle %}
<li><p>{{ article.title }}</p></li>
{% else %}
<li>No related blog posts!</li>
{% endif %}
{% endfor %}
</ul>

Related

I Need Support Code To Link Articles Via Tag

I have a piece of code:
{% if article.tags.size > 0 %}
<div class="related-posts">
<h3>Read More:</h3>
<ul>
{% for tag in article.tags %}
{% for related_post in blogs[blog.handle].articles %}
{% if related_post.tags contains tag and related_post.handle != article.handle %}
<li>{{ related_post.title }}</li>
{% endif %}
{% endfor %}
{% endfor %}
</ul>
</div>
{% endif %}
This code has the effect of creating internal links between articles with the same tag as read more . I have a problem. If I put this code on the website it worked. But it only retrieves articles with the same post category. As for the articles that are not in the same category of articles, it will not be retrieved. I changed the code blogs[blog.handle].articles to blog.articles. But it still doesn't work. I use Sense 3.0.0 theme Shopify.
Can someone help me with this problem.
Thank you!
{% if article.tags.size > 0 %}
<div class="related-posts">
<h3>Read More:</h3>
<ul>
{% for tag in article.tags %}
{% for related_post in blogs[blog.handle].articles %}
{% if related_post.tags contains tag and related_post.handle != article.handle %}
<li>{{ related_post.title }}</li>
{% endif %}
{% endfor %}
{% endfor %}
</ul>
</div>
{% endif %}

why i don't see all parts in html using django

I wrote the following code:
{% extends "base.html" %}
{% block content %}
{% if all_site %}
<ul>
<h3>Here all my site:</h3>
{% for site in all_site %}
<li> {{ site.name }}</li>
{% endfor %}
</ul>
{% else %}
<h3> You don't have any Site.</h3>
{% endif %}
{% endblock content %}
when, I run. I not see "Here all my site", but I only see the one contained in the for.
I tried to modify it, for now a solution that I have found working is this:
{% extends "base.html" %}
{% block content %}
{% if all_site %}
<h3>mmmmmm</h3>
<ul>
<h3>Here all my site:</h3>
{% for site in all_site %}
<li> {{ site.name }}</li>
{% endfor %}
</ul>
{% else %}
<h3> You don't have any Site.</h3>
{% endif %}
{% endblock content %}
in this case if I do run, i see:
here all my site:
site 1
site 2

Single Index Blog Post for Multiple Series Posts in Jekyll

I have several blog posts that fall under one umbrella blog post. For example, I have several posts about SQL Zoo tutorials, but I want to be able to link them all up to one "umbrella" post so that I only have one SQL Zoo post on the index page of my blog. I got this idea from: https://codeasashu.github.io/implement-series-post-jekyll-part-2/ and tried to follow the instructions, but now my series post does not show up on my index page. I have the following code in a file called post-series.html located in my _includes folder:
{% assign seriesarray = '|' | split : '|' %}
{% assign seriestitle = '' %}
{% assign serieslabel = '' %}
{% assign sortedposts = (site.posts | sort: 'date') %}
{% for post in sortedposts %}
{% if post.series and page.series_slug != nil and post.series == page.series_slug %}
{% capture postitem %} <li> {{ post.title }} </li> {% endcapture %}
{% assign seriesarray = seriesarray | push: postitem %}
{% assign seriestitle = 'Posts in this series' %}
{% assign serieslabel = 'Series Post' %}
{% elsif post.series != nil and page.series != nil and page.series == post.series %}
{% assign pageurl = page.url | split:'/' | last %}
{% assign posturl = post.url | split:'/' | last %}
{% if pageurl != posturl %}
{% capture postitem %} <li> {{ post.title }} </li> {% endcapture %}
{% else %}
{% capture postitem %} <li> {{ post.title }} </li> {% endcapture %}
{% endif %}
{% assign seriesarray = seriesarray | push: postitem %}
{% endif %}
{% if post.series_slug != nil and page.series != nil and page.series == post.series_slug %}
{% capture series_title %} {{ post.title }} {% endcapture %}
{% assign seriestitle = 'This posts is part of series - ' | append: series_title %}
{% assign serieslabel = 'This posts is part of series - ' | append: series_title %}
{% endif %}
{% endfor %}
{% capture serieslayout %}
{% if seriesarray.size > 0 %}
<hr />
<div class="panel">
<div class="panel-body">
<h4> {{ seriestitle }} </h4>
<ul id="post-series-list">
{% endif %}
{% for post in seriesarray %} {{ post }} {% endfor %}
{% if seriesarray.size > 0 %} </ul> </div> </div> {% endif %}
{% endcapture %}
and the following code from my index.html file in the root of my directory:
---
layout: index
---
<div id="home">
<h1>{{ site.title }}</h1>
<hr />
<ol class="posts">
{% for post in paginator.posts %}
{% assign seriesPost = nil %}
{% if post.series == nil %}
{% if post.series_slug != nil %} {% assign seriesPost = '(Series)' %} {% endif %}
<li class="post-listing">
<img class="post__image" src="/static/img/{{ post.cover_image}}" alt="{{ post.cover_alt }}" />
<div class="post__text">
<a class="post__title" href="{{ post.url }}">{{ post.title }}</a><br>
<span>
{{ post.date | date_to_string }} •
{% assign words = post.content | number_of_words %}
{% if words < 360 %}
1 min read
{% else %}
{{ words | divided_by:180 }} min read
{% endif %}
</span>
{{ post.excerpt }}
</div>
</li>
{% endif %}
{% endfor %}
</ol>
<!-- <div class="sidebar-right sidebar"></div> -->
<!-- <ul>
{% for post in paginator.posts %}
<li>
{{ post.title }}
{{ post.excerpt }}
</li>
{% endfor %}
</ul> -->
<!-- Pagination links -->
{% if paginator.total_pages > 1 %}
<ul class="pagination pagination-sm">
{% if paginator.previous_page %}
<li>«</li>
{% else %}
<li class="disabled"><span aria-hidden="true">«</span></li>
{% endif %}
<li>First</li>
{% for page in (1..paginator.total_pages) %}
{% if page == paginator.page %}
<li class="active"><a>{{ page }}<span class="sr-only">(current)</span></a></li>
{% elsif page == 1 %}
<li>{{ page }}</li>
{% else %}
<li>{{ page }}</li>
{% endif %}
{% endfor %}
<li>Last</li>
{% if paginator.next_page %}
<li>»</li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
</div><!-- end #home -->
My full repo can be found here: https://github.com/thedatasleuth/thedatasleuth.github.io
In your index.html, {% if post.series == nil %} simply bares posts containing a series: someserie front matter variable to be printed.
For the second problem (note that on SO, you are supposed to ask one question at a time) :
Umbrella post always have series_slug: "My serie slug" in front
matter.
Serie's posts always have series: "My serie slug" in front
matter, and this must be strictly equal to umbrella page series_slug. (eg : you have a post with published: false and series: "SQL Zoology" that will not appear in SQL Zoo serie if you publish it.)
In _layouts/post.html remove {% include series.html %}.
In _includes/post-series.html replace all your code by the following :
{% comment %} #### On an umbrella page {% endcomment %}
{% if page.series_slug != nil %}
{% assign key = page.series_slug %}
{% assign title = page.title %}
{% assign url = page.url %}
{% assign sentence = "All posts in this serie :" %}
{% endif %}
{% comment %} #### On a serie page {% endcomment %}
{% if page.series != nil %}
{% assign key = page.series %}
{% assign umbrella_page = site.posts | where: 'series_slug', key | first %}
{% assign title = umbrella_page.title %}
{% assign url = umbrella_page.url %}
{% assign series_posts = site.posts | where: "series", key %}
{% for post in series_posts %}
{% if post.url == page.url %}
{% assign idx = forloop.index %}
{% endif %}
{% endfor %}
{% capture sentence %}
This article is <strong>Part {{ idx }}</strong> in a <strong>{{ series_posts.size }}-Part</strong> in {{ title }} serie
{% endcapture %}
{% endif %}
{% if page.series_slug != nil or page.series != nil %}
{% assign series_posts = site.posts | where: "series", key %}
<hr />
<div class="panel">
<div class="panel-body">
{% if page.series_slug != nil %}
{% assign key = page.series_slug %}
{% assign title = page.title %}
{% assign url = page.url %}
{% endif %}
<h4>{{ sentence }}</h4>
<ul id="post-series-list">
{% for post in series_posts %}
<li>
{% if page.url == post.url %}
This post : {{ post.title }} - part {{ forloop.index }}
{% else %}
{{ post.title }} - part {{ forloop.index }}
{% endif %}
</li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
The problem you are facing
You forgot to add the series and series_slug YML variables. That is why it is not working in your case. You seem to not fully understand how the code works, probably due to the complexity of the solution. Therefore, I added another (much simpler) solution, that might fit your needs equally well.
A better/simpler solution
Simply add a YML variable called group: groupname to each post you want in a group. Do NOT skip any of the posts during pagination. Next, list the posts with the same group on the footer of each post (in your page/post layout) with the code below. Finally, add 'part 1', 'part 2', etc. to the post names in the series.
{% if post.group != nil %}
<ul>
{% for post in site.posts %}
{% if post.group == page.group %}
<li>{{ post.title }}</li>
{% endif %}
{% endfor %}
</ul>
{% endif %}
PS. If you really want to skip some posts in the pagination, I would create an universal solution. Add a skip_pagination boolean to the Front Matter (YML) and see if it is true in the pagination loop. This enables you to skip any post in the paginator.

Django Multi-Conditional Statement

I have the following code working in a Django HTML template. However, it’s quite repetitive. How can this code be simplified?
It translates to, "If you're not staff, you get to see nav.html. If you are staff, you only get to see nav.html if you're on these 4 pages."
{% if not request.user.is_staff %}
{% include ‘nav.html’ %}
{% else %}
{% if request.get_full_path == ‘/one/’ %}
{% include ‘nav.html’ %}
{% if request.get_full_path == ‘/two/’ %}
{% include ‘nav.html’ %}
{% if request.get_full_path == ‘/three/’ %}
{% include ‘nav.html’ %}
{% if request.get_full_path == ‘/four/’ %}
{% include ‘nav.html’ %}
{% endif %}
{% endif %}
From your view, you can send a list containing the paths for which to show nav.html. Something like,
allowed_paths = ['/one/', '/two/', '/three/', '/fourth/']
In your template, you can simply do,
{% if not request.user.is_staff or request.get_full_path in allowed_paths %}
{% include 'nav.html' %}
{% endif %}

Django template: Show a link only once if a user belongs in more than one groups

I have a template in django that shows a link if a user has group name different than patient.
My code is:
{% if user.is_authenticated %}
{% for group in user.groups.all %}
{% if group.name != 'Patient' %}
<li {% if request.get_full_path == modules_url %} class="active" {% else%} class="inactive"{% endif %}>
<b style="color:#ff9904;">Modules</b>
</li>
{% endif %}
{% endfor %}
{% endif %}
In case a user is a member of four different groups, the link Modules is shown 4 times in the template.
Is there any way to show it only once?
I think by handle using templatetags should easier.
from django import template
from django.contrib.auth.models import Group
register = template.Library()
#register.filter(name='has_group')
def has_group(user, group_name):
"""
{% if request.user|has_group:'grouName' %}
{# do_stuff #}
{% endif %}
return Boolean (True/False)
"""
group = Group.objects.get(name=group_name)
return group in user.groups.all()
Basicly you can also do with this to get first group:
{% if user.groups.all.0 == 'Patient' %}
...
{% endif %}
I found the solution thanks to here. I used the forloop.counter variable.
{% if user.is_authenticated %}
{% for group in user.groups.all %}
{% if group.name != 'Patient' %}
{% if forloop.counter < 2 %}
<li {% if request.get_full_path == modules_url %} class="active" {% else%} class="inactive"{% endif %}>
<b style="color:#ff9904;">Modules</b>
</li>
{% endif %}
{% endif %}
{% endfor %}
{% endif %}