Django4FrontEnd
Autor: Carlos Batman
Django4FrontEnd
Author: Carlos Batman
Templates em Django - Django4FrontEnd
Fat models
Thin views
STUPID TEMPLATES
fonte: Vokal
Templates em Django - Django4FrontEnd
<div class="card">
<header>Bla bla bla 1</header>
<p>Texto 1</p>
<footer>Footer 1</footer>
</div>
<div class="card">
<header>Bla bla bla 2</header>
<p>Texto 2</p>
<footer>Footer 2</footer>
</div>
<div class="card">
<header>Bla bla bla 3</header>
<p>Texto 3</p>
<footer>Footer 3</footer>
</div>
<!-- ... and MANY MORE! -->
Repetição...
Repetição...
Repetição...
Padrões!
<!-- Página de perfil de Joaquim -->
<div class="profile">
<p>Joaquim Raia</p>
<!-- Só deveria mostrar se tiver profissão -->
<p>Carpinteiro</p>
</div>
<!-- ... -->
<!-- Página de perfil de Joaquim -->
<div class="profile">
<p>Joaquim Raia</p>
<!-- Só deveria mostrar se tiver profissão -->
<p>Carpinteiro</p>
</div>
Templates em Django - Django4FrontEnd
<!-- What if we had ENTITIES? -->
{% for article in articles %}
<div class="card">
<header>{{article.title}}</header>
<p>{{article.tease}}</p>
<footer>{{article.footnote}}</footer>
</div>
{% endfor %}
<!-- READABLE! -->
Padrões!
{% for profile in profiles %}
<div class="profile">
<p>{{profile.name}}</p>
{% if profile.job %}
<p>{{profile.job}}</p>
{% endif %}
</div>
{% endfor %}
<!-- READABLE -->
Templates em Django - Django4FrontEnd
E se tivéssemos um molde?
<!DOCTYPE html>
<html lang="<!-- changes -->">
<head>
<title><!-- changes --></title>
<link rel="stylesheet" type="text/css" href="stylesforeverything.css" />
<script src="usethiseverywhere.js"></script>
</head>
<body>
<!-- changes -->
</body>
</html>
Templates em Django - Django4FrontEnd
E se tivéssemos um molde?
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="stylesforeverything.css" />
<script src="usethiseverywhere.js"></script>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
Templates em Django - Django4FrontEnd
fonte: https://docs.djangoproject.com/en/1.7/topics/templates/
Texto... com contexto!
Templates em Django - Django4FrontEnd
{% load staticfiles %}
<html>
<head>
<title>Django Girls blog</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link href='//fonts.googleapis.com/css?family=Lobster&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="{% static 'css/blog.css' %}">
</head>
<body>
<div class="page-header">
<h1><a href="/">Django Girls Blog</a></h1>
</div>
<div class="content container">
<div class="row">
<div class="col-md-8">
{% for post in posts %}
<div class="post">
<div class="date">
{{ post.published_date }}
</div>
<h1><a href="">{{ post.title }}</a></h1>
<p>{{ post.text|linebreaksbr }}</p>
</div>
{% endfor %}
</div>
</div>
</div>
</body>
</html>
fonte: https://tutorial.djangogirls.org/en/template_extending/
Templates em Django - Django4FrontEnd
fonte: Django Best Practices
Templates em Django - Django4FrontEnd
Templates em Django - Django4FrontEnd
Fonte: Django Girls
Templates em Django - Django4FrontEnd
the Django template system is not simply Python embedded into HTML.
This is by design: the template system is meant to express presentation, not program logic
fonte: https://docs.djangoproject.com/en/1.8/topics/templates/
Templates em Django - Django4FrontEnd
<div class="card">
<header>{{title}}</header>
<p>{{excerpt}}</p>
<footer>{{footnote}}</footer>
</div>
Templates em Django - Django4FrontEnd
Certo
Errado
{{variavel}}
{{ variavel }}
{{ variavel_interessante }}
{{ variavel-com-hifens }}
{{ variavel com espacos }}
'-' é operador em Python (e não só...)
Templates em Django - Django4FrontEnd
fonte: Django Project
{% for story in story_list %}
<h2>
<a href="{{ story.get_absolute_url }}">
{{ story.headline|upper }}
</a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
{% endfor %}
{% endblock %}
Templates em Django - Django4FrontEnd
fonte: Django Project
{{value|length}}
{{value|dictsort:"name"}}
{{value|dictsort:"author.age"}}
<!-- True = 'sim' -->
<!-- False = 'nao' -->
<!-- None = 'talvez' -->
{{ value|yesno:"sim,nao,talvez" }}
<!-- neste caso, None = 'nao' -->
{{ value|yesno:"sim,nao" }}
<!-- link fica logo à volta de um <a></a> -->
{{'olhem para www.google.com'|urlize}}
{{ "<p>Nao queria nenhuma <em>tag</em> no meu conteudo</p>"|striptags }}
Templates em Django - Django4FrontEnd
fonte: Django Project
{{value|default:'Nada'}} <!-- False or None -->
{{value|default_if_none:'Nada'}} <!-- None and ONLY if None -->
{{"Batman"|upper}} <!-- "BATMAN" -->
{{"Robin"|lower}} <!-- "robin" -->
{{"BATMAN and rOBIN"|title}} <!-- titlecase - "Batman And Robin" -->
<p>Você tem {{num_trab}} trabalhador{{num_trab|pluralize:"es"}}</p>
<p>Você também tem {{num_funis}} funi{{num_cherries|pluralize:"l,s"}}.</p>
<!-- pode ser usado dentro de blocktrans -->
{{"My son my planet or me"|truncatechars:9}} <!-- "My son..." -->
{{"<p>All Saiyans</p>"|truncatechars_html:9}} <!-- "<p>All Sa...</p>" -->
{{"Prince of all Sayians"|truncatewords:3}} <!-- Prince of all... -->
<!-- DICA: tambem existe truncatewords_html -->
Templates em Django - Django4FrontEnd
fonte: Django Project
{{value|default:'Nada'}} <!-- False or None -->
{{value|default_if_none:'Nada'}} <!-- None and ONLY if None -->
{{"Batman"|upper}} <!-- "BATMAN" -->
{{"Robin"|lower}} <!-- "robin" -->
{{"BATMAN and rOBIN"|title}} <!-- titlecase - "Batman And Robin" -->
<p>Você tem {{num_trab}} trabalhador{{num_trab|pluralize:"es"}}</p>
<p>Você também tem {{num_funis}} funi{{num_cherries|pluralize:"l,s"}}.</p>
<!-- pode ser usado dentro de blocktrans -->
{{"My son my planet or me"|truncatechars:9}} <!-- "My son..." -->
{{"<p>All Saiyans</p>"|truncatechars_html:9}} <!-- "<p>All Sa...</p>" -->
{{"Prince of all Sayians"|truncatewords:3}} <!-- Prince of all... -->
<!-- DICA: tambem existe truncatewords_html -->
Templates em Django - Django4FrontEnd
fonte: Django Project
<!-- assumamos numeric_value como 3 e string_value como 'Nada' -->
{{numeric_value|add:2}} <!-- 5 -->
{{value|add:' a apontar'}} <!-- 'Nada a apontar' (sem aspas) -->
Templates em Django - Django4FrontEnd
fonte: Django Project
<!-- some_list = [1, 3, 5, 9, 1, 23] -->
<!-- funciona como as listas em Python' -->
{{some_list|slice:':2'}}
<!-- isto equivale a
>>> some_list[:2]
-->
<!-- ate índice 2 -->
<!-- resultado: [1, 3] -->
{{some_list|slice:'1:6:2'}}
<!-- desde o índice 1 até o índice 6, de 2 em 2 -->
<!-- resultado: [3, 9, 23] -->
Templates em Django - Django4FrontEnd
fonte: Django Project
Templates em Django - Django4FrontEnd
fonte: Django Project
{% extends "base_generic.html" %}
{% block title %}{{ section.title }}{% endblock %}
{% block content %}
<h1>{{ section.title }}</h1>
{% for story in story_list %}
<h2>
<a href="{{ story.get_absolute_url }}">
{{ story.headline|upper }}
</a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
{% endfor %}
{% endblock %}
Templates em Django - Django4FrontEnd
fonte: Django Project
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="stylesforeverything.css" />
<script src="usethiseverywhere.js"></script>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
Templates em Django - Django4FrontEnd
fonte: Django Project
{% extends "base_generic.html" %}
{% block title %}{{ section.title }}{% endblock %}
{% block content %}
<h1>{{ section.title }}</h1>
{% for story in story_list %}
<h2>
<a href="{{ story.get_absolute_url }}">
{{ story.headline|upper }}
</a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
{% endfor %}
{% endblock %}
Templates em Django - Django4FrontEnd
fonte: Django Project
Block + Extends
A essência do que realmente torna esta "linguagem" numa Templating Engine
Templates em Django - Django4FrontEnd
fonte: Stack Overflow
<!-- extended.html -->
{% extends 'base.html' %}
{% block extra_head_content %}
{{ block.super }}
{% comment %}
sem este bloco, o <script>
seria reescrito no template expandido
{% endcomment %}
<link rel="stylesheet" type="text/css" href="/static/css/account.css" />
{% endblock %}
<!-- base.html -->
{% load static %}
<html>
<head>
<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}" />
{% block extra_head_content %}
<script src="{% static 'default_script.js' %}"></script>
{% endblock %}
</head>
<body>{% block content %}{% endblock %}
</html>
Templates em Django - Django4FrontEnd
fonte: Django Project
Templates em Django - Django4FrontEnd
fonte: Stack Overflow
<!-- Passa o contexto -->
{% include 'app/partials/component.html' %}
<!-- Nao passa o contexto -->
{% include 'app/partials/component.html' only %}
<! -- conteudo mais variavel extra -->
{% include 'app/components/component.html' with extra='batman string' %}
<!-- apenas variaveis definidas -->
{% include 'app/components/component.html' with extra=3 something=else only %}
Templates em Django - Django4FrontEnd
{% for book in books %}
<li>{{ book }}</li>
{% empty %}
<li>Sorry, there are no books.</li>
{% endfor %}
<!-- ex. 2 -->
{% for item in items %}
{# se não for o primeiro ou segundo elemento... #}
{# forloop.counter começa com 1... forloop.counter0 começa com 0 #}
{% if forloop.counter > 2 %}
<li>{{item}}</li>
{# se for o último elemento... #}
{% if forloop.last %}
<li>Fim</li>
{% endif %}
{% endfor %}
<!-- ex. 2.1 -->
{% for item in items %}
{% if forloop.first %}
<li>Início</li>
{% endif %}
{# se item for um dos dois últimos (dica por: Mickael Morgado) #}
{% if forloop.revcounter < 2 %}
<li>{{item}}</li>
{# se for o último elemento... #}
{% endfor %}
dica: Mickael Morgado
Templates em Django - Django4FrontEnd
fonte: Django Project
{% with total=business.employees|length companhia=business.company %}
A companhia {{companhia}} tem:
{{ total }} trabalhador{{ total|pluralize:"es" }}
{% endwith %}
{# The 'with' tag CACHES a complex variable (makes a copy, not a reference) #}
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}
{% verbatim myblock %}
Avoid template rendering via the {% verbatim %}{% endverbatim %} block.
{% endverbatim myblock %}
{% filter force_escape|lower %}
This text will be HTML-escaped, and will appear in all lowercase.
{% endfilter %}
Templates em Django - Django4FrontEnd
{% lorem 4 p random %}
<!-- 4 paragrafos de lorem ipsum, cada um dentro de um elemento 'p' -->
<!-- ultimo parametro eh opcional, mas se preenchido faz com que o possa
n comecar com 'lorem ipsum dolorem...' -->
<p>
{% lorem 23 w %}
<!-- 23 palavras latinas... wohoo! -->
</p>
Templates em Django - Django4FrontEnd
Subdomínios de tags que podem requerer bibliotecas adicionais
Templates em Django - Django4FrontEnd
fonte: Django Project
{% load i18n %}
<!-- python manage.py makemessages -a -->
<!-- python manage.py compilemessages -->
<p>{% trans "Uma string qualquer" %}</p>
<p>{% trans "comando" context "army ranking" %}</p> <!-- importante para diversos contextos -->
<p>{% trans variavel_em_contexto %}</p>
{% trans "Nao exibir ja" as titulo_traduzido %}
<title>{{ titulo_traduzido }}</title>
{% blocktrans %}
<p>Este bloco tem alguma {{variavel}} e <i>tags</i><br />
E requer cuidado especial</p>
{% endblocktrans %}
{% blocktrans with autor=livro.autor.nome|upper count quantidade=livro.vendidos %}
O autor {{autor}} vendeu {{quantidade}} livro de {{livro.nome}}
{% plural %}
O autor {{autor}} vendeu {{quantidade}} livros de {{livro.nome}}
{% endblocktrans %}
Templates em Django - Django4FrontEnd
fonte (informação e exemplo): Django Project
{% load i18n %}
<!-- obter lista de objetos com código
e nome de línguas disponíveis para projeto -->
{% get_available_languages as languages %}
{% trans "View this category in:" %}
{% for lang_code, lang_name in languages %}
<!-- dentro desta tag, tudo o que tenha traduções
irá ser adaptado à língua especificada -->
{% language lang_code %}
<a href="{% url 'category' slug=category.slug %}">
{{ lang_name }}
</a>
{% endlanguage %}
{% endfor %}
Templates em Django - Django4FrontEnd
fonte: Django Project
<p>A data foi: {{ value|date:"D d M Y" }}</p>
<p>Faltam: {{ conference_date|timeuntil:from_date }}</p>
<p>Publicado há {{ blog_date|timesince:comment_date }}</p>
{{ value|time:"H:i" }}
{{ value|time }} <!-- vai buscar o TIME_FORMAT nas settings -->
Templates em Django - Django4FrontEnd
fonte: https://docs.djangoproject.com/en/1.7/topics/templates/
{% load humanize %}
<!-- variam com a lingua/regiao -->
<p>{% apnumber 1 %}</p> <!-- one -->
<p>{% apnumber 10 %}</p> <!-- 10 -->
<p>{% intcomma 4500 %}</p> <!-- 4,500 -->
<p>{% naturalday somedate %}</p> <!-- now, 2 days ago... -->
<p>{% naturaltime somedate %}</p> <!-- now, a minute ago, 1 day and 3 hours ago... -->
<p>{% ordinal 1 %} <!-- 1st -->
Templates em Django - Django4FrontEnd
fonte: Django Forms Api
<!-- todo o formulário com campos dentro de parágrafos -->
{{ form.as_p }}
<!-- todo o formulário com campos dentro de itens de lista -->
{{ form.as_ul }}
<!-- o campo, definido com o nome da propriedade do mesmo no formulário -->
{{ form.field }}
Mas, sendo Front-end developer, pode dar jeito renderizar o formulário e campos manualmente
Templates em Django - Django4FrontEnd
fontes: Django Docs Forms API (1.7), Stack Overflow
<form method="POST">
<!-- medida de segurança automática do django -->
{{form.csrf}}
<!-- campo input renderizado manualmente -->
<input
id="{{form.field.id_for_label}}"
name="{{form.field.html_name}}"
{% if form.field.value %}
value="{form.field.value}"
{% endif %}
/>
<select id="{{form.field.id_for_label}}" name="{{form.field.html_name}}">
{% for value,label in form.field.choices %}
<option value="{{value}}"{% if form.field.value == value %} selected{% endif %}>
{{ label }}
</option>
{% endfor %}
</select>
</form>
Renderização manual
Templates em Django - Django4FrontEnd
fonte: https://docs.djangoproject.com/en/1.7/topics/templates/
Texto... com contexto!
Templates em Django - Django4FrontEnd
fontes: Python code patterns l
Afinal, onde vai MESMO buscar os templates?
# ate ao 1.6 (1.7?), era diferente
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'APP_DIRS': True, # inclui pasta templates de cada app instalada
'DIRS': '/path/to/my/templates'
},
]
INSTALLED_APPS = ('myproject.polls', 'myproject.quizzes')
Pediram-me um template 'pages/about.html'.
Onde procuro?
Ordem das aplicações importa!
Templates em Django - Django4FrontEnd
Personalização
# settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
# wow, ate caminhos ah mao temos
# cuidado com os caminhos absolutos, amigos
'/home/html/example',
'/home/html/default',
],
'OPTIONS': {
'context_processors': ['...'],
'...': '...'
}
},
{
# Jinja eh outro tipo de templating engine
# temos um estagiario que gosta de Jinja E vai trabalhar numa pasta dif.
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'DIRS': [
'/home/html/somethingwithjinja'
],
},
]
Templates em Django - Django4FrontEnd
É o que o erro diz
Usar um base.html
Evitar lógica na camada de apresentação...
se possível evitar QUALQUER lógica
Queries? Lololololol...
{% url %} e {% static %} em vez de links absolutos
Templates em Django - Django4FrontEnd
fonte: https://docs.djangoproject.com/en/1.10/topics/performance/#template-performance
Templates em Django - Django4FrontEnd
fonte: https://docs.djangoproject.com/en/1.7/topics/templates/
Texto... com contexto!
Templates em Django - Django4FrontEnd
Templates em Django - Django4FrontEnd
fonte: Django Project
https://docs.djangoproject.com/en/1.10/topics/performance/
# QuerySet operation on the database
# fast, because that's what databases are good at
my_bicycles.count()
# counting Python objects
# slower, because it requires a database query anyway, and processing
# of the Python objects
len(my_bicycles)
# Django template filter
# slower still, because it will have to count them in Python anyway,
# and because of template language overheads
{{ my_bicycles|length }}
Templates em Django - Django4FrontEnd
fonte: https://docs.djangoproject.com/en/1.7/topics/templates/
Too much?
Templates em Django - Django4FrontEnd
fonte: Django Best Practices
Templates em Django - Django4FrontEnd
fonte: Cached Templates (official django documentation)
TEMPLATES = [{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'OPTIONS': {
'loaders': [
('django.template.loaders.cached.Loader', [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
]),
],
},
}]
Templates em Django - Django4FrontEnd
{% load cache %}
{% cache 500 sidebar %}
{% comment %}
parametro 1 - longevidade da cache (s)
parametro 2 - nome opcional
{% endcomment %}
<section>
<p>{{request.user.username}}</p>
...
</section>
{% endcache %}
fonte: Django Project
Templates em Django - Django4FrontEnd
fonte: Django Project
{% load cache %}
{% cache 500 sidebar request.user.username %}
{% comment %}
Vou ter uma versao CACHE diferente
para CADA utilizador (request.user.username)
{% endcomment %}
{% endcache %}