I'm Twig beginner. I currently try to setup Yii2 layout with Twig.
I having 3 Twig file.
base.twig
{{ this.beginPage() }}
<!DOCTYOE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ app.language }}">
<head>
<meta charset="{{ app.charset }}" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ html.encode(this.title) }}</title>
{{ this.head() }}
{{ html.csrfMetaTags() | raw }}
</head>
<body>
{{ this.beginBody() }}
{% block body %}{% endblock %}
{{ this.endBody() }}
</body>
</html>
{{ this.endPage() }}
cp.twig
{% extends '_layouts/base.twig' %}
{% block body %}
<div class="cp">
{% block header %}{% endblock %}
<hr />
{% block content %}
{{ content }}
{% endblock %}
</div>
{% endblock %}
index.twig
{% extends '_layouts/cp.twig' %}
{% block header %}this is header{% endblock %}
After I render from my Yii2 controller return $this->render('index'); then it come out very weird output:
<!DOCTYOE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<meta name="csrf-param" content="_csrf">
<meta name="csrf-token" content="z_y1CPsfUBwHE6uC3dHg225wVQ8i2-eGhZa9f55Qrm39nYI6gk0TdVJ6nruf5q6WJAcCaUGolPWo9fxM_TrNHA==">
</head>
<body>
<div class="cp">
<hr />
<!DOCTYOE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<link href="/mlaxology/yii2/workspace/projects/pawscms/web/assets/903cba57/css/style.css" rel="stylesheet">
<meta name="csrf-param" content="_csrf">
<meta name="csrf-token" content="z_y1CPsfUBwHE6uC3dHg225wVQ8i2-eGhZa9f55Qrm39nYI6gk0TdVJ6nruf5q6WJAcCaUGolPWo9fxM_TrNHA==">
</head>
<body>
<div class="cp">
this is header <hr />
</div>
</body>
</html>
</div>
</body>
</html>
It output unexpected duplicated parent layout.
My objective is to create a dynamic layout header which can be override by child layout with Twig {% block header %}{% endblock %} command. I know there is other way to solve this issue, like using Twig variable to store the dynamic header. But I like they way what {% block %} does.
I'm wondering why base.twig {% block body %}{% endblock %} working properly but index.twig having repeat content issue ....
I already spend 2 days on this, try googling but no similar issue can be found ... finally I think I really need stackoverflow help.
Sorry for my English and thanks for reading this :)
My ugly way to solve this issue :
base.twig:
{% if content is defined %}{{ content | raw }}{% else %}
{{ void(this.beginPage()) }}
<!DOCTYOE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ app.language }}">
<head>
<meta charset="{{ app.charset }}" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ html.encode(this.title) }}</title>
{{ this.head() }}
{{ html.csrfMetaTags() | raw }}
</head>
<body>
{{ this.beginBody() }}
{%- block body %}{% endblock %}
{{ this.endBody() }}
</body>
</html>
{{ void(this.endPage()) }}
{% endif %}
After several debug ... this happen because reprint content, so I wrap with {% if content is defined %}{{ content | raw }}{% else %} for temp fix.
Any better way to solve this issue?
Related
i have two html file ,i should extends secend file from first file but it doesnt work
first file base.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}Library{% endblock %}</title>
</head>
<body>
<div id="test">
{% block test %}
<h1>This page belongs to me.</h1>
{% endblock %}
</div>
</body>
</html>
secend one booklist.html
{% extends "base.html" %}
{% block content %}
<h3>Books</h3>
<div>
{% for book in books %}
{% if book.available %}
<p>{{ book.author }} wrote {{ book.title }}.</p>
{% endif %}
{% endfor %}
</div>
{% endblock %}
You Forgot to add in your parent template
{% block content %}{% endblock %}
This is where the child template is going to be placed.
Your parent template should look like this (for example):
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}Library{% endblock %}</title>
</head>
<body>
<div id="test">
{% block test %}
<h1>This page belongs to me.</h1>
{% endblock %}
</div>
<div class="myChildContentComesHere">{% block content %}{% endblock %}</div>
</body>
</html>
I have a Django website where I have separated the html files into a base.html file as so:
{% include 'head.html' %}
<body>
{% include 'nav.html' %}
{% block content %}
{% endblock content %}
{% include 'footer.html' %}
{% include 'scripts.html' %}
</body>
</html>
Due to including head.html, the title on each page is the same, since head.html has only 1 title. Here is the head.html file:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{% static 'css/materialize.css' %}">
<link rel="stylesheet" href="{% static 'css/materialize.min.css' %}">
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<link rel="stylesheet" href="{% static 'css/custom.css' %}">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<title>mytitle</title>
</head>
But i want to display different titles for different pages and I dont know how to. Anyone have any idea?
base.html
{% include 'head.html' with title=title %}
<body>
{% include 'nav.html' %}
{% block content %}
{% endblock content %}
{% include 'footer.html' %}
{% include 'scripts.html' %}
</body>
</html>
views.py
def home(request):
context = {
"title":"Home"
}
return render(request,"template",context)
head.html
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{% static 'css/materialize.css' %}">
<link rel="stylesheet" href="{% static 'css/materialize.min.css' %}">
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<link rel="stylesheet" href="{% static 'css/custom.css' %}">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<title>{{title}}</title>
</head>
Use blocks which are overridable:
head.html
...
<title>{% block page_title %}{% endblock %}</title>
my_concrete_page.html
{% extends base.html %}
{% block page_title %}my concrete title{% endblock %}
I am giving this answer from my knowledge:
Make one file for this :
head.html
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{% static 'css/materialize.css' %}">
<link rel="stylesheet" href="{% static 'css/materialize.min.css' %}">
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<link rel="stylesheet" href="{% static 'css/custom.css' %}">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
make different file for your different title :
title1.html
<title>mytitle</title>
title2.html
<title>mytitle</title>
now add in your main file like this :
<head>
{% include 'head.html' %}
{% include 'title1.html' %}
</head>
<body>
{% include 'nav.html' %}
{% block content %}
{% endblock content %}
{% include 'footer.html' %}
{% include 'scripts.html' %}
</body>
</html>
I hope this works for you.
use include instead of extend for base.html and pass dynamic title to base.html
django link : include
{% include "base.html" with objects=website.title %}
I had to combine the ideas of #Ivan and #Soham. I removed the title tag from my head.html and added that to my base.html. Along with that I used overrideable block tag inside the title tag. So now my base.html looks like this:
<!DOCTYPE html>
<html lang="en">
{% include 'head.html' %}
<title>{% block title %}{% endblock title %}</title>
<body>
{% include 'nav.html' %}
{% block content %}
{% endblock content %}
{% include 'footer.html' %}
{% include 'scripts.html' %}
</body>
</html>
And all I have to do now is use the tags accordingly in other pages:
{% extends 'base.html' %}
{% block title %}whatever i want the title to be{% endblock title %}
Option 1. Base.html file
<link rel="stylesheet" href="{% static 'css/style.css' %}"
.
.
<title>{% block title %} Home-title {% endblock %}</title>
Then add like this code your file
{% block title %} Search Results {% endblock %}
Option 2. To query a model in the view:
{% extends "blog/base.html" %}
{% block title %} {{blog_obj.title}} {% endblock %}
{% block content %}
I am learning djnago , I would like to display an html page (in template forlder) into another html file by keeping {% extends 'base.html' %} which my template HTML that has my nav bar, CSS , javascritp..
the structure:
App1=>templates=>App1=>map.html (is a map app html file generated with folium https://python-visualization.github.io/folium/)
App1=>templates=>App1=>home.html
Src=>templates=>base.html
in home.html I would like to diplay map.html and all base.html elements (nav bar, CSS, javasript)
Here is my base .html code :
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- semantic UI -->
<!--Chart js-->
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<title>skill-site | {% block title %} {% endblock title %}</title>
</head>
<body>
{% include 'navbar.html' %}
{% block scripts %}
{% endblock scripts %}
<div class="container ui">
{% block content %}
{% endblock content %}
</div>
</body>
</html>
here is the code for home.html but it is not working:
{% extends 'base.html' %}
{% block title %}my map{% endblock title %}
{% block content %}
{% include './map.html' %}
{% endblock content %}
Thanks for your help
So I'm trying to develop an app in Django. At the moment I'm trying to do a simple search bar that when you type the title of a fil it show several data of that film. I have successfully developed the search bar and it works. The problem is that when doing the html template and extending it from base.html the data shown dissapears.
base.html
<!DOCTYPE html>
<html lang="es">
<head>
{% load staticfiles %}
<title>Peliculas</title>
<meta name="description" content="website description" />
<meta name="keywords" content="website keywords, website keywords" />
<meta http-equiv="content-type" content="text/html; charset=windows-1252" />
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.16/dist/vue.js"></script>
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?
family=Tangerine&v1" />
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?
family=Yanone+Kaffeesatz" />
<link rel="stylesheet" type="text/css" href="{% static 'myapp/style.css' %}"/>
</head>
<body>
<div id="content">
<div id="main">
<div id="header">
<div id="logo">
<h1>SERIAL KILLER</h1>
<div class="slogan">SLOGAN</div>
</div>
<div id="menubar">
<ul id="menu">
<!-- put class="current" in the li tag for the selected page - to highlight which page you're
on -->
{%block menu%}
{% endblock %}
</ul>
</div>
</div>
</div>
<div id="site_content">
{%block lado%}
{% endblock %}
<div id="content">
{% block contenido %}
{% endblock %}
</div>
</body>
</html>
the template where I show the data from the query: buscarResultados.html
{% extends "base.html" %}
{% load staticfiles %}
{% block titulo %} RESULTADOS {% endblock %}
{%block content %}
<ul>
{% for peli in object_list %}
<li>
{{peli.titulo}}, {{peli.descripcion}}
</li>
{% endfor %}
</ul>
{% endblock %}
my form in index.html
<div id="search">
<form action="{% url 'busqueda_resultados' %}" method= 'get'>
<input type="text" name="q" placeholder="Buscar...">
<input type="submit" value="Buscar">
</form>
</div>
my views.py
class BuscarPeliculas(ListView):
model = Pelicula
template_name = 'buscarResultados.html'
def get_queryset(self):
query = self.request.GET.get('q')
object_list = Pelicula.objects.filter(
Q(titulo__icontains=query) | Q(descripcion__icontains=query)
)
return object_list
my urls.py
path('busqueda/', views.BuscarPeliculas.as_view(), name='busqueda_resultados'),
what appears if I extend from base.html
What appears if I don't extend from base.html
as you can see, The data dissapears if I extend from base.html, I tried to do my question as complete as possible, help is much appreciated.
Its because you are addintg it to a block content, but the base.html expects block contenido
fix your block names
I'm having trouble trying to get Flask (along with Flask-Bootstrap) to only produce one head element to my HTML document. The problem I'm having right now is that the head element is correct, but Flask is dropping it into the beginning of the body as well.
/personal_website/app/templates/index.html:
{% extends "bootstrap/base.html" %}
#! I have not changed bootstrap/base.html
{% block head %}
{{super()}}
{% block title %}My_Name | Home{% endblock title %}
{% block styles %}
{{super()}}
<link href="{{url_for('static',filename='stylesheets/style.css')}}"
rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto"
rel="stylesheet">
{% endblock styles %}
{% endblock head %}
Console output:
<head>
<title>My_Name | Home</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap -->
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/stylesheets/style.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
</head>
<body>
My_Name | Home
<!-- Bootstrap -->
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/stylesheets/style.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
I actually was able to correct this by taking the contents of what was in the header (ex: Title and Styles) out of the block head.
/personal_website/app/templates/index.html:
{% extends "bootstrap/base.html" %}
{% block title %}My_Name | Home{% endblock %}
{% block styles %}
{{super()}}
<link href="{{url_for('static',filename='stylesheets/style.css')}}"
rel="stylesheet">
{% endblock styles %}
{% block head %}
{{ super() }}
{% endblock %}
This still alowed me to inherit the contents of the head from bootstrap/base.html
I think you just need to remove this line (probably both times):
{{super()}}