Setting URL variable for all posts - jekyll

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.

Related

Can a liquid for loop contain a page variable in 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] %}

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.

Conctenating two collections in a liquid assignment

Based on this tutorial, I built a multi-lingual Jekyll site. In every page, the following code links to the versions of the same page in different languages:
{% assign pages=site.pages | where:"id", page.id | sort: 'path' %}
{% for p in pages %}
<img src="{{ site.baseurl }}/images/{{ p.lang }}.png" alt="This page in {{ p.lang }}"/>
{% endfor %}
This works well, but I want to do the same in pages that belong to other collections besides "site.pages". For example, I have a collection called "site.TOPICS". I would like to replace the first line with something like:
{% assign pages=site.pages + site.TOPICS | where:"id", page.id | sort: 'path' %}
or:
{% assign pages=site.EVERYTHING | where:"id", page.id | sort: 'path' %}
But this does not work.
Is there a way to concatenate two collections? Or alternatively, to access all objects in the site regardless of type?
Right now (Jekyll 3.1.x I don't think you can do it.
I found: https://github.com/Shopify/liquid/issues/427
Which seems to show it is coming - this is an issue that looks like it is solved in Liquid, but a higher version of liquid that Jekyll uses.
I also found this: https://github.com/mpc-hc/mpc-hc.org/commit/624a4bf63710ce00d98c80f8b3655a71c0468747#diff-23a9de36055c1aa13a62d73b9c318ebd
where parker says this is a potential 4.x feature.
It looks like if you have more than one collection you could use site.documents to do this, I did a little test and while it sounds like site.documents is all docs in the site, it looks like it is really all docs in collections.
There is a push filter that maybe you could use to push one array into another, but I don't think it is really made to add 2 arrays together.
In the meantime I think just duplicating your code and having one for pages and one for collections would work. If I understand correctly your id would only be found if it matched so one would find something the other wouldn't.

Can you use Jekyll layout variables in pages?

In a Jekyll layout, default.html, you initialize a variable
{% assign relative_path = "../../" %}
Inside a page using default layout, this variable is empty though.
How can you use inside pages variables set in layout?
This is the opposite of
Can you use Jekyll page variables in a layout?
After some research in Jekyll code, it seems that you cannot access layout variables from a page or post. The only information about layout a page can see is the layout's name {{ page.layout }}.
Then you can use this to store some layout related variables in _config.yml and get them from any post/page using the {{ page.layout }} variable.
_config.yml
layoutVars:
default:
relative_path: "../../"
post:
relative_path: "an other path"
page:
relative_path: "hello world"
use in a page or post
{% assign pagePath = site.layoutVars[page.layout].relative_path %}
You have two possibilities.
Store your variable in the layouts yaml-header, e.g.:
---
variable : value
---
Have a look at jekylls front matter defaults. You can declare variables depending on the type of posts/documents and the folder the posts are stored in.
I'm not if this is what you are looking for, but i hope it helps...

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