How to modularize templates in django? - python

base.html
<!DOCTYPE html>
<html>
<head>
{% block head %}
{% endblock %}
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
head.html
<title>Example</title>
body.html
<h1>Example Django</h1>
Using django, you can render the template "base.html" but replace the blocks "head" and "body", respectively, by templates "head.html" and "body.html"?

If i understand you right, you need include tag
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#include
<!DOCTYPE html>
<html>
<head>
{% include "head.html" %}
</head>
<body>
{% include "body.html" %}
</body>
</html>

{% include "base.html" %}
{% block head %}
{% include "head.html" %}
{% endblock %}
{% block body %}
{% include "body.html" %}
{% endblock %}

Related

Inherit template without using super()

I have the following base.html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<link rel = "stylesheet" href = "{{ url_for('static', filename = 'css/base.css') }}" type = "text/css"/>
{% block head %}
{% endblock %}
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
Then I have base_header.html, which I want for pages with a header
{% extends "base.html" %}
{% block head %}
<link rel = "stylesheet" href = "{{ url_for('static', filename = 'css/header.css') }}" type = "text/css"/>
{% endblock %}
{% block content %}
<header>
...
</header>
{% endblock %}
In order for the header to show up, I have to call super() in both blocks
{% extends "base_header.html" %}
{% block head %}
{{ super() }}
<title>Page title</title>
{% endblock %}
{% block content %}
{{ super() }}
<h1>Page header</h1>
{% endblock %}
Is it possible to have this sort of template inheritance without having to include super() every time I want to include the header? I would like it so if I decide a page needs a header, I can just change extends "base.html" to extends "base_header.html" without further changes.
You need the super() call, because otherwise your final template is replacing the content of the head block in the parent template. You could introduce a new block in the intermediate template, base_header.html:
{% block head %}
<link rel = "stylesheet" href = "{{ url_for('static', filename = 'css/header.css') }}" type = "text/css"/>
{% block more_head %}
{% endblock %}
{% endblock %}
Then your final template looks like:
{% extends "base_header.html" %}
{% block more_head %}
<title>Page title</title>
{% endblock %}

Extends base template not appearing in Flask Python

I've got a base.html page that has both a header and a footer block.
When I use {% extends "base.html" %} in my home.html page, I get nothing from the base.html page.
If I use {% include "base.html" %}, all my content in the home.html page is at the bottom, with the header and footer at the top. Does anyone know how I can fix this?
I'd like the header block at the top, the content from home.html in the middle, and the footer block rendered on the bottom of the home page.
I'd be grateful for any help. Thanks.
Here is my code. myapp.py
from flask import Flask, render_template, url_for
app = Flask(__name__)
#app.route("/")
#app.route("/home")
def home():
return render_template("home.html", title="Home",
menu = menu)
#app.route("/base")
def base():
return render_template("base.html", title="Base")
if __name__ == "__main__":
app.run(debug=True)
base.html
<!DOCTYPE html>
<html>
<head>
<title>{{title}} - Restaurant</title>
</head>
<body>
{% block header %}
<ul>
<li>Home</li>
</ul>
{% endblock header %}
{% block footer %}
<h1>This is a footer</h1>
{% endblock footer %}
</body>
home.html
{% extends "base.html" %}
{% block header %}
<h1>Home Page</h1>
{% endblock header %}
{% block footer %}
<h1>New stuff in home page</h1>
{% endblock footer %}
Defining a block in a child template automatically overrides the version from the parent template completely. If you want to also output the parent version, you need to call super() - see the Jinja2 docs.
So your home.html should be:
{% extends "base.html" %}
{% block header %}
{{ super() }}
<h1>Home Page</h1>
{% endblock header %}
{% block footer %}
{{ super() }}
<h1>New stuff in home page</h1>
{% endblock footer %}
Try this?
base.html
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %} - Restaurant</title>
</head>
<body>
{% block header %}
<ul>
<li>Home</li>
</ul>
{% endblock header %}
{% block content %}{% endblock %}
<h1>This is a footer</h1>
</body>
home.html
{% extends "base.html" %}
{% block content %}
{% block header %}
<h1>Home Page</h1>
{% endblock header %}
{% block footer %}
<h1>New stuff in home page</h1>
{% endblock footer %}
{% endblock %}
https://flask.palletsprojects.com/en/1.1.x/tutorial/templates/

Django- url not displaying page despite changing

This is the index.html
{% extends 'base.html' %}
{% block content %}
<h1>list of {{title}}</h1>
{% if questions %}
<ul>
{% for question in questions %}
<li>
{{question.title}}
</li>
{% endfor %}
</ul>
{% else %}
<p>there is a no question available</p>
{% endif %}
{% endblock %}
details.html
{% extends 'base.html' %}
{% block content %}
<H2>Details Page</H2>
<h3>{{question.title}}</h3>
{% for choice in question.choices %}
<p>{{choice.text}}({{choice.votes}})</p>
{% empty %}
<p>There is no choice available for this Question</p>
{% endfor %}
<p>Poll is created by {{question.created_by.first_name}}</p>
{% endblock %}
This is base.html
{%load static%}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebPage</title>
<link rel="stylesheet" href="(%static 'css/custom.css'%)">
</head>
<body>
<h1>Welcome to My Page</h1>
{% block content %}
{% endblock %}
</body>
</html>
And poll.urls
from django.conf.urls import url
from poll.views import *
urlpatterns = [
url('', index, name='polls_list'),
url('<int:id>/details/', details, name='polls_details')
]
So this is what happens I have 3 questions that display on the index.html, on clicking any of them it changes to the proper url but does not open the requested page. How do I solve this. Do keep in mind that i just started django two days ago so pardon my naivety.Thanks
In urls.py you are using the url() function but path syntax. Change it to path:
path('', index, name='polls_list'),
path('<int:id>/details/', details, name='polls_details')
Edit If you're using pre-2.0, path syntax is not supported, so you need to use regexes:
url('^$', index, name='polls_list'),
url('^(?P<id>\d+)/details/$', details, name='polls_details')
Can you please edit your url as per the code below. Django can handle the url creation.
{{question.title}}

How to access context variables in parents template django

I have base.html and file with header _header_main.html in my main template index.html i extends base.html and include _header_main.html but variables that i pass into index.html not visible in parent template
base.html:
<html>
<head>
<title>{% block title %}{% endblock %}</title>
<!-- styles -->
...
</head>
<body>
{% block _header_main %}{% endblock %}
{% block _header_mobile %}{% endblock %}
<div class="wrapper">
<!-- header -->
{% block header_main %}{% endblock %}
{% block header_mobile %}{% endblock %}
<div class="after_header"></div>
<!-- end header -->
{% block content %}{% endblock %}
<footer class="footer">
...
</footer>
</div>
</body>
</html>
_header_main.html:
<header class="header">
<ul>
{% for i in servers %}
<li>{{ i.title }}</li>
{% endfor %}
</ul>
</header>
index.html:
{% extends "base.html" %}
{% load static %}
{% block title %}Title{% endblock %}
{% block header_main %}
{% include "_header_main.html" %}
{% endblock %}
{% block content %}
Some content...
{% endblock %}
<scripts>
...
</scripts>
How i can access to variables items in my template?
Edit. My function in views.py
def index(request):
servers = Server.objects.all().order_by('ranking')
basket_count, total_price = basket_calculate(request)
server_arr = [i.title for i in servers]
servers_string = ', '.join(server_arr)
return render(request, 'index.html', {'servers':servers, 'temp_year' : datetime.now().year,
'basket_count':basket_count, 'total_price':total_price,
'servers_string':servers_string })
The reason why my items variable don't show in templates, is because i add <script> tag with js without block, so my scripts didn't work. I add my scripts to {% block script %} and all works fine!

How to parse a django template and render specific tag

Is it possible to parse a django template and only render a specific tag ?
This snippet is close to what I'm looking for but it doesn't return the entire template.
Basically if I have this template as input
<html>
<title>{% block title%}{% endblock %}</title>
<body>
{% block content %}
{% mycustomtag "args" %}
{% endblock content %}
</body>
</html>
and i want to only render mycustomtag this is the output Im looking for
<html>
<title>{% block title%}{% endblock %}</title>
<body>
{% block content %}
<p>Result from mycustomtag</p>
{% endblock content %}
</body>
</html>
Thanks.
If I properly understand your question, then there is a way to do that, using the {% verbatim %} tag. It will be added in Django 1.5, but for now you can use it as your custom tag - here is the source: https://code.djangoproject.com/ticket/16318
The only drawback here is that you cannot use directly this template, it needs double rendering. If this is what you need - then everything is OK.
To use it, all you need to do is to enclose the other tags with {% verbatim %} :
{% load my_custom_tags %} <-- this is needed to load the 'verbatim' and 'mycustomtag' tags
{% verbatim %}
<html>
<title>{% block title%}{% endblock %}</title>
<body>
{% block content %}
{% endverbatim %}
{% mycustomtag "args" %}
{% verbatim %}
{% endblock content %}
</body>
</html>
{% endverbatim %}
I've made a simple test with this template:
#register.simple_tag
def mycustomtag(a):
return "<p>%s</p>" % a
....
from django.template import loader, Context
print loader.get_template("test.html").render(Context({}))
This prints the following:
<html>
<title>{%block title%}{%endblock%}</title>
<body>
{%block content%}
<p>args</p>
{%endblock content%}
</body>
</html>
Hope this could be helpful.

Categories

Resources