Compartir a través de


Paso 3: Atender archivos estáticos, agregar páginas y usar la herencia de plantilla con la aplicación Flask

Paso anterior: Crear una aplicación de Flask con vistas y plantillas de página

En los pasos anteriores de este tutorial, ha aprendido a crear una aplicación de Flask mínima con una sola página HTML independiente. Las aplicaciones web modernas normalmente están formadas por muchas páginas y usan recursos compartidos, como archivos CSS y JavaScript, para proporcionar un comportamiento y un estilo uniformes.

En este paso aprenderá lo siguiente:

  • Usar plantillas de elementos de Visual Studio para agregar rápidamente nuevos archivos de distintos tipos con práctico código reutilizable (paso 3.1)
  • Atender archivos estáticos desde el código (paso 3-2, opcional)
  • Agregar páginas adicionales a la aplicación (paso 3.3)
  • Usar la herencia de plantilla para crear un encabezado y una barra de navegación que se use en varias páginas (paso 3.4)

Paso 3.1: Familiarizarse con las plantillas de elemento

A medida que desarrolle una aplicación de Flask, lo normal es que vaya agregando muchos más archivos Python, HTML, CSS y JavaScript. Para cada tipo de archivo (y otros archivos como web.config que pueda necesitar para la implementación), Visual Studio ofrece prácticas plantillas de elemento como punto de partida.

Para ver las plantillas disponibles, vaya al Explorador de soluciones, haga clic con el botón derecho en la carpeta en la que desee crear el elemento y seleccione Agregar>Nuevo elemento:

Add new item dialog in Visual Studio

Para usar una plantilla, seleccione la plantilla deseada, especifique un nombre para el archivo y seleccione Aceptar. La adición de un elemento de este modo agrega automáticamente el archivo al proyecto de Visual Studio y marca los cambios para el control de código fuente.

Pregunta: ¿Cómo sabe Visual Studio qué plantillas de elemento debe ofrecer?

Respuesta: El archivo de proyecto de Visual Studio (.pyproj) contiene un identificador de tipo de proyecto que lo marca como un proyecto de Python. Visual Studio utiliza este identificador de tipo para mostrar solo aquellas plantillas de elementos que sean adecuadas para el tipo de proyecto. De esta manera, Visual Studio puede proporcionar un amplio conjunto de plantillas de elemento para muchos tipos de proyecto sin pedirle que los ordene cada vez.

Paso 3.2: Atender archivos estáticos desde la aplicación

En una aplicación web compilada con Python (con cualquier plataforma), los archivos de Python siempre se ejecutan en el servidor del host web y nunca se transmiten al equipo de un usuario. Otros archivos, como CSS y JavaScript, se usan exclusivamente por el explorador, por lo que el servidor host simplemente los ofrece tal cual cada vez que se solicitan. Estos archivos se denominan archivos "estáticos", y Flask puede distribuirlos automáticamente sin tener que escribir ningún código. En los archivos HTML, por ejemplo, puede hacer referencia a archivos estáticos con una ruta relativa en el proyecto. En la primera sección de este paso se agrega un archivo CSS a la plantilla de página existente.

Cuando necesite proporcionar un archivo estático desde el código, por ejemplo, mediante una implementación de punto de conexión de API, Flask ofrece un cómodo método con el que hacer referencia a archivos mediante rutas de acceso relativas dentro de una carpeta denominada static (en la raíz del proyecto). En la segunda sección de este paso se muestra ese método usando un archivo de datos estático simple.

En cualquier caso, puede organizar los archivos en static como quiera.

Usar un archivo estático en una plantilla

  1. En el Explorador de soluciones, haga clic con el botón derecho en la carpeta HelloFlask en el proyecto de Visual Studio, seleccione Agregar>Nueva carpeta y asigne a la carpeta el nombre static.

  2. Haga clic con el botón derecho en la carpeta static y seleccione Agregar>Nuevo elemento. En el cuadro de diálogo que aparece, seleccione la plantilla Hoja de estilo, ponga al archivo el nombre site.css y haga clic en Aceptar. El archivo site.css aparece en el proyecto y se abre en el editor. La estructura de carpetas debería ser similar a la de la imagen siguiente:

    Static file structure as shown in Solution Explorer

  3. Reemplace el contenido de site.css por el código siguiente y guarde el archivo:

    .message {
        font-weight: 600;
        color: blue;
    }
    
  4. Reemplace el contenido del archivo templates/index.html de la aplicación por el código siguiente, que reemplaza el elemento <strong> usado en el paso 2 por un <span> que hace referencia a la clase de estilo message. El uso de una clase de estilo de este modo ofrece mucha más flexibilidad al aplicar estilo al elemento.

    <html>
        <head>
            <title>{{ title }}</title>
            <link rel="stylesheet" type="text/css" href="/static/site.css" />
        </head>
        <body>
            <span class="message">{{ message }}</span>{{ content }}
        </body>
    </html>
    
  5. Ejecute el proyecto y observe los resultados. Cuando haya terminado, detenga el servidor y confirme los cambios en el control de código fuente (como se ha explicado en el paso 2).

Atender un archivo estático desde el código

Flask proporciona una función denominada serve_static_file a la que puede llamar desde el código para hacer referencia a cualquier archivo de la carpeta static del proyecto. El siguiente proceso crea un punto de conexión de API simple que devuelve un archivo de datos estáticos.

  1. Si aún no lo ha hecho, cree una carpeta static: en el Explorador de soluciones, haga clic con el botón derecho en la carpeta HelloFlask del proyecto de Visual Studio, seleccione Agregar>Nueva carpeta y asigne a la carpeta el nombre static.

  2. En la carpeta static, cree un archivo de datos JSON estático denominado data.json con el siguiente contenido (que son datos de ejemplo carentes de significado):

    {
        "01": {
            "note" : "Data is very simple because we're demonstrating only the mechanism."
        }
    }
    
  3. En views.py, agregue una función con la ruta /api/data que devuelva el archivo de datos estático mediante el método send_static_file:

    @app.route('/api/data')
    def get_data():
      return app.send_static_file('data.json')
    
  4. Ejecute la aplicación y vaya al punto de conexión /api/data para comprobar que se ha devuelto el archivo estático. Cuando haya terminado, detenga la aplicación.

Pregunta: Estoy utilizando un certificado X.509 con mi servicio y obtengo un System.Security.Cryptography.CryptographicException. ¿Hay alguna convención para organizar los archivos estáticos?

Respuesta: Puede agregar otros archivos HTML, CSS y JavaScript a la carpeta static como quiera. Una forma habitual de organizar los archivos estáticos es crear subcarpetas denominadas fonts, scripts y content (para las hojas de estilos y cualquier otro archivo).

Pregunta: ¿Cómo gestiono las variables de dirección URL y los parámetros de consulta en una API?

Respuesta: Vea la respuesta en el paso 1-4 de la Pregunta: ¿Cómo trabaja Flask con las rutas de dirección URL de variables y con los parámetros de consulta?

Paso 3.3: Agregar una página a la aplicación

La adición de otra página a la aplicación implica lo siguiente:

  • Agregar una función de Python que define la vista.
  • Agregar una plantilla para el marcado de la página.
  • Agregar el enrutamiento necesario al archivo urls.py del proyecto de Flask.

Los pasos siguientes agregan una página de información al proyecto de "HelloFlask" y los vínculos a esta página desde la página principal:

  1. En el Explorador de soluciones, haga clic con el botón derecho en la carpeta templates, seleccione Agregar>Nuevo elemento, seleccione la plantilla de elemento Página HTML, ponga al archivo el nombre about.html y haga clic en Aceptar.

    Sugerencia

    Si el comando Nuevo elemento no aparece en el menú Agregar, asegúrese de que ha detenido la aplicación para que Visual Studio salga del modo de depuración.

  2. Reemplace el contenido de about.html por el siguiente marcado (reemplace el vínculo explícito a la página principal por una barra de navegación sencilla en el paso 3-4):

    <html>
        <head>
            <title>{{ title }}</title>
            <link rel="stylesheet" type="text/css" href="/static/site.css" />
        </head>
        <body>
            <div><a href="home">Home</a></div>
            {{ content }}
        </body>
    </html>
    
  3. Abra el archivo views.py de la aplicación y agregue una función denominada about que use la plantilla:

    @app.route('/about')
    def about():
        return render_template(
            "about.html",
            title = "About HelloFlask",
            content = "Example app page for Flask.")
    
  4. Abra el archivo templates/index.html y agregue la siguiente línea dentro del elemento <body> que se va a vincular a la página Acerca de (de nuevo, reemplace este vínculo por una barra de navegación en el paso 3-4):

    <div><a href="about">About</a></div>
    
  5. Guarde todos los archivos con el comando de menú Archivo>Guardar todo o presione Ctrl+Mayús+S. (Este paso no es necesario, ya que la ejecución del proyecto en Visual Studio guarda los archivos automáticamente. No obstante, está bien conocer el comando).

  6. Ejecute el proyecto para observar los resultados y compruebe la navegación entre las páginas. Detenga la aplicación cuando haya finalizado.

Pregunta: ¿Importa en Flask el nombre de una función de página?

Respuesta: No, porque es el decorador @app.route el que determina las direcciones URL para las que Flask llama a la función para generar una respuesta. Los desarrolladores suelen hacer coincidir el nombre de la función con la ruta, aunque no es algo obligatorio.

Paso 3.4: Usar la herencia de plantilla para crear un encabezado y una barra de navegación

En lugar de tener vínculos de navegación explícitos en cada página, las aplicaciones web modernas suelen utilizan un encabezado de personalización de marca y una barra de navegación que proporciona los vínculos de página, los menús emergentes, etc. más importantes. Para asegurarse de que la aplicación es coherente, el encabezado y la barra de navegación deben ser los mismos en todas las páginas, sin repetir el mismo código en cada plantilla de página. Es preferible definir los elementos comunes de todas las páginas en un solo lugar.

El sistema de plantillas de Flask (Jinja de forma predeterminada) ofrece dos formas de reutilizar elementos específicos a través de varias plantillas: la inclusión y la herencia.

  • La inclusión son otras plantillas de página que se insertan en una ubicación específica de la plantillas de referencia mediante la sintaxis {% include <template_path> %}. También puede utilizar una variable si desea cambiar la ruta de acceso dinámicamente en el código. La inclusión se utiliza normalmente en el cuerpo de una página para incorporar la plantilla compartida en una ubicación específica de la página.

  • La herencia utiliza {% extends <template_path> %} al principio de una plantilla de página para especificar una plantilla base compartida sobre la que construye a continuación la plantilla de referencia. La herencia se suele usar para definir un diseño, una barra de navegación y otras estructuras que se comparten entre las páginas de una aplicación, de manera que las plantillas de referencia solo tengan que agregar o modificar áreas específicas de la plantilla base denominadas bloques.

En ambos casos, <template_path> se refiere a la carpeta templates de la aplicación (../ o ./ también son válidos).

Una plantilla base delimita los bloques mediante las etiquetas {% block <block_name> %} y {% endblock %}. Si una plantilla de referencia utiliza etiquetas con el mismo nombre de bloque, su contenido de bloque reemplaza al de la plantilla base.

Los pasos siguientes muestran la herencia:

  1. En la carpeta templates de la aplicación, cree un nuevo archivo HTML (con el menú contextual Agregar>Nuevo elemento o Agregar>Página HTML) denominado layout.html y reemplace su contenido por el siguiente marcado. Puede ver que esta plantilla contiene un bloque denominado "content" que es todo lo que tienen que reemplazar las páginas de referencia:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title>{{ title }}</title>
        <link rel="stylesheet" type="text/css" href="/static/site.css" />
    </head>
    
    <body>
        <div class="navbar">
            <a href="/" class="navbar-brand">Hello Flask</a>
            <a href="{{ url_for('home') }}" class="navbar-item">Home</a>
            <a href="{{ url_for('about') }}" class="navbar-item">About</a>
        </div>
    
        <div class="body-content">
            {% block content %}
            {% endblock %}
            <hr/>
            <footer>
                <p>&copy; 2018</p>
            </footer>
        </div>
    </body>
    </html>
    
  2. Agregue los estilos siguientes al archivo static/site.css de la aplicación (en este tutorial no se muestra un diseño con capacidad de respuesta. Pero, estos estilos solo generan un resultado interesante):

    .navbar {
        background-color: lightslategray;
        font-size: 1em;
        font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
        color: white;
        padding: 8px 5px 8px 5px;
    }
    
    .navbar a {
        text-decoration: none;
        color: inherit;
    }
    
    .navbar-brand {
        font-size: 1.2em;
        font-weight: 600;
    }
    
    .navbar-item {
        font-variant: small-caps;
        margin-left: 30px;
    }
    
    .body-content {
        padding: 5px;
        font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    
  3. Modifique templates/index.html para hacer referencia a la plantilla base y reemplace el bloque de contenido. Puede ver que, mediante la herencia, esta plantilla se simplifica:

    {% extends "layout.html" %}
    {% block content %}
    <span class="message">{{ message }}</span>{{ content }}
    {% endblock %}
    
  4. Modifique templates/about.html para hacer también referencia a la plantilla base y reemplace el bloque de contenido:

    {% extends "layout.html" %}
    {% block content %}
    {{ content }}
    {% endblock %}
    
  5. Ejecute el servidor para observar los resultados. Cuando haya terminado, cierre el servidor.

    Running app showing the nav bar

  6. Dado que ha efectuado cambios sustanciales en la aplicación, vuelve a ser un buen momento para confirmar los cambios en el control de código fuente.

Pasos siguientes

Puede profundizar más con estos recursos: