In Grav which uses twig as a templating engine, I have:
<ul>
{% for page in taxonomy.findTaxonomy({'tag': 'shell'}) %}
<li>{{ page.title }}</li>
{% endfor %}
</ul>
to get all pages that have tag set to shell -
However, page.title renders fine, but page.url gives
%7B%7B%20page.url%20%7D%7D?
If I put page.url in place where page.title is, so between <a></a> tags,
everything works fine? Is this some kind of bug?
EDIT
Exactly the same as described here: https://github.com/erusev/parsedown/issues/266
FOUND SOLUTION
Luckily Grav has an option to process twig first then markdown.
By setting twig_first: true into page meta, I was able to solve the problem.
So the culprit is markdown processor.
just print the object using {{var_dump(page)}}
then you can see the getter method or array value of the object.
Here is my solution for your problem {{ page.route }}
It is working for me!
Hope this helps someone.
Related
To my understanding, by using twig's extends method, it should be possible to add code to the footer from within a template that is included anywhere else.
Like if we render the main page and have a <form> there in a template edit_form.html.twig and we know we need special javascript here (only for that form) so we decide to add this javascript tags in the footer at the end of the page like this:
edit_form.html.twig
{% block edit_form %}
<form id="editForm">
<!-- form html here -->
</form>
{% endblock edit_form %}
{{ include('edit_form_js.html.twig') }}
We want this javascript to be at the end of the page:
edit_form_js.html.twig
{% extends "footer.html.twig" %}
{% block js %}
{{ parent() }}
<script>
// special js code only needed for the <form>
</script>
{% endblock js %}
footer.html.twig
{% block js %}
<script src="jquery.js"></script>
{% endblock js %}
But doing this does not add the custom form javascript at the end after the jquery inclusion but results in the block js being twice on the page (after the form and in the footer)
Is my understanding of twigs extends wrong?
Q: Is there any way to add code from anwywhere to the footer?
Included templates don't know anything from the template it's being called from. There for an included template cannot alter a block from that said template. You might want to have a look at the deferred extension
I am using django-el-pagination package and trying to implement digg-style pagination on my home template. I am displaying it with..
{% get_pages %}
{{ pages.get_rendered }}
and it is showing like this <1234567> which is fine but
I want to add some css or class to change the way it look.
If you have any other way to achieve this. Please suggest..
please tell how can I customize it.
You can change it to make it looks something like this or like whatever you want:
Here is an example:
{% get_pages %}
<div class="pagination">
{% for page in pages %}
<li class="page-item">{{ page.number }}</li>
{% endfor %}
</div>
You can check the documentation here: https://django-el-pagination.readthedocs.io/en/latest/templatetags_reference.html#get-pages to check all the available options for get_pages
I need to generate a menu that lists all pages (like the sitemap sample) but if a page has childs it should become only a toggle for its submenu, not linking to any page. Only the innermost childs will be pages.
E.G.:
about (link)
portfolio (no link - only toggle)
work01 (link)
work02 (link)
contacts (link)
As I said, the summentioned sample creates and links a page also for "portfolio".
My site is here andrearicci.it (subpage) and the menu item "projects" now toggles the submenu, but I can't get rid of its link - so I had to format an unwanted 'projects summary' page.
On that page the menu is
<nav>
<ul class="projlist">
{% for project in site.get('/projects').children %}
<li{% if this == project %} class="active"{% endif
%}>{{ project.name }}</li>
{% endfor %}
</ul>
</nav>
I wish an automatic solution, that could work also adding other page groups (e.g. paintings/web design/whatever) without the need of changing it every time.
Is it maybe more a question about Jinja other than Lektor?
Thank you for any help.
A.R.
Idea: just test if the page contains children, if so - do not link the page.
The test should be as easy as
{% if project.children %}
{# no link #}
{% else %}
{# link #}
{% endif %}
so heres the use case:
render a login form block in dynamic page structure, but only if user is not authenticated
block must not be defined if not authenticated (to preserve dynamic page structure)
twig 2.2
symfony 3.2
In a base template, I'm only rendering a block if its defined (not 'not emtpy')
base.html.twig
{% if block('left_sidebar') is defined %}
<div class="col-md-2">
{{- block('left_sidebar') -}}
</div>
<div class="col-md-10">
{% else %}
<div class="col-md-12">
{% endif %}
index.html.twig
For the above to work the block cant be defined at all (which is entirely designed). The following renders the block anyway, and I cant' figure out why.
{% if not is_granted('IS_FULLY_AUTHENTICATED') %}
{% block left_sidebar %}
{% include ':blocks:block__login.html.twig' %}
{% endblock %}
{% endif %}
I'm wondering if this is'nt working because of the same reason that the base template code does work. That is that the blocks are compiled before runtime, and the conditional statements are executed at runtime.
Can anyone please confirm that this I'm right? Or correct me if I'm wrong?
edit
I've tried forcing the result of the condition to both true and false, and the block is rendered in either case.
so, to wrap this up, as it seems to be a problem occurring in a few places, my suspicions are correct in that its a compile/runtime issue.
Blocks are compiled and because the if statement is at runtime one cant control the other.
heres the github issue thread if anyone wants more info.
The block() function appears to return a falsey value if nothing or only white space was output in it, so you can wrap the block in a truthiness test and in the child template make sure it is empty if you don't want it to show. Something like this worked for me:
base.html.twig:
{% if block('left_sidebar') %}
<div class="col-md-2">
{% block left_sidebar %}{% endblock %}
</div>
<div class="col-md-10">
{% else %}
<div class="col-md-12">
{% endif %}
index.html.twig
{% block left_sidebar %}
{% if not is_granted('IS_FULLY_AUTHENTICATED') %}
{% include ':blocks:block__login.html.twig' %}
{% endif %}
{% endblock %}
Twig compiles your templates into php classes, which you can see in the symfony cache directory, and blocks are methods in those classes. This means that blocks are always defined at compile time and conditionals like yours only determine if they are "executed".
For your use case, I would reccommend to to put the call to is_granted in the base template. Then you would not need to include any if element in index.html.twig because defining the sidebar block will have no effect if it is never used.
There is no real performance hit to defining unused blocks since the parsing of twig blocks only happens at compile time. Defining blocks whether or not are used is done, for instance, in symfony's own form component.
I'm using Twig with Silex and are having some trouble with extend within an if statement. Basically the page is being extended even tho, the request is not done by AJAX.
{% if app.request.isXmlHttpRequest == false %}
{% extends 'layout.html.twig' %}
{% endif %}
However this works. The button is only being showed when the request is AJAX based.
{% if app.request.isXmlHttpRequest %}
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
{% endif %}
Also possibly worth mentioning my code is enclosed in an {% block content %} tag.
Does anyone have experience with this issue? (Being able to extend only if isXmlHttpRequest is false)
Thanks in advance
Try this one:
{% extends app.request.isxmlhttprequest ? "" : "layout.html.twig" %}
Behind the courtains extends is a token parsed in a way that no conditions can be placed around it, the outcome will be what you got: your template is always extended.
I'm not sure how it'll work with the empty string, you may need to create a "layout-ajax.html.twig" file with no content but the block you want to override.