A√ļn no tienes acceso a esta clase

Crea una cuenta y contin√ļa viendo este curso

Curso de Flask

Curso de Flask

Bernardo Cassina

Bernardo Cassina

Herencia de templates

11/36
Recursos

Macro: son un conjunto de comandos que se invocan con una palabra clave, opcionalmente seguidas de parámetros que se utilizan como código literal. Los Macros son manejados por el compilador y no por el ejecutable compilado.

Los macros facilitan la actualización y mantenimiento de las aplicaciones debido a que su re-utilización minimiza la cantidad de código escrito necesario para escribir un programa.

En este ejemplo nuestra macro se vería de la siguiente manera:

{% macro nav_link(endpoint, text) %}
    {% if request.endpoint.endswith(endpoint) %}
        <li class="active"><a href="{{ url_for(endpoint) }}">{{text}}a>li>
    {% else %}
        <li><a href="{{ url_for(endpoint) }}">{{text}}a>li>
    {% endif %}
{% endmacro %}

Un ejemplo de uso de macros en Flask:

{% from "macros.html" import nav_link with context %}

<html lang="en">
    <head>
    {% block head %}
        <title>My applicationtitle>
    {% endblock %}
    head>
    <body>
        <ul class="nav-list">
            {{ nav_link('home', 'Home') }}
            {{ nav_link('about', 'About') }}
            {{ nav_link('contact', 'Get in touch') }}
        ul>
    {% block body %}
    {% endblock %}
    body>
html>

Como podemos observar en la primera l√≠nea estamos llamando a macros.html que contiene todos nuestros macros, pero queremos uno en espec√≠fico as√≠ que escribimos import nav_link para traer el macro deseado y lo renderizamos de esta manera en nuestro men√ļ {{ nav_link('home', 'Home') }}.

Aportes 39

Preguntas 8

Ordenar por:

¬ŅQuieres ver m√°s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi√≥n.

Si usan Vs code les recomiendo las extencion Jinja para que les coloree los tags de jinja

explicas bien pero te vas directamente a la practica con un poco de teoría previa se entendería mas rápido y mejor

Si alguno ya le resulto tedioso estar escriiendo {% %} en cada linea que hay que aplicar jinja les recomiendo usar Jinja2 Snipper Kit para VScode ya que es tan facil como,por ejemplo, poner jif+ enter y ya te arma toda la estructura de un if

Herencis de Template: La parte m√°s poderosa de Jinja es la herencia de plantillas. La herencia de plantillas le permite crear una plantilla de ‚Äúesqueleto‚ÄĚ de base que contiene todos los elementos comunes de su sitio y define los bloques que las plantillas secundarias pueden anular.

les comparto el codigo de la clase:

hello.html

{% extends 'base.html' %}
{% import 'macros.html' as macros %}

{% block title %} 
    {{ super() }}
    Bienvenido 
{% endblock %}

{% block content %}
    {% if user_ip %}
    <h1>
        Hello, tu ip es {{ user_ip }}
    </h1>
    {% else %}
        <a href="{{ url_for('index') }}">ir a inicio</a>
    {% endif %}

    <ul>
        {% for todo in todos %}
            {{ macros.render_todo(todo) }}
        {% endfor %}
    </ul>
{% endblock %}

base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>
        {% block title %}Flask Platzi |{% endblock %}
    </title>
</head>
<body>
    {% block content %}
    {% endblock %}    
</body>
</html>

macros.html

{% macro render_todo(todo) %}
    <li> Descripción: {{ todo }} </li>
{% endmacro %}

main.py

from flask import Flask, request,make_response, redirect, render_template

app = Flask(__name__)

todos = ['Comprar Cafe', 'Enviar Solicitud de compra', 'Entregar video a productor']
@app.route('/')
def index():
    user_ip = request.remote_addr

    response = make_response(redirect('/hello'))
    response.set_cookie('user_ip', user_ip)

    return response


@app.route('/hello')
def hello():

    user_ip = request.cookies.get('user_ip')
    context = {
        'user_ip': user_ip,
        'todos': todos
    }

    return render_template('hello.html',**context)

Excelente, me siento tan cómodo como con laravel, y creo que flask es mucho mas rápido jiji!!

El profe diciendo la palabra ‚Äúmacros‚ÄĚ.
Yo, simple mortal que empezó en esto con excel: Recuerdos de Vietnam vienen a mí

Si desean hacer una pagina donde puedan establecer el titulo de manera dinamica, hagan lo siguiente:

@app.route("/hello")
def hello():
    user_ip = request.cookies.get("user_ip")
    context = {"user_ip": user_ip, "todos": todos, "title": "Hello"}

    """
    Aqui expandimos el dicionario context para poder
    acceder a sus varibles sin la necesidad de hacer
    uso de 'content.the_thing_you_wanna_call'
    """
    return render_template("hello.html", **context)
 <!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	{% if title %}
	<title>Flask | {{ title }}</title>
	{% else %}
	<title>Flask | Bienvenido</title>
	{% endif %}
</head>
<body>
	{% block content %}{% endblock %}
</body>
</html>

Excelente, utilizo Visual Studio Code y todo el texto tenia el mismo formato, instale la extensión jinja para visualizar el texto con colores y un mejor formato. Se los recomiendo.

listo sin errores , cosa extra√Īa por que siempre tengo errores :'c

¬°Hola Comunidad!
.
Copio la forma de c√≥mo podemos aplicar estilos a nuestra plantilla ya que es una de las cosas que se necesitar√°n si o si al momento de hacer una p√°gina web, seguro este punto se toca en alg√ļn video posterior, pero nunca est√° de m√°s leer algo antes.
.
Primero debemos saber que todos los archivos p√ļblicos, es decir aquellos que no ser√°n procesados como las plantillas que est√°n en /templates o los archivos de extensi√≥n .py, deber√°n colocarse en una carpeta de nombre static. El motor de templates de Jinja2 reconoce de forma predeterminada la carpeta static (al igual que lo hace con templates) para extraer de all√≠ los archivos complementarios.
.
Dicho esto. Actualicemos los estilos de nuestro ejemplo:
.
Creamos la carpeta static dentro de nuestra carpeta de proyecto. Deberíamos terminar con algo así:
.

.
Una vez creada la carpeta, podemos colocar ene lla nuestro archivo CSS, sin embargo yo colocaré otra carpeta de nombre css, de tal manera que mi archivo style.css estará en una ruta similar a esta: C:\tu_ruta\python\flask\static\css\style.css.
.
Para este ejemplo quisiera modificar, de manera simple, los colores del listado que cargamos en la vista hello. Así que escribiré unos estilos básicos en style.css:

ul li {
	color: red;
	text-decoration: underline;
}

Luego, asociar√© este archivo CSS con nuestra plantilla base.html ¬ŅPor qu√© a base.html y no a las dem√°s? Porque depende, en mi caso considero que este CSS se aplicar√° a todas mis plantillas, la mayor√≠a de veces es as√≠.
.
Para poder hacer la asociación escribimos lo siguiente en base.html, entre las etiquetas head:

<head>
	<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>

Nota que en mi ejemplo yo solo estoy colocando mi línea de código, obviamente tenemos más código allí, pero creo que se entiende.
.
Con esto ya deberíamos poder abrir nuestro navegador y ver los cambios aplicados. Deberíamos ver algo así:

Bueno, es un ejemplo muy sencillo ūüôā, seguramente hay diferentes maneras de hacerlo. Si conoces otra comp√°rtela y as√≠ aprendemos algo m√°s. Aqu√≠ est√° el enlace a la documentaci√≥n d√≥nde puedes indagar m√°s.
.
Espero les sirva.
.
¬°Saludos!

Python Template Snippets es una extension que te ayuda a no tener que escribir toda la sentencia {{ % … % }} también tiene soporte para django

Aquí los principales shortcuts

que significa renderear?

Cuando creamos una p√°gina web es una pr√°ctica com√ļn crear una estructura de la p√°gina que ser√° compartida por todas las vistas del sistema. Esta estructura generalmente incluye la cabecera y el pie de la p√°gina. La herencia de templates nos permite la creaci√≥n de templates padres que podr√°n ser heredados por cada vista particular.

Esta herencia se logra a trav√©s de la creaci√≥n de bloques. Los bloques de Jinja2 tienen un nombre √ļnico designado y pueden o no tener contenido. Al crear un template hijo e indicar la herencia los bloques definidos ocuparan el espacio asignado a dicho bloque en el template padre.

Se define el comienzo de un bloque con la palabra block seguida de su nombre y se indica su final con la palabra endblock.

<!DOCTYPE html>
<html lang="es">
  <head>
      <meta charset="UTF-8">
      {% block head %}
      <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
      <title>Titulo</title>
      {% endblock %}
  </head>
  <body>

{% block menu %}
<nav class="navbar navbar-expand-md navbar-dark bg-dark navbar-fixed-top">
  <a class="navbar-brand" href="#">Título</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarSupportedContent">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Enlace</a>
      </li>
    </ul>
  </div>

  <div class="navbar-collapse collapse w-100 order-3 dual-collapse2">
       <ul class="navbar-nav ml-auto">
         <li class="nav-item">
           {% if nombre != "" %}
             <span class="navbar-text">Hola {{nombre}}</span>
           {% else %}
             <a class="btn btn-info">Iniciar sesion</a>
           {% endif %}
         </li>
       </ul>
   </div>
</nav>
{% endblock %}
  <br/>
  {% block contenido %}
  {% endblock %}
  <br/>

  {% block pie %}
  <footer class="footer">
    <div class="container-fluid text-center text-md-left">
      <div class="row">
        <div class="col-md-2"></div>
        <div class="col-md-2">
            <ul>
              <li>
                <a href="#">Enlace 1</a>
              </li>
              <li>
                <a href="#">Enlace 2</a>
              </li>
              <li>
                <a href="#">Enlace 3</a>
              </li>
              <li>
                <a href="#">Enlace 4</a>
              </li>
          </ul>
        </div>
        <div class="col-md-6">
            <p>Aenean purus mi, laoreet et aliquam quis, imperdiet non risus. Nulla id luctus enim, convallis laoreet urna. Curabitur iaculis dictum ante, eget sodales massa elementum quis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed tempor facilisis nisi at commodo.</p>
        </div>

        <div class="col-md-2"></div>
      </div>
    </div>
  </footer>
 {% endblock %}

En este template se encuentran definidos los siguientes bloques:

head: Contiene los enlaces a hojas de estilos, js, etc
men√ļ: Contiene el men√ļ de navegaci√≥n
contenido: Bloque vacío
pie: Contiene el pie de la p√°gina

Al crear un template hijo es necesario especificar el template del cual hereda utilizando la sentencia extends seguida del nombre del archivo padre. Luego es posible definir el contenido de cada bloque pudiendo :

Heredar el contenido del padre sin modificarlo
Heredar el contenido pero permitir el agregado de contenido propio del hijo a través de la función super
Generar contenido nuevo a partir de los bloques vacíos en el template padre.
{% extends 'main.html'%}  {# Herencia #}
{% block head %}
    {{ super() }} {# Heredar el contenido del bloque padre #}
    <link rel="stylesheet" href="{{url_for('.static', filename='css/style.css')}}"> {# Nuevo contenido del bloque #}
{% endblock %}

{% block contenido %}
<div class="container">
  <div class="row">
    <div class="col-md-12">
        <h2>{{subtitulo}}</h2>
    </div>
  </div>
  <div class="row">
    <div class="col-md-4">
      <img src="https://via.placeholder.com/330x250">
    </div>
    <div class="col-md-5">
      <p>{{texto}}</p>
    </div>
    <div class="col-md-3">
      <ul class="list-group">
      {% for valor in lista %}
        <li class="list-group-item"> {{ valor }}</li>
      {% endfor %}
      </ul>
      <a href="#" class="btn btn-primary btn-block btn-lg">${{precio}}</a>
    </div>
  </div>
</div>
{% endblock %}

Qué sucede con la herencia de los diferentes bloques en el template hijo:

head: Al utilizar la función super se hereda el contenido del template padre pero permite agregar contenido nuevo
men√ļ: Al no hacer referencia a este bloque se hereda directamente del template padre
contenido: El template hijo genera todo el contenido
pie: Al no hacer referencia a este bloque se hereda directamente del template padre

Excelente clase, super pr√°ctica.

  • Para extender un template tenemos que hacer uso de {{ extends base.html }}
  • Para agregar un bloque de c√≥digo de python en html hacemos uso de {% block nameblock %}contenido{% endblock %}
  • Si se quiere concatenar el contenido html con el contenido en python se debe de agregar {{ super() }}, para que extienda el contenido html al contenido en python.
  • Los macros son peque√Īos pedazos que c√≥digo, que se usaran a lo largo del proyecto, son como funciones. Para ello hacemos uso de {% macro nombremacro(parametro) %} contenido {{ parametro}} {% endmacro %}
  • Para importar un macro hacemos uso de {% import archivomacro as variable %}

Veamos:

Para llegar a este curso es necesario entender varios paradigmas de programación:

Estructurada
Orientada a Objetos
y de ese mundo de los macros que inclusive sin el background justificado es criticado desde los lenguajes que los implementaron y que nos permit√≠an una programaci√≥n donde la metodolog√≠a de sustituci√≥n de macros era la base para construir sistemas ampliamente parametrizables hace mas de 20 a√Īos

El problema de no entender es que primero te mercadearon la idea que aprender a programar se hace en unas horas y que no necesitas mas nada para continuar…

<Lifelong Learning..!>

Excelente clase, hoy aprendí conceptos nuevos para html como los macros y las herencias de templates. Uff cuanto potencial con sencillos pedazos de código!

util herencia de templates para cuando el proyecto se haga m√°s grande

¬ŅComo se indentan varias lineas de forma autom√°tica? ūüėģ

Si usan VSCode, les recomiendo desactivar el FormatOnSave de los archivos HTML que estén trabajando para los templates de Jinja2, o cambiar la extensión del archivo a Jinja, aunque se pierdan los snipets. A veces es menos molesto a que, de forma constante, te esté reacomodando los bloques de control e iteraciones.

Un typo me llevó ya un buen rato, pero me forzó también a entender más la lógica de cómo se va armando la aplicación.

Yo uso ‚Äėinclude‚Äô, cual es la diferencia entre ambos?

entonces utilizaremos varios macros?

Las macros son similares a las funciones en Python. La funci√≥n de las macros es reutilizar el c√≥digo en las plantillas para evitar la redundancia del c√≥digo (una definici√≥n, usos m√ļltiples).

Las plantillas de Flask se pueden heredar. Los elementos repetitivos de la plantilla se extraen y se colocan en la plantilla principal, y la plantilla secundaria se puede reescribir seg√ļn sus propias necesidades.
Por lo general, la parte com√ļn se define en la plantilla principal y la plantilla secundaria se abre definiendo el bloque. La plantilla secundaria hereda de la plantilla principal y realiza cambios, mejorando as√≠ el c√≥digoReutilizaci√≥n„Äā

Utilice el método de copia simple original para probar:
Cree un archivo Python de función de vista:

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/list/')
def course_list():
    return render_template('list.html')

if __name__ == '__main__':
    app.run(debug=True)

Cree el directorio de plantillas, cree index.html y list.html debajo de él, index.html es el siguiente:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Casa</title>
</head>
<body>
    <h1>Esta es la p√°gina principal</h1>
    <ul>
        <li>horario del plan de estudios</li>
        <li>Detalles del curso</li>
        <li>Video tutorial</li>
        <li>sobre nosotros</li>
    </ul>
    <div class="footer">
                 Parte inferior del sitio
    </div>
</body>
</html>

list.html es el siguiente:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>horario del plan de estudios</title>
</head>
<body>
    <h1>Esta es la p√°gina de la lista de cursos</h1>
    <ul>
        <li>Python</li>
        <li>Java</li>
        <li>PHP</li>
        <li>C++</li>
    </ul>
    <div class="footer">
                 Parte inferior del sitio
    </div>
</body>
</html>

macros

Esta documentacion me ayudo bastante para complementar las condicionales, ciclos y herencia de plantillas.
https://unipython.com/flask-plantillas-que-son-y-como-se-usan/

Template padre:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>
        {% block title %} Flask | {% endblock %}
    </title>
</head>
<body>
    {% block content %}
    {% endblock %}
</body>
</html>

Extends: Conectar dos templates e insertar contenido en el bloque correspondiente del template padre.

Import: Importar macros de otro archivo, son similares a las funciones y ayudan a no repetir código.

{% extends 'base.html' %}
{% import 'macros.html' as macros %}

{% block title %} 
    {{ super() }}
    Bienvenido 
{% endblock %}

{% block content %}
    <h1>Hello world template</h1>
    {% if user_ip %}
        <h2>Tu IP es {{ user_ip }}</h2>
    {% else %}
        <a href="{{ url_for('index') }}">Inicio</a>
    {% endif %}

    <ul>
        {% for todo in todos %}
            {{ macros.render_todo(todo) }} # usando el macro
        {% endfor %}
    </ul>
{% endblock %}

Archivo de macros:

{% macro render_todo(todo) %}
    <li>{{ todo }}</li>
{% endmacro %}

Les dejo el <!DOCTYPE html>

`<!DOCTYPE html>
<html lang=‚Äúen‚ÄĚ>
<head>
<meta charset=‚Äúutf-8‚ÄĚ>
<title>JS Bin</title>
</head>
<body>

</body>
</html>`

Los macros son peque√Īos pedazos de c√≥digo que se repite en varias partes de los templates.

Podemos extender de una base html y sobreescribir los bloques que necesitemos, o extenderlos con la base.

Wow, ¬°esto es completamente nuevo!

Todo bien hasta este momento.

Como crear MACROS

Esta super interesante la clase, hay que recordar que si se hace algo pesada siempre se puede volver a tras para revisar y probar codigo

Excelente, gracias

Felicito a Bernardo Cassina porque es un muchacho muy joven y entiende muy bien las bases de distintos paradigmas de programaci√≥n, estos ampliamente usados hace m√°s de unos 25-30 a√Īos y que fue muy bien aprovechado en los sistemas de la √©poca hasta la fecha! Con la sustituci√≥n de macros se implementaron muchas soluciones!

excelente que bonito, esto esta genial

Flask is amazing!