Currently my dilemma is I want the div in my base.html to be in my home_page.html but I need it around my header, main and footer.
This is my base.html
<div class="cover-container d-flex h-100 p-3 mx-auto flex-column">
{# header #}
{# /header #}
{% block content %}{% endblock %}
{# footer #}
{# footer #}
</div>
And this is my home_page that extends base.
{% extends "../base.html" %}
{% load static %}
{% load wagtailcore_tags wagtailimages_tags %}
{% block body_class %}Home{% endblock %}
{% block extra_css %}
{# Override this in templates to add extra stylesheets #}
{% endblock %}
{% block extra_js %}
{# Override this in templates to add extra javascript #}
{% endblock %}
{% block content %} {# html stuff sits in here#}
<main role="main" class="inner cover">
{% endblock %}
Is there a way to call on the header and footer specifically in the homepage.html?
I only want this div to be on the home page and not all the pages
I assume that what you mean here is that you only want this div to have this particular set of classes for the home page, and not for other pages (IOW, having a div with no classes or other classes is ok for the other pages).
If that's the case, the solution is simple: leave the div where it is, but wrap the div's classes into it's own block (with default - eventually empty - values), and override thsi block in the home page, ie:
base.html:
<div class="{% block page-css-class %}{% endblock %}">
{# header #}
{# /header #}
{% block content %}{% endblock %}
{# footer #}
{# footer #}
</div>
and home.html
{% extends "../base.html" %}
{% block page-css-class %}cover-container d-flex h-100 p-3 mx-auto flex-column{% endblock %}
{# your remaining code here #}
extends tag is used to inherit your parent template into the child template. It then looks for theblock tags in your parent template and replaces it with the values of the child template.
include tags loads a template and renders with the current context. You probably want to use {% include "footer.html" with my_context_variable=value %} to pass additional context.You can read more about it here.
Related
What do I want?
I want to extend cards/apps.html inside addstudents.html so that I don't need to write the chucks of codes multiple times. What can I do to extends multiple .html files inside DJANGO template?
Error I am getting
'extends' cannot appear more than once in the same template
WHAT TO DO?
NOTE: I don't want to use {% include %}, because the situation/condition isn't suitable.
SOME INFORMATION YOU MAY NEED...
Inside cards/apps.html
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">{{card_title}}</h6>
</div>
<div class="card-body">
{% block card_body %}
{% endblock %}
</div>
Inside addstudents.html
{% extends 'layouts/panel.html' %}
{% extends 'apps/card.html' %}
{% load static %}
{% block content %}
{% with card_title='My Card TITLE' %}
{% block card_body %}
...SOME FORM, .... SOME PARAGRAPH
{% endblock %}
{% endblock %}
What's inside layouts/panel.html
layouts/panel.html contains some menu and navbars items [including CSS, bootstrap and JS dependencies].
What's apps/card.html?
apps/card.html contains the code-snippet of HTML and Bootstrap CARD. And I don't want to write this code multiple times. That's why I want it to be manipulated via Django Template Tags.
HOPE YOU UNDERSTOOD
I don't think this is directly possible. But here is a work around. In the view which handles addstudents.html, add has_card to the context as True.
views.py
def app_students(request):
# Your code
return render(request, 'addstudents.html', {'has_card': True})
layouts/panel.html
[...]
{% if has_card %}
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">{{card_title}}</h6>
</div>
<div class="card-body">
{% block card_body %}
{% endblock %}
</div>
</div>
{% endif %}
[...]
addstudents.html
{% extends 'layouts/panel.html' %}
{% with card_title='My Card TITLE' %}
{% block card_body %}
...SOME FORM, .... SOME PARAGRAPH
{% endblock %}
So this, if has_card doesn't exist, won't have the card_body block, but if it does exist as a truthy value, then it will.
I'm not sure if it fits your need.
One way could be to split the responsibilities a bit between the different templates.
From given information it could be possible to put bootstrap/layout stuff in cards/apps.html and add additional blocks for childs to override to just handle the forms and view specific information.
To clarify the inheritance that may resolve the problem:
layouts/panel.html -> apps/card.html -> addstudents.html
The apps/card.html overrides block content from layout/panel.html and adds additional blocks which are used by the addstudents.html.
It can also be seen as, in words: addstudents.html extends card.html which extends panel.html.
Afaik you can extend as many times you want, but not use extends twice in the same template.
cards/apps.html
{% extends 'layouts/panel.html' %}
{% block content %}
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">{% block card_title %}{% endblock %}</h6>
</div>
<div class="card-body">
{% block card_body %}
{% endblock %}
</div>
{% endblock content %}
addstudents.html
{% extends 'apps/card.html' %}
{% block card_title}My Card TITLE{% endblock card_title%}
{% block card_body %}
...SOME FORM, .... SOME PARAGRAPH
{% endblock card_body %}
Worth mention is also {{ block.super }} which can be quite useful sometimes if you need to render a "parent".
I am working on a project that uses twig.
Each page uses
{% extends "_layouts/_master" %}
Inside the _layouts/master there is a body tag
<body class="{% block bodyClass %}{% endblock %}">
Can I add a class to the body tag from a page that is using the include?
You can override parent block (defined in _layouts/_master) in child template (the one that extends parent). In your child template add this:
{% extends "_layouts/_master" %}
{% block bodyClass %}css-body-class another-css-body-class{% endblock %}
You can also include content of parent block and append something to it:
{% extends "_layouts/_master" %}
{% block bodyClass %}{{parent()}} css-body-class another-css-body-class{% endblock %}
You can read more in twig documentation for extends.
I've created a flask application and want to link Bootstrap and a custom css file.
What's currently happening is that bootstrap is being applied, but my custom styles in styles.css aren't showing. I know that my file references are correct, because the bootstrap and custom css work independent of one another. How can I get them both to apply at the same time such that I can override the bootstrap defaults in my css?
My template.html looks like this:
{% extends "bootstrap/template.html" %}
{% block head %}
{{ super() }}
<link rel="stylesheet" type="text/css" href="/static/css/styles.css" >
{% endblock %}
{% block title %} -- TITLE -- {% endblock %}
{% block navbar %}
-- NAVBAR HTML --
{% endblock %}
{% block content %}
-- BODY TEXT HTML--
{% endblock %}
A content page looks like this:
{% extends "template.html" %}
{% block title %} -- TITLE -- {% endblock %}
<head>
{% block head %}
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
{% endblock %}
</head>
{% block page_content %} PAGE CONTENT
{% endblock %}
Using the sf2.6.4 and the Twig templating system, I have a weird behaviour with the tag 'use'.
With a simple base template defining a default navbar and header content :
{# base.html.twig #}
<html lang="fr">
<head></head>
<body>
{% block navbar %}<hr> nav bar foo bar<hr>{% endblock %}
<!-- a default header -->
{% block header %}
{% include 'AppBundle:TestingTwigUse:header.html.twig' %}
{% endblock %}
</body>
With the given default header.html.twig template :
{# header.html.twig #}
{% block header_container %}
{% block header_title %}<h1>Default title</h1>{% endblock %}
{% block header_content %}
<div>
This default text header, blablabla...
</div>
{% endblock %}
{% endblock %}
When I try to build an index template, inheriting the base one and overiding the header content using 'use' tag like following :
{# index.html.twig #}
{% extends "AppBundle:TestingTwigUse:base.html.twig" %}
{% block header %}
{% use 'AppBundle:TestingTwigUse:header.html.twig' %}
{% block header_container %}
{{ parent() }}
{% block header_content %}
***** child template specific content ****
{% endblock %}
{% endblock %}
{% endblock %}
I have the strange following result with header_content block twice :
***** child template specific content **** ***** child template specific content ****
any idea ?
I thinkg the problem is you have two header_content blocks - one in the index.twig.html, second in the parent() call. Second definition overrides first which leads to duplications after compilation.
If you want to override the default text - you should remove parent() call. If you want to update (append) the default text - you should refactor your blocks structure to avoid identical names.
UPD Try following index
{# index.html.twig #}
{% extends "AppBundle:TestingTwigUse:base.html.twig" %}
{% block header_content %}
***** child template specific content ****
{% endblock %}
UPD 2 Check this solution
I found a solution. Use the block() function to get the child's block
content and pass it to header.html.twig as a variable in the include
statement
Finaly two solutions :
With 'use', we can get the part we want to keep but loosing inheritance :
{% block header %}
{% use 'AppBundle:TestingTwigUse:header.html.twig' with header_title as parent_header_title %}
{% block header_title %}
{{ block('parent_header_title') }}
{% endblock %}
***** child template specific content ****
{% endblock %}
The one is 'embeb' that combines include AND extends behaviour :
{% block header %}
{% embed 'AppBundle:TestingTwigUse:header.html.twig' %}
{% block header_content %}
***** child template specific content ****
{% endblock %}
{% endembed %}
{% endblock %}
I'm trying to specify a variable in a child template and access it from another template which is included in the parent template.
Here's what I'm trying to do (code trimmed to the bare minimum):
child.html
{% set var = 'foo' %}
{% extends 'base.html' %}
base.html
{% include 'bar.html' %}
bar.html
{{ var }}
At this point, I render the child.html file and nothing is output.
This is what I've tried:
If I specify the variable in the base.html file instead of the child.html file, it works.
If I pass the variable in my render call, it works. template.render(var = 'foo')
Chaging the base.html file to be {% include 'bar.html' with context %} doesn't fix it.
I am able to access the variable in my base.html file just fine, and in fact, I've managed to create a workaround by adding {% set foo = var %} to my base.html, and changing bar.html to {{ foo }}
So concisely put, my question is: Is there a way for a template that's included in a parent template to access a variable set in a child template? (Without having to define a new variable in the parent file like my workaround)
I was able to get this by passing the variable within the child block on the parent template.
Ex. I have active_page declared on my child template pricing.html.
At first, I was not able to access active_page within my included file navbar-alt.html but when I set the variables inside of the navbar block it worked.
{% block wrapper %}
<div id="wrapper">
{% block navbar %}
{% set navigation_bar = [
('/what-we-do', 'what-we-do', 'what we do'),
('/pricing', 'pricing', 'pricing'),
('/demo', 'demo', 'demo'),
('http://indico.readme.io/v1.0/docs', 'docs', 'docs')
] -%}
{% set active_page = active_page|default('index') -%}
{% if "dashboard" not in request.path %}
{% include 'includes/navbar-alt.html' %}
{% else %}
{% include 'includes/navbar.html' %}
{% endif %}
{% endblock navbar %}
{% if "dashboard" in request.path %}
{% block sidebar %}
{% include 'includes/sidebar.html' %}
{% endblock sidebar %}
{% endif %}
{% block content_wrapper %}
<div id="content">
{% block content %}{% endblock content %}
</div>
{% endblock content_wrapper %}
{% include 'includes/flashes.html' %}
</div>
{% endblock wrapper %}
Original inspiration:
Jinja Tricks