Wildcard match in Liquid tag? - jekyll

I'm trying to filter out part of a post from my site's RSS feed. I want the rest of the post, but just want to remove certain parts.
Is there a way to filter this out somehow? I've looked at these Liquid tags/filters, and the closest I've found were remove and replace, but they seem to match literally.
I'm trying to basically do this in my feed.xml:
{{ post.content | replace:'<span class="no-rss">*</span>','' | cdata_escape }}
Is there some way to use a wildcard in these filters, or achieve this otherwise that I'm not aware of? My Google-fu has run dry on this one.

Two solutions :
using excerpt with posts
Part of the post you want to inject in your feed is at the beginning of your post.
Use excerpt
isolating part of content with liquid filters
If you are in a page (they don't have excerpt), or in a post and want to select specific part of your content, you can use liquid filters.
string.split and array filters.
In any post or page
---
your front matter variables here
---
Head of my document
<!-- start -->
Text to extract
<!-- end -->
Bottom of my document
in your rss
{% for p in site.posts %}
{% if p.content contains "<!--start-->" %}
{% assign extract = p.content | split: "<!--start-->" | last | split: "<!--end-->" | first %}
{{ extract }}
{% else %}
{{ p.content }}
{% endif %}
{% endfor %}

Instead of removing the whole span you could get rid of the style class being applied to it:
{{ post.content | remove: ' class="no-rss"' | cdata_escape }}

Related

Can I get posts by using an array of tags using Jekyll?

I'm working on a liquid script for my Jekyll website to retrieve related posts. I'd like to use the array of tags used for the current post (post.tags) to do a query that matches other posts on the site that also have one (or more) of those tags. Such as:
assign relatedPosts = site.posts | where 'tags', page.tags
However, in the documentation it only mentions passing in a string, not an array of strings? I would ideally like to accomplish this using the where operator (or something similar), instead of iterating through every post on the site.
You are correct that you can't supply an array for the where operator, as per the documentation, you can only pass a string there.
By the nature of your requirement, it looks like iterating through every post on the website is not something you can avoid, since basically you want to check all your posts for a couple of different tags.
One possible solution would be to iterate through your post tags first, then check that tag against all site post tags, something like this:
{% assign new_array = "" | split: "" %}
{% for tag in page.tags %}
{% assign tag_found = site.posts | where "tags": tag %}
{% assign new_array = new_array | concat: tag_found %}
{% endfor %}
OUTPUT: {{ new_array }}

Get the read time for a specific post in Jekyll Pages from home page/ any other page

I am new to liquid and Jekyll, using the below code to calculate the post read time on the post page. But how should I calculate the reading time on the home page or any other page to display it below a post title?
When I use the same code on the homepage as well, I get different read times on the home page and inside that particular post.
I think I am not able to get the context of that post to count the number of words on some other page. Please suggest.
<span class="reading-time" title="Estimated read time">
{% assign words = content | number_of_words %}
{% if words < 360 %}
1 min
{% else %}
{{ words | divided_by:180 }} mins
{% endif %}
</span>
This is probably happening because, on the home page, you also have some HTML formatting your page.
Strictly speaking, you should indeed strip the HTML out of your content before counting the words, to have an accurate reading time.
So, using the strip_html filter could be a solution:
{% assign words = content | strip_html | number_of_words %}

Trying to get a collection from a Front Matter value

Hi I'm new to Jekyll and have a basic blog set up. Now my idea is to loop through a collection per blog post to get some fancy HTML going on. Because as far as I'm aware you can't simply add HTML to the markdown.
// config.yml
collections:
- hollowknight
So I've set up a collection named hollowknight and I got a blog post about Hollow Knight.
In the Front Matter of the blog post I have collectionid: 'hollowknight'. And in the Layout I use for blog posts I tried the following:
// post.html
{% capture collection %}site.{{ page.collectionid }}{% endcapture %}
{% for section in collection %}
{{ section.title }}
{% endfor %}
So the idea was to set the collection variable to site.hollowknight as configured in the config and the Front Matter. I set up a single article inside the collection, but it isn't showing up.
Is there any way to realise this?
Edit: https://talk.jekyllrb.com/t/list-collection-with-name-from-front-matter/3619/6
Or is there a way to use paragraphs in the Front Matter, because then I could just use arrays and objects in the Front Matter of the posts to do my magic?
Edit: https://github.com/jekyll/jekyll/issues/246#issuecomment-1639375
Or am I just stretching to far from what Jekyll is supposed to be?
Edit
So I found out I was getting the collection the wrong way, https://talk.jekyllrb.com/t/list-collection-with-name-from-front-matter/3619/6.
{% for section in site.[page.collectionid] %}
{{ section.content | textilize }}
{% endfor %}
The only weird part is, everywhere I see | textilize being used but can't get it to work.
This is the final solutions:
{% for section in site.[page.collectionid] %}
{{ section.content | markdownify }}
{% endfor %}
It's markdownify instead of textilize.
Also I ended up using a Front Matter array with objects to loop through instead of a collection to keep it more organized.

Strip url to 1 word in Jekyll

I am building a Jekyll blog, and I have come across an issue with permalinks.
My permalinks to blog posts are set like this in
_config.yml:
permalink: /:page/:categories/:title
It outputs like this when navigating to a blog post:
http://localhost:4000/blog/travel/netherlands-trip-prequesites/
I have some static pages in the site: Blog, Travel
The variable page.url outputs this url: /blog/travel/netherlands-trip-prequesites
The code my navigation bar uses to highlight the current page (giving it an "active" class):
{% assign url = page.url|remove:'index.html' %}
{% for nav in site.navigation %}
{% if nav.href == url %}
<li class="active">{{nav.name}}</li>
{% else %}
<li>{{nav.name}}</li>
{% endif %}
{%endfor%}
It works great when navigating to static pages, however when I click a blog post it doesn't highlight the correct static page. (ex.: If i navigate to a blog post with the url /blog/smth/title it should automatically highlight "Blog" in my navigation. When I navigate to /travel/smth/title it should highlight "Travel")
What I'd like to do is to strip down the output of page.url to its first part. For example I'd like to stip the following output
/blog/travel/netherlands-trip-prequesites
down to
/blog/
Why? So I can use it to check which static page it belongs to and highlight it accordigly.
The easiest way is to use split:
{{ page.url | split:'/' | first }}
That will give you the URL content up to the first / character.
I managed to solve it with three filters:
{{ page.url | replace:'/',' ' | truncatewords: 1 | remove:'...' }}
page.url outputs: /page/cat/title, then replace removes the forward slashes producing: page cat title. truncatewords truncates the string down to one word, producing: page... (for some reason three dots gets inserted after the remaining word). After all this I only needed to remove those dots with remove and voilá, my final string: page.
Hope this helps someone.
The answer provided by PeterInvincible was almost perfect, however, there's no need to get piping to remove involved...
The following also will produce desired output
{{ page.url | replace:'/',' ' | truncatewords: 1,"" }}
And to save it to a variable use capture redirection
{{ capture url_base }}{{ page.url | replace:'/',' ' | truncatewords: 1,"" }}{{ endcapture }}
Which can be called via {{url_base}} or mixed with other processing calls.
Also for file paths instead of URLs page.dir works well if you're not using permalink settings for layout, check the gh-pages branch (specifically _includes/nav_gen.html for functional, though rough'round the edges, example) for hosted examples of similar code examples related to liquid syntax and other magic.
Edits & Updates
The above linked script is now live/mostly-working/modular and auto-serving parsed sub-directories viewed currently at the related https://s0ands0.github.io/Perinoid_Pipes/ project site providing examples of recursive parsing of directories. Including and modding for nearly any theme should be possible just check the commented section at the top for currently recognized commands that maybe passed at inclusion call... on that note of inclusion and modularization here's how to turn the above example code for directory parsing into a function
{% comment %}
# Save this to _include/dir_path_by_numbers.html
# import with the following assigning arguments if needed
# {% include dir_path_by_numbers.html directory_argument_path="blog" directory_argument_depth=1 %}
{% endcomment %}
{% assign default_arg_directory_path = page.url %}
{% assign default_arg_directory_depth = 1 %}
{% if directory_argument_path %}
{% assign directory_to_inspect = directory_argument_path %}
{% else %}
{% assign directory_to_inspect = default_arg_directory_path %}
{% endif %}
{% if directory_argument_depth %}
{% assign directory_to_inspect_depth = directory_argument_path %}
{% else %}
{% assign directory_to_inspect_depth = default_arg_directory_depth %}
{% endif %}
{% comment %}
# Defaults read and assigned now to output results
{% endcomment %}
{{ directory_to_inspect_depth | replace:'/',' ' | truncatewords: directory_to_inspect_depth,"" | remove_first: '/' | replace:' ','/' }}
The above should output directory path lengths of whatever size desired and maybe included as shown previously or if feeling adventurous try what's shown below; though for looping and recursive features look to the linked script for how I've worked around stack size restrictions.
{% capture dir_sub_path %}{{include dir_path_by_numbers.html directory_argument_path="blog" directory_argument_depth=1}}{% endcapture %}
Note above is just speculation, untested, and maybe more buggy than scripts tested and hosted publicly... in other words inspiration.
Simplest way would be using
if page.url contains
example:
<li class="{% if page.url contains '/docs/' %}current{% endif %}">
Docs

How to display post summary on index page using Jekyll?

I am using Jekyll to create a blog by following this excellent tutorial. I would like to add a post summary on the index page. I tried using:
post.content | truncatewords:50 | strip_html
it works but it displays the entire post until the 50 word count is reached. This includes the heading too. I would like to just summarize the actual content of the post. How can I structure my posts to do this?
Update 16 Nov, 2015
Now Jekyll support excerpt separator, In template you can do this:
{% if post.excerpt %}
{{ post.excerpt }}
{% endif %}
and In global config _config.yml you can set:
excerpt_separator: <!--more-->
and the same use with <!--more--> html comment tag.
Old answer
You can try this:
{% if post.content contains '<!--more-->' %}
{{ post.content | split:'<!--more-->' | first }}
{% else %}
{{ post.content }}
{% endif %}
and add <!--more--> tag in the article after summary, just like Wordpress.
Use YAML front matter and define a separate title per post, like this:
---
title: Efficient smuflet based kwoxel trees
---
Post content goes here.
Then you can use or not use post.title as you please.
Or, if you want to write a separate summary (not just the first n characters) for each post, just add a field for that summary in the front matter as well.
From the Jekyll documentation:
Each post automatically takes the first block of text, from the beginning of the content to the first occurrence of excerpt_separator, and sets it as the post.excerpt.
...
Because Jekyll grabs the first paragraph you will not need to wrap the excerpt in p tags, which is already done for you.
See http://jekyllrb.com/docs/posts/#post-excerpts for more info and an example.
Use {{ post.excerpt }} in your index.md file to get an excerpt of this post.