Output the page URL in Jekyll? - jekyll

How can I get the current page's URL?
I have tried:
{{ site.url }}
But this fails to out put anything.

You need to define that in your _config.yml.
It's empty by default.
Once defined you might want something like {{site.url}}{{page.url}} to get the whole path.
To capture the whole path in a variable you can use
{% capture url_path %}{{site.url}}{{page.url}}{% endcapture %}

It can work out of the box in GitHub Pages at least using {{ page.url | absolute_url }}. See Page Variables doc in conjunction with the Absolute URL filter.

Related

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.

How to use Liquid include variable within a for loop?

I have this Liquid template which looks like this:
# /_includes/slideshow.html
{% for image in {{ include.images }} %}
...
{% endfor %}
which I'm trying to use with a YAML file (for my Jekyll site) like this:
# /index.md
{% include slideshow.html images='site.data.homepage_images' %}
The reason I see this failing is because my include variable {{ include.images }} resolves to a string within the for loop. Is there a different way to accomplish this? I'm still rather new to Liquid, YAML, Jekyll, and well, web development altogether, so any help in doing this is much appreciated!
(Note: the problem goes away if I replace {{ include.images }} with site.data.homepage_images.)
Additionally, the reason why I'm doing this (and why that crude fix isn't the solution I'm looking for) is for the ability to inject my image slideshow elsewhere around my site. It'd save a lot of code to abuse my include variable in this way.
Correct syntax in for loop is : {% for image in include.images %}

Page variable in for loop file name

For a bilingual website, i have yaml data files for 2 languages.
files example:
en_services.yml
fr_services.yml
Variable example in my page:
---
lang: en
---
I want to loop trough the file with the lang as the prefix, something like that:
{% for service in site.data.{{ page.lang }}_services %}
{% endfor %}
This doesn't work, is there a way I can do that?
By the way, I don't think I can add subfolders in the _data folder, right?
Thanks.
While that doesn't work, if you are able to put them both in the same file (grouped under the appropriate language code) there is a solution.
This gist was for another example based on post authors, but your should be able to use the same setup using language codes instead of author names.
You should use:
site.data[{{ page.lang }} + '_services']
data[i] has key/value entries for all the files in your _data directory, and passing the string in, like so (for /_data/book.yaml):
site.data['book']
...totally works and opens up the possibility of concatenating strings inside the brackets with whatever variable you want. :)
{% capture thefile %}{{ page.lang }}_services{% end capture %}
{% for service in site.data[thefile] %}
...
{% endfor %}
Should do the trick.

How to suppress blank line in Jekyll?

I use GitHub Pages for my blog, and am running into a problem with Jekyll. My post.html has a block like this:
{% for testpost in site.posts %}
{% four %}
{% lines of %}
{% processing %}
{% goes here %}
{% endfor %}
The part in the middle doesn't matter. The important part is the end of the line which is outside of the {% %} markup, and is therefore rendered into the html. Since this is in a loop, it's putting about 1000 blank lines into the middle of by HTML page. It doesn't affect the display, but it make a View/Source troublesome.
Any ideas on how to avoid those extra blank lines?
Since Liquid v4 (included in Jekyll from v3.5) there is a Whitespace control, which finally resolved case with blank line, white space, etc.
Link to documentation: https://shopify.github.io/liquid/basics/whitespace/
There's a nice workaround, that I found out in https://github.com/plusjade/jekyll-bootstrap/blob/master/_includes/JB/setup, and which is compatible with github pages.
Just enclose your loop in a capture statement, and assign nil to the resulting var.
{% capture cache %}
{% for p in site.posts %}
do stuff here
{% endfor %}
{% endcapture %}{% assign cache = nil %}
How about
{{ page.content | escape | strip_newlines }}
There is Jekyll plugin that strips the whitespace.
Jekyll plugins by Aucor: Plugins for eg. trimming unwanted
newlines/whitespace and sorting pages by weight attribute.
You can get it directly from its Github repository. So basically you wrap your code with {% strip %}{% endstrip %}. Even if this doesn't suit you needs, you can easily change the ruby script.
For example:
{% strip %}
{% for testpost in site.posts %}
{% four %}
{% lines of %}
{% processing %}
{% goes here %}
{% endfor %}
{% endstrip %}
However, please remember the nature of Jekyll plugins, you can't run them on the Github Pages server.
Quote from Jekyll Doccumentation:
GitHub Pages is powered by Jekyll, however all Pages sites are generated using the --safe option to disable custom plugins for security reasons. Unfortunately, this means your plugins won’t work if you’re deploying to GitHub Pages.
You can still use GitHub Pages to publish your site, but you'll need to convert the site locally and push the generated static files to your GitHub repository instead of the Jekyll source files.
Actually there is a new solution for this problem which works without any plugin.
A Jekyll layout that compresses HTML. At a glance:
removes unnecessary whitespace;
removes optional end tags;
removes optional start tags;
removes comments;
preserves whitespace within <pre>;
GitHub Pages compatible;
ignores development environments;
configurable affected elements;
profile mode;
automatically tested.
http://jch.penibelst.de/
If you - for some reason - do not want to use this here is a nice article, which describes some workarounds:
Compressing Liquid generated code - sylvain durand

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