Can a liquid for loop contain a page variable in Jekyll? - jekyll

Let's say I have a bunch of _data files that I use to create a list for specific pages. All of the pages that have these lists have a custom front matter variable of pageName. The value of pageName just so happens to match the _data file with the list.
Rather than pasting the html blocks of code into each page, I'd like to use an include to pull in a generic block of html. To do that, the include has to be dynamic or contain liquid markup to become dynamic.
That might be more context than you need, but my question boils down to this, is something like this possible:
{% for item in site.data.{{page.pageName}} %}
{{ item.label }}
{% endfor %}
Unless I'm missing something, this doesn't work so I'm wanting to know if there's a way of achieving similar functionality.
I found this similar question, but it doesn't seem to answer whether it can be used to access a page variable to build a file name.

You can use the bracket notation like this :
{% for item in site.data[page.pageName] %}

Related

Setting URL variable for all posts

I'm trying to reference an image from a GitHub pages post. I have been referencing images from the layout, and to do so I have used the following code in my _layouts/default.html:
{% assign custom_url = site.url | append: site.baseurl %}
{% assign full_base_url = custom_url | default: site.github.url %}
… href="{{ "/images/logo.png" | prepend: full_base_url }}" …
(I'm not sure how exactly I ame up with the first two lines, but they seem to work well in both the live pages and my local preview so I'm inclined to keep their semantics.)
Trying to duplicate only the last row in the body of a post failed, leading to nothing being prepended. I assume that the variable is not present when the post gets rendered, only when that rendering gets plugged into the layout. Using all three rows in every post with images feels a bit repetitive.
I have read Jekyll Front Matter Defaults which describes how to perform settings for all posts, but that does seem to only allow setting static values, not computed values like I do in my assignments.
I have also read How to define global variables in Liquid? which seems to be addressing the same Liquid problem. But the question is very bare-bones, and tagged for Shopify not Jekyll so some of the answers don't feel applicable to me. The gist I get from the answers there is that maybe I might be able to include some “snippets” somehow somewhere, but I have no clue how to do that, let alone do that in a way that would not require adding lines to every post. The fact that the term “snippet” tends to refer to code snippets does not make searching for guides any easier.
In one of my Jekyll project, I had the same kind of requirement and as you, I did not find a really clear way to do it.
I battled a long time trying to fit this into _config.yaml, but because of the processing order, realised it would never work.
What I finally ended up with is maybe not the cleanest of the solution, and I would really like someone coming with a better solution than this one, but here it is:
In the _includes folder I created a variables.html file containing all those global variables I knew I could use on all pages.
In your case the file _includes/variables.html would be
{% assign custom_url = site.url | append: site.baseurl %}
{% assign full_base_url = custom_url | default: site.github.url %}
Then in all the layouts I would need those variables, I would just include the variables.html files right after the DOCTYPE, here is a simplified example of _layouts/default.html:
<!DOCTYPE html>
{% include variables.html %}
<html>
<head></head>
<body>
{{ content }}
Some image
</body>
</html>
This way your variables custom_url and full_base_url are globally accessible in everywhere you are using the default layout.

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 %}

Is it possible to have a different template for pagination?

I'm wanting to have my list of entries be formatted differently on the first page. But I can't figure out if there's any way to check which page is being shown.
I'm able to get my posts and have them paginated, but I can't find information on how to do something like this (or if it's even possible or not)
{% if record.number == 1 %}
first page template
{% else %}
other pages
{% endif %}
Or possibly set another twig file as for the other layouts.
You can use app.request to get the GET parameter which contains the page number. Then you can check if you are on the first page or not.

How do I inspect Pelican variables

I'm modifying a Pelican template and I have the code below which adds url every time a page is found. I can see that the p object has the attributes url and title.
However I only knew this because I copied the code from another template shown below. Is there any way to inspect objects in jinja2 or Pelican to understand what information is contained within them?
{% for p in pages %}
<h1 class = "sidebar-title">
<a href="{{ SITEURL }}/{{ p.url }}">
{{ p.title }}
</a>
</h1>
https://github.com/getpelican/pelican-themes/blob/master/backdrop/templates/base.html
<li{% if p == page %} class="active"{% endif %}>{{ p.title }}</li>
I am not aware of an official resource explaining all variables, objects, attributes and properties in detail.
But for a start, I think the following start points suffice:
Common variables available for the standard templates
pelican.contents.py:
This is the module which contains (most of) the data structures pelican uses and which are made available in the templates. Have a look for properties (#property, these are functions which act like they are attributes) and attributes. At lines 367ff there are some very simple subclass definitions which could be of use.
pelican.writers.py: This module brings together the templating engine jinja2, the templates and the data to be inserted in the templates. Of special interest for you could be lines 138ff, as this seems like a good point to simply insert some small debug prints to see the real data which is present in the data structures.

Is there a way to evaluate string with liquid tags

I need to provide page content reference list (it should contain references on sections on page).
The only way which I can see is to use page.content and parse it, but I stumbled on problem with data evaluation. For example I can pull out this string from page.content: {{site.data.sdk.language}} SDK but there is no way to make jekyll process it, it outputs as is.
Also I want to make it possible to create cross-pages links (on specific section on page, but that link generated by another inclusion and doesn't persist in page.content in HTML form).
Is there any way to make it evaluate values from page.content?
P.S. I'm including piece of code which should build page content and return HTML with list (so there is no recursions).
P.P.S. I can't use submodules, because I need to run this pages on github pages.
Thanks.
Shouldn't {{ site.data.sdk.language | strip_html }} do it? I don't know, most probably I didn't understand the problem. Can you elaborate more? Maybe provide a link to a post you're referring to?
Thinking about the similar
{% assign title = site.data.sdk.language %}
which is a stock Liquid tag and does the job well, so instead of
{% section title={{site.data.sdk.language}} %}
write your code as
{% section title = site.data.sdk.language %}
The key here is that once you enter {%, you're in Liquid. Don't expect Liquid to go "Inception" all over itself. {{ is just a shorthand for "print this to output", but an parameter passing is not output, it's just reading a variable.
You should be able to also go wild and do:
{% section title = site.data.sdk.language | capitalize %}
For more re-read the docs: https://github.com/Shopify/liquid/wiki/Liquid-for-Designers