Jekyll: Filter posts by subdirectory - github

I'm using jekyll to host a website on github.io
The homepage has a "Recent Posts" section which displays the latest 10 posts.
I'm using the following code in my index.html to generate the list:
<ul class="post-list">
{% for post in site.posts limit:10 %}
<li><article>{{ post.title }} <span class="entry-date"><time datetime="{{ post.date | date_to_xmlschema }}">{{ post.date | date: "%B %d, %Y" }}</time></span>{% if post.excerpt %} <span class="excerpt">{{ post.excerpt }}</span>{% endif %}</article></li>
{% endfor %}
</ul>
The _posts directory has 3 subdirectories. The above code generates a list from all three directories. I want to exclude the posts in one of those directories in my "Recent Posts" directory.
More generally, how can I select a subset of the subdirectories in the _posts directory?

I solved the problem by adding an if statement inside the for loop:
{% if post.path contains 'xxx' or post.path contains 'yyy'%}
<li><article>...</article></li>
{% endif %}
This works for simple cases but it could get ugly for more complicated cases.
The for loop seems to be iterating over a list but I can't figure out how to generate a list with the elements I want. I can't find a good reference for the scripting language used by Jekyll.

Related

Filtering by tag shows all pages instead of tagged pages

With reference to the Wagtial recipe on tags, I have set up tags in my courses app. However, tag filtering does not seem to be working. The tags themselves seem to be working: I can select tags in the admin and show them on the page. I have a course page tag model that seems to be working properly:
class CoursePageTag(TaggedItemBase):
content_object = ParentalKey('CoursePage',
on_delete=models.CASCADE,
related_name='course_tagged_items')
I have filtering setup in the CourseListingPage model (with template = "courses/course_listing_page.html") like this:
# Get all courses
course_pages = (
CoursePage.objects.live().public().order_by("-first_published_at")
)
# Filter by tag
tag = request.GET.get('tag')
if tag:
course_pages = course_pages.filter(tags__name=tag)
context['course_pages'] = course_pages
return context
And in the template I have this:
{% for tag in page.tags.all %}
{{ tag }}
{% endfor %}
When I click a tag on a course page with the above template code, I do arrive at the parent course listing page, and the URL shows what seems to be the correct filtering format:
courses/course-listing/?tag=test
But I do not see a filtered list of pages. Instead I see all course pages. I suspect there is something very simple that I am doing wrong here.
Answering my own question: {% for course in course_pages %} is required in the template at the location of the listing of the filtered pages -- in my case, below the filtering code. So, I now have the filtering code, then the actual listing of the pages, which begins with:
{% for course in course_pages %}
{% with course=course.specific %}
... HTML/template code for page details (e.g. course.title, course.sub_title) ...
{% endfor %}
{% endwith %}
I didn't initially that realize that the filtering code only does the filtering; it doesn't actually show the results of the filtering. For a beginner like me, when the docs say that the code will filter the listing to only those pages with a matching tag name before passing this to the template for rendering, it's possible to misread this to mean that the template will show the filtered results without further steps. But that's not the case. The extra contextual code is required -- at least it was for me.

How to order Wagtail tags

I tried to create tags for my Posts as described in doc (tutorial My first website). But i need to show these tags in specific order. Is there some simple way or i just need to create own class with Orderable?
I have assumed you have gotten to this point in the docs - Tagging Posts and want to present the view of your BlogPage with the tags in a special order (eg. alphabetical). Orderable is if you want to do more complex admin interaction with InlinePanels and ordering of related models, where you are asking the page editor to order related items themselves.
The tutorial has this code for your template blog_page.html:
{% if page.tags.all.count %}
<div class="tags">
<h3>Tags</h3>
{% for tag in page.tags.all %}
<button type="button">{{ tag }}</button>
{% endfor %}
</div>
{% endif %}
To work with a custom ordering of your tags, you will need to set up a way to send your ordered tags to the template context. The easiest way to do this is to have a method added to your BlogPage model, we will call this get_ordered_tags.
class BlogPage(Page):
date = models.DateField("Post date")
# other fields...
def get_ordered_tags(self):
"""Specific ordered list of tags."""
# ordered_tags = self.tags.order_by('?') # order randomly
ordered_tags = self.tags.order_by('name') # order by tag name
return ordered_tags
Further up the page you would have seen the docs on Overriding Context, we will do something similar to add ordered_tags to our Page's context.
We can then easily make one minor change to our template, just replace:
{% for tag in page.tags.all %}
With:
{% for tag in page.get_ordered_tags %}
So instead of getting the tags in their default order, we are getting them in our specific order.

How to exceed 255 characters limit of product tag in Shopify?

I am looking for a way to exceed the 255 characters limit on product tag in Shopify admin. Please suggest any way of doing so.
In general this does not sound like a good idea. If you are trying to embed extra information per item you might want to look at putting that in a snippet file and then formatting your tag like __extra File1 and then a snippet like the following in your product template:
{% for tag in product.tags %}
{%if tag contains '__extra' %}
{% assign snip = tag | remove_first : '__extra ' %}
{% include snip %}
{% endif %}
{% endfor %}
This would allow you to share large chunks of information per product while not blowing up your tags.
If you adopt this approach then you'll also want to go through your theme and make sure you filter out tags beginning with '__'. e.g.
{% for tag in collection.all_tags %}
{% assign tag_pref = tag | slice:0,2 %}
{% unless tag_pref == '__' %}
... do your tag related layout
{% endunless %}
{% endfor %}

How can I add proper tag support for jekyll blog hosted on GitHub?

Problem
Recently I added tag support for my personal blog, but I am not happy with a way that it was done.
Blog uses jekyll with github-pages, so my solution has many limitations that platform comes with.
In order to create tag javascript I created file tag/javascript/index.html with following content:
---
layout: tag
tag: javascript
---
And it in my tag layout file I have following code:
---
layout: default
---
<div class="tag-header">
posts related to <strong>{{ page.tag }}</strong>
</div>
{% for post in site.posts %}
{% if post.tags contains page.tag %}
<section class="post">
<header>
{{ post.title }}
</header>
<time>
{{ post.date | date_to_string }}
</time>
<summary>
{% if post.excerpt %}
{{ post.excerpt }}
read more
{% endif %}
</summary>
<div class="tags">
{% for tag in post.tags %}
<span>
#{{ tag }}
</span>
{% endfor %}
</div>
</section>
{% endif %}
{% endfor %}
Result is something like this posts related to javascript.
Question
How can I automate tag creation process, so it does not require manual tag file creation (tag/javascript/index.html from sample)?
Notice
I have read An easy way to support tags in a jekyll blog already, and the only working solution for github-pages was this one, which I don't like, because it puts all tags in one page.
Additionally note that I am using github-pages, so custom plugin is not an option.
You can find full sources here.
Current Jekyll (3.1.x) cannot generate tag page automatically. You need to use a custom plugin. But you don't want to.
Why ? It's not so difficult to change deployment process on github pages.
You can store you code in master and you generated page in gh-pages. This answer will give your more information on how to do it.

Perform for loop using eco with increment and metadata usage

I'm using docpad and on index page, in navigation pane I want to get a list of links grouped by category.
Category is defined in each markdown document in meta info on top. For example category:"tutorials"
So I have this:
<% for docu in #getFilesAtPath("document-repository").toJSON(): %>
<li><h2><%=cat=docu.category%></h2></li>
<%for docu in #getFilesAtPath("document-repository",category:cat}).toJSON():%>
<li><%=docu.title%></li>
<%end%>
<% end %>
But of course it is bad as it is looping as many times as many documents I have. I have only one category and I want it to loop only once when list of links is printed.
With jekyll it was done like this (part of _includes nav.html from https://github.com/devo-ps/carte) :
{% for category in site.categories %}
<li><h2>{{ category | first }}</h2>
<ul>
{% for posts in category %}
{% for post in posts %}
<li class='{{ post.type }}'><a href='#{{ post.url }}'>{{ post.title }}</a></li>
{% endfor %}
{% endfor %}
</ul>
</li>
{% endfor %}
He somehow knows how many categories are there. I don't know how to port it to docpad
I think the best question is when after asking in you find the answer :)
So I found a "workaround" at least I think it is a workaround and not a solution. For me that is perfect:
I've added "categories" to docpad.coffee file
templateData:
site:
categories: ['Tutorials','General']
Now I will always update this array with categories that should be used in meta info of each markdown doc
My loop looks like this now....and works!!!
<% for category in #site.categories : %>
<li><h2><%- category %></h2>
<ul>
<%for docu in #getFilesAtPath("document-repository",[{filename: -1}]).findAll({category:category}).toJSON():%>
<li><%=docu.title%></li>
<% end %>
</ul>
</li>
<% end %>