Not able to load multiple blocks in base template in Django - python-3.x

I am having a problem in my templates. I am trying to add two blocks in the base template,
it works when I include them but when I try to extend the base template it won't work and won't even throw an error.

This shud be the problem ... I will also leave a link to the original answer
MOVE THE INCLUDE BLOCKS INTO THE NAMED BLOCKS
Another situation where an include statement will fail without raising an error is if you are working in a template which extends another, and your include is outside of a named block:
{% extends "my_base.html" %}
{% block content %}
{{ block.super }}
{% include "partials/file1.html" %}
{% endblock %}
{% include "partials/file2.html" %}
In this case file2.html will not be included because it is not in a block, and you will get no warning messages, and will try all sorts of things before you realise what you've done.
Include tags not working

My Django ver: 2.2
For all trying to figure out how to declare multiple blocks, even though base has just one {% block content %},
You can declare block within block
This is my base.html:
{% block content %}
{% endblock %}
This is my home.html:
{% block content %}
{% extends 'base.html' %}
Some common content I want
{% block my_variable_data %}
{% endblock %}
{% endblock %}
My some other page:
{% extends 'home.html' %}
{% block data_content %}
{% endblock %}

Related

How do I override a block in a nested template in Twig 2.x [duplicate]

I am trying to override a {% block %} in a file (index.html.twig) that extends the file where the block is used (base.html.twig). But the extending file is including another twig file (feature.twig) where the block that overrides the content in index.html.twig is placed.
Is that possible in any way? Maybe with something else than the include statement?
{# index.html.twig #}
{% extends 'base.html.twig' %}
{{ include('feature.html.twig') }}
{# base.html.twig #}
{% block extraJs %}{% endblock %}
{# feature.html.twig #}
{% block extraJs %}<script>$('...');</script>{% endblock %}
The include-function (or tag) only ever embeds the rendered result. It is not possible to manipulate blocks in the including file.
But in your case this is not necessary. Because index.html.twig extends base.html.twig, you can overwrite the block extraJs like so:
{# index.html.twig #}
{% extends 'base.html.twig' %}
{% block extraJs %}
{{ include('feature.html.twig') }}
{% endblock }
If needed you can extend the original block by using the parent-function. E.g.:
{# index.html.twig #}
{% extends 'base.html.twig' %}
{% block extraJs %}
{{ parent() }} {# `extraJs`-block content from `base.html.twig` #}
{{ include('feature.html.twig') }}
{% endblock }
No it's not possible. include just render template and include the output. You can't override block using it. Here is a issue related to this problem https://github.com/twigphp/Twig/issues/1360
Just as an info,I think you cannot put comments {# index.html.twig #} before the {% extends 'base.html.twig' %} and comments as I understood must be put always in blocks,hope this helps

Multiple blocks in Grav cms twig template

I am making a Grav template from a static html. This is a one-pager, so I am using modular templates and content. The problem is that I have a gallery, and my clicking on an image, a modal pops up. The code for the modals are places outside the container I am using for the image gallery.
Is there a way to have a twig modular template creating output code two different places on the base template? I have tried using multiple blocks in the modular template, but in the final output all code are places inside the image gallery container? My templates have multiple level nesting just to make it a little bit easier:
main
Listing of categories
Listing of images for each category
base.html.twig (simplified):
{% block body %}
{% block modal %}{% endblock %}
{% block content %}{% endblock %}
{% endblock %}
modular.html.twig:
{% extends 'partials/base.html.twig' %}
{% block content %}
{{ page.content }}
{% for module in page.collection() %}
<div id="{{ _self.pageLinkName(module.menu) }}">
{{ module.content }}
</div>
{% endfor %}
{% endblock %}
category-list.html.twig (simplified):
{% block content %}
{% for module in page.collection() %}
{{ module.content }}
{% endfor %}
{% endblock %}
content template (simplified):
{% block modal %}
{{ page.titel }}
{% endblock %}
{% block content %}
{{ page.content }}
{% endblock %}
My problem: rendering the block modal from the content template in the block Modal in the base template. Currently the block modal is rendered in block content.
Any ideas?
Thanks

Use grandparent block

I have the following twig templates:
{# layout.twig #}
{% block content %}
THIS IS LAYOUT
{% endblock %}
{# secondary_layout.twig #}
{% extends layout.twig %}
{% block content %}
THIS IS SECONDARY_LAYOUT
{% endblock %}
{# mypage.twig #}
{% extends secondary_layout.twig %}
{% block content %}
{# I WOULD LIKE TO USE layout content block here #}
{% endblock %}
I can call parent() inside the content block in mypage.twig, but how to use a grandparent instead?
There are situations, in which you can achieve this. Unfortunately not in your case. However, it works if only "horizontal re-use" is used (use keyword), but not with inheritance (extends). This for instance applies to form themes.
In my case I defined a form theme which inherits from the bootstrap 3 form theme. The bootstrap theme itself inherits from "form_div_layout". I wanted to override the choice widget and include the grand parent's (form_div_layout) block content, because the bootstrap version of the block didn't fit for me in this single case. So, basically a very similar problem.
This can be solved by inheriting from both, the parent (bootstrap_3_layout) and grand parent layout (form_div_layout), while declaring an alias for the grand parent block to be overridden:
{# my_form_theme.html.twig #}
{% use 'form_div_layout.html.twig' with choice_widget_collapsed as base_choice_widget_collapsed %}
{% use 'bootstrap_3_layout.html.twig' %}
{% block choice_widget_collapsed -%}
{# There is no "grandparent()" function, so instead we can do this: #}
{{- block('base_choice_widget_collapsed') -}}
{%- endblock %}
I'm writing this answer, although it doesn't answer the actual question. But other people will probably also find this question when googling for such a "grandparent"-feature and maybe they'll give up unnecessarily, when they read that it's impossible here.
Ok by writing the problem I got one solution, just modify secondary_layout
{# secondary_layout.twig #}
{% extends layout.twig %}
{% block content %}
{% if use_layout_block %}
{{ parent() }}
{% else %}
THIS IS SECONDARY_LAYOUT
{% endif %}
{% endblock %}
{# mypage.twig #}
{% extends secondary_layout.twig %}
{% block content %}
{% set use_layout_block = true %}
{% endblock %}
It may help someone.
If someone got another solution, feel free to answer.
You can include the block of any template with the function block().
block - Documentation - Twig
block(<block_name>, [template_name])
In your case, the solution could be as follows:
{# mypage.twig #}
{% extends secondary_layout.twig %}
{% block content %}
{{ block('content', 'layout.twig') }}
{% endblock %}

Using parent() function and overriding parent's children block

How can I use {{ parent() }} and override one of its children blocks, I found some solution but it looks wrong, here is an example that may be explain the issue:
index.html.twig:
{% block wrapper %}
<h1>title</h1>
{% block one %}<p>Content of block one</p>{% endblock one %}
{% block two %}<p>Content of block one</p>{% endblock two %}
{% endblock wrapper %}
new_index.html.twig:
{% extends 'index.html.twig' %}
{% block wrapper %}
{{ parent() }}
{% block two %}<p>NEW content of block two</p>{% endblock two %}
{% endblock wrapper %}
But I see the content of block two twice (and it looks logical). How can I update the code to fix it?
Wow, solution is simple, just write block two outside the wrapper block, there is no hierarchy for blocks :)
new_index.html.twig:
{% extends 'index.html.twig' %}
{% block wrapper %}
{{ parent() }}
{% endblock wrapper %}
{% block two %}<p>NEW content of block two</p>{% endblock two %}

How to include a template that set content into blocks using twig

It's difficult to explain but I have a layout.html.twig template like this:
{% block css '' %}
{% block content '' %}
{% block js %}
<script src="jQuery.js"></script>
{% endblock js %}
I have another template index.html.twig that extends the layout one like this
{% extends 'AcmeBundle::layout.html.twig' %}
{% block content %}
{% include 'AcmeBundle:Module:module_1.html.twig' %}
{% include 'AcmeBundle:Module:module_2.html.twig' %}
{% include 'AcmeBundle:Module:module_3.html.twig' %}
{% endblock content %}
{% block js %}
{{ parent() }}
<script ...></script>
{% endblock js %}
Each included module has some javascript inside but they need to have jQuery loaded to work.
But jQuery is set in the layout.html.twig so it's not working.
How can I include my modules being sure that the script is executed after jQuery is loaded?
Is it possible to access the js block somehow? I had a look to embed but I'm not sure it's what I need.
Any ideas?
Cheers,
Maxime

Resources