Platzi
Platzi

¡Invierte en ti y celebremos! Adquiere un plan Expert o Expert+ a precio especial.

Antes: $349
$259
Currency
Antes: $349
Ahorras: $90
COMIENZA AHORA
Termina en: 17D : 21H : 4M : 5S

Debes tener cuenta en Platzi

Para ver esta clase abierta debes iniciar sesión

Renderizado de vistas - Layout y template del home7/35

En Hapi podemos usar la arquitectura MVC (Modelo-Vista-Controlador) para organizar la lógica de nuestras aplicaciones. Para implementar el uso de vistas es necesario instalar el plugin Vision y configurarlo de la siguiente manera:

server.views({
  engines: { // --- hapi puede usar diferentes engines
    hbs: handlebars // --- asociamos el plugin al tipo de archivos  
  },
  relativeTo: __dirname, // --- para que las vistas las busque fuera de /public
  path: 'views', // --- directorio donde colocaremos las vistas dentro de nuestro proyecto
  layout: true, // --- indica que usaremos layouts 
  layoutPath: 'views' // --- ubicación de los layouts
})

Al crear el archivo layout.hbs evitaremos repetir las mismas secciones de html en cada una de las vistas, remplazando sólo lo relativo al contenido que cambiará según las rutas definidas en nuestra aplicación.

En la definición de las rutas, tendremos que cambiar la respuesta devuelta en handler para que invoque a h.view() en lugar de h.file(), con los parámetros esperados por el layout.

Para poder incorporar el html de las vistas dentro del layout.hbs, es necesario usar triples llaves en lugar de dobles, ya que por defecto Handlebars escapa el código html convirtiéndolo en su equivalente texto plano.

En la configuración de Handlebars, la propiedad layoutPath estaba escrita como ‘view’ … ya luego fue corregida como ‘views’, puesto que se refieren al mismo directorio indicado en path.

Mi aporte en código

'use strict'

// Requerir el modulo de hapi (Framework)
const Hapi = require('@hapi/hapi')
// Requerir el plugin de hapi para servir archivos estaticos
const inert = require('@hapi/inert')
// Requerir el plugin de hapi para gestionar el motor de plantillas
const vision = require('@hapi/vision')
const path = require('path')

// Configurar el servidor de nuestra aplicación. En un contenedor (Docker) si marca error colocar 0.0.0.0 (todos)
const server = Hapi.server({
  port: process.env.PORT || 3000,
  host: 'localhost',
  // Definir propiedades generales para todas las rutas. (En este caso indico que las rutas que requieran archivos estáticos, se servirán desde la carpeta public)
  routes: {
    files: {
      relativeTo: path.join(__dirname, 'public')
    }
  }

})

// Definicion de función para inicializar el proyecto. Intenamnete hay tareas asincronas
async function init() {

  try {
    // Registrar los plugins que hapi va a necesitar (en este caso servir archivos estaticos)
    await server.register(inert)
    // Registrar plugin para gestionar el motor de plantillas
    await server.register(vision)

    // Configurar nuestro motor de plantillas. Usará handlebars y cuando invoquemos una vista automáticamente buscará una con extensión hbs (no hace falta especificarlo). Debe buscar a partir del directorio actual, las vistas se encuentran en views y se activa compatibilidad con layouts, los cuales se encuentran en layouts
    server.views({
      engines: {
        hbs: require('handlebars')
      },
      relativeTo: __dirname,
      path: 'views',
      layout: true,
      layoutPath: 'layouts'
    })

    // Definición de rutas (indicar el método HTTP, URL y controlador de ruta)
    // Se declaran después del plugin ya que las rutas hacen uso del misom para devolver archivos estáticos
    server.route({
      method: 'GET',
      path: '/',
      handler: (req, h) => {
        // El plugin de vision inyecta el metodo view al objeto h para renderizar una vista con el motor de plantillas configurado en la aplicación
        return h.view('index', {
          title: 'Home'
        })
      }
    })

    // Ruta para servir archivos estáticos asociados (img/css/js)
    server.route({
      method: 'GET',
      path: '/{param*}',
      handler: {
        directory: {
          path: '.',
          redirectToSlash: true
        }
      }
    })

    // Arrancar el servidor de Hapi
    await server.start()
    console.log(`Servidor lanzado en: ${server.info.uri}`)
  } catch (error) {
    console.error(error)
    // Salir de nodeJS con un código de error (1), 0 es un código de exito
    process.exit(1)
  }
}

// Inicializar el proyecto
init();

No entendí muy bien la función que tiene layoutPath.
El profesor menciona que esta propiedad nos va a permitir poner los layouts junto con las vistas.
Pero no entiendo muy bien a qué se refiere. ¿alguien podría ayudarme?

En layout.hbs, como es que es {{{content}}} “conecta” por asi decirlo con index.hbs?

Ojo con Hapi, ah movido todos sus plugins a otra ruta de instalación.
Recomiendo revisar la documentación.

const hapi = require('@hapi/hapi')
const inert = require('@hapi/inert')
const vision = require('@hapi/vision')

Esta un poco jodido esto jaja

La variable ‘content’ en donde la define para que se renderize

lo veo un poco enredado ,
¯\_(ツ)_/¯

Ahora es:

npm i @hapi/vision
'use strict'
const hapi = require('@hapi/hapi')
const inert = require('@hapi/inert')
const vision = require('@hapi/vision')
const path = require('path')
const handlebars = require('handlebars')

const server = hapi.Server({
    port: process.env.PORT || 3000,
    host: 'localhost',
    routes: {
        files: {
            relativeTo: path.join(__dirname, 'public')
        }
    }
})

const initRoutes = async () =>{
    server.route({
        method: 'GET',
        path: '/',
        handler: (req, h) => {
            return h.view('index', {
                title: 'home'
            })
        }
    })

    server.route({
        method: 'GET',
        path: '/{param*}',
        handler: {
            directory: {
                path: '.',
                index: ['index.html']
            }
        }
    })
}

const initViews = async ()=>{
    server.views({
        engines: {
          hbs: handlebars
        },
        relativeTo: __dirname,
        path: 'views',
        layout: true,
        layoutPath: 'views'
    })
}

const main = async () =>{
    try {
        await server.register(inert)
        await server.register(vision)
        await server.start()
        await initRoutes()
        await initViews()

    } catch {
        console.error(error)
        console.exit(1)
    }finally{
        console.log(`Servidor lanzado en ${server.info.uri}`)
    }
}

main()

La manera actual de instalar vision

npm i @hapi/hapi

y si usas yarn

yarn add @hapi/hapi

En la configuración de Handlebars, la propiedad layoutPath estaba escrita como ‘view’ … ya luego fue corregida como ‘views’, puesto que se refieren al mismo directorio indicado en path.

Mi aporte en código

'use strict'

// Requerir el modulo de hapi (Framework)
const Hapi = require('@hapi/hapi')
// Requerir el plugin de hapi para servir archivos estaticos
const inert = require('@hapi/inert')
// Requerir el plugin de hapi para gestionar el motor de plantillas
const vision = require('@hapi/vision')
const path = require('path')

// Configurar el servidor de nuestra aplicación. En un contenedor (Docker) si marca error colocar 0.0.0.0 (todos)
const server = Hapi.server({
  port: process.env.PORT || 3000,
  host: 'localhost',
  // Definir propiedades generales para todas las rutas. (En este caso indico que las rutas que requieran archivos estáticos, se servirán desde la carpeta public)
  routes: {
    files: {
      relativeTo: path.join(__dirname, 'public')
    }
  }

})

// Definicion de función para inicializar el proyecto. Intenamnete hay tareas asincronas
async function init() {

  try {
    // Registrar los plugins que hapi va a necesitar (en este caso servir archivos estaticos)
    await server.register(inert)
    // Registrar plugin para gestionar el motor de plantillas
    await server.register(vision)

    // Configurar nuestro motor de plantillas. Usará handlebars y cuando invoquemos una vista automáticamente buscará una con extensión hbs (no hace falta especificarlo). Debe buscar a partir del directorio actual, las vistas se encuentran en views y se activa compatibilidad con layouts, los cuales se encuentran en layouts
    server.views({
      engines: {
        hbs: require('handlebars')
      },
      relativeTo: __dirname,
      path: 'views',
      layout: true,
      layoutPath: 'layouts'
    })

    // Definición de rutas (indicar el método HTTP, URL y controlador de ruta)
    // Se declaran después del plugin ya que las rutas hacen uso del misom para devolver archivos estáticos
    server.route({
      method: 'GET',
      path: '/',
      handler: (req, h) => {
        // El plugin de vision inyecta el metodo view al objeto h para renderizar una vista con el motor de plantillas configurado en la aplicación
        return h.view('index', {
          title: 'Home'
        })
      }
    })

    // Ruta para servir archivos estáticos asociados (img/css/js)
    server.route({
      method: 'GET',
      path: '/{param*}',
      handler: {
        directory: {
          path: '.',
          redirectToSlash: true
        }
      }
    })

    // Arrancar el servidor de Hapi
    await server.start()
    console.log(`Servidor lanzado en: ${server.info.uri}`)
  } catch (error) {
    console.error(error)
    // Salir de nodeJS con un código de error (1), 0 es un código de exito
    process.exit(1)
  }
}

// Inicializar el proyecto
init();

No entendí muy bien la función que tiene layoutPath.
El profesor menciona que esta propiedad nos va a permitir poner los layouts junto con las vistas.
Pero no entiendo muy bien a qué se refiere. ¿alguien podría ayudarme?

En layout.hbs, como es que es {{{content}}} “conecta” por asi decirlo con index.hbs?

Ojo con Hapi, ah movido todos sus plugins a otra ruta de instalación.
Recomiendo revisar la documentación.

const hapi = require('@hapi/hapi')
const inert = require('@hapi/inert')
const vision = require('@hapi/vision')

Esta un poco jodido esto jaja

La variable ‘content’ en donde la define para que se renderize

lo veo un poco enredado ,
¯\_(ツ)_/¯

Ahora es:

npm i @hapi/vision
'use strict'
const hapi = require('@hapi/hapi')
const inert = require('@hapi/inert')
const vision = require('@hapi/vision')
const path = require('path')
const handlebars = require('handlebars')

const server = hapi.Server({
    port: process.env.PORT || 3000,
    host: 'localhost',
    routes: {
        files: {
            relativeTo: path.join(__dirname, 'public')
        }
    }
})

const initRoutes = async () =>{
    server.route({
        method: 'GET',
        path: '/',
        handler: (req, h) => {
            return h.view('index', {
                title: 'home'
            })
        }
    })

    server.route({
        method: 'GET',
        path: '/{param*}',
        handler: {
            directory: {
                path: '.',
                index: ['index.html']
            }
        }
    })
}

const initViews = async ()=>{
    server.views({
        engines: {
          hbs: handlebars
        },
        relativeTo: __dirname,
        path: 'views',
        layout: true,
        layoutPath: 'views'
    })
}

const main = async () =>{
    try {
        await server.register(inert)
        await server.register(vision)
        await server.start()
        await initRoutes()
        await initViews()

    } catch {
        console.error(error)
        console.exit(1)
    }finally{
        console.log(`Servidor lanzado en ${server.info.uri}`)
    }
}

main()

La manera actual de instalar vision

npm i @hapi/hapi

y si usas yarn

yarn add @hapi/hapi