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.
Related
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] %}
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.
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
I am working on a client's Django/Mezzanine website that has got some strange issue that I just can't seem to figure out. On the blog page (template of blog_post_list.html) I cannot get the meta title of the page to display, meaning
{% block meta_title %}
{{ blog_page.title }}
{% endblock %}
produces no output in the resulting html. The same holds for the meta description, but I am not worried about it as much. The strange thing is that it seems to work just fine for individual blog entries, as well as all the other pages on the website, except the blog list.
Any ideas?
Nothing is displayed in Django template if you render not existing variable or variable value is None.
First test if {{ blog_page }} renders anything. If it doesn't check if blog_page is in your template context.
You can debug template's context by writing simple custom templatetag, e.g.:
templates/your_template.html:
{% load pdb from debug %}
{% block meta_title %}
{% pdb %}
{{ blog_page.title }}
{% endblock %}
templatetags/debug.py:
from django import template
register = template.Library()
#register.simple_tag(name='pdb', takes_context=True)
def pdb(context, *args, **kwargs):
import ipdb;
ipdb.set_trace()
Apparently, there was a bit of confusion involved: I thought blog_page.title was a standard variable in mezzanine, apparently it is not, it was a custom model created by the previous developer. Since I have basically only the templates and a dump of the DB, it does not appear to be possible to restore the original model for blog_page class, so I simply solved it by supplying a meta title manually in the blog_post_list template.
Is there a way I can load a jinja2 template from within another template file? Something like
{{ render_template('path/to/file.html') }}
I have some snippets which I want to reuse, so it's important for me to have this functionality.
{% include "file" %} does this. See the jinja2 docs for more information.
Use either the extends tag or the include tag, depending on how you want to design your multi-file views.
You should make template files with {% macro -%}s and use {% import "file" as file %} to use the macros in other template files. See the docs.
Here is an example:
<!- in common_macros.html ->
{% macro common_idiom1(var1, var2, ... varN) -%}
<!- your idiom, where you can use var1 through varN ->
{%- endmacro %}
<!- in my_template.html ->
{% import "common_macros.html" as idioms %}
{{ idioms.common_idiom1(a, b, ... N) }}
Specifically this answer allows the OP to pass arguments to his macros, similar to the behavior he desired like how render_template behaves (simply including the file as previous answers have stated above does not achieve the same behavior as render_template).
This is generally better than making a fresh template for every idiom, or than using inheritance, which is a special case solution (what if you want to use the snippet multiple times in one template)?