Modelado de contenido con Jekyll
Publicado: 2022-03-10No es exactamente un tema nuevo, pero últimamente he tenido motivos para revisar la habilidad del modelado de contenido en el trabajo de mi equipo. Nuestra experiencia ha llegado a un punto en el que las limitaciones de cómo practicamos empiezan a ser claras. Nuestro problema más común es que las personas tienden a vincularse a sí mismas y a sus modelos mentales a una plataforma elegida y sus convenciones.
En lugar de enseñar a las personas cómo modelar contenido, terminamos enseñándoles cómo modelar contenido en Drupal o cómo modelar contenido en WordPress. Pero preferiría que lo enfoquemos desde un enfoque en los mejores intereses de los usuarios, independientemente de la plataforma en la que termine dicho contenido.
Lectura adicional en SmashingMag:
- Crea un blog con páginas de Jekyll y GitHub
- Por qué los generadores de sitios web estáticos son la próxima gran novedad
- Generadores de sitios web estáticos revisados: Jekyll, Middleman, Roots, Hugo
- Automatización del desarrollo basado en guías de estilo
Esta línea de pensamiento me devolvió a una idea con la que me he obsesionado un poco, que es que cuando tenemos que crear un artefacto para comunicar ciertas ideas a un cliente, el proceso casi siempre va mejor cuando ese artefacto está lo más cerca posible. posible a un sitio web real en lugar de una imagen de un sitio web o un PDF lleno de diagramas.
Por lo tanto, la pregunta que terminé haciéndome: ¿existía una herramienta que pudiera usar para ayudar a las personas a modelar rápidamente el contenido de una manera independiente de la plataforma y, al mismo tiempo, crear un artefacto que fuera ideal para comunicar la intención a un cliente o equipo?
Una teoría de alto nivel del modelado de contenido
Desviémonos un poco antes de entrar en Jekyll. Creo que puede eliminar todas las convenciones y el lenguaje específico de la plataforma de la discusión sobre el modelado de contenido y definirlo como un sistema de tres partes:
- La idea central es la de un objeto : alguna unidad de contenido que se mantiene unida en un sitio. Por ejemplo, una publicación de blog o una persona serían un objeto en un sitio.
- Los objetos tienen atributos que los definen . Una publicación de blog podría tener un título, un cuerpo de contenido, un autor. Una persona podría tener un nombre, una foto, una biografía.
- Los objetos tienen relaciones que determinan dónde terminan en un sitio y los diseños tienen una lógica que define qué atributos de un objeto se usan y dónde. Nuestro objeto de publicación de blog de ejemplo está conectado a un objeto de persona porque su autor es una persona. Enviamos el nombre del autor y un enlace a su perfil en la página de publicación, y enviamos su biografía completa en su página de perfil.
Quería crear un sistema que respetara las ideas de alto nivel que describí, pero que permitiera al equipo la libertad de crear atributos y relaciones como mejor les pareciera sin preocuparse por ideas específicas para ciertas plataformas. En su lugar, podrían centrarse en definir el contenido en función de lo que es mejor para los usuarios . Y resulta que Jekyll tiene las características para hacerlo posible.
Entra Jekyll
Jekyll es un marco de blogs estático. Y antes de dirigirse a la sección de comentarios, sí, soy consciente de que es correcto considerarlo como una plataforma por derecho propio. Sin embargo, tiene algunas ventajas sobre algo como Drupal o WordPress.
Jekyll se toma la simplicidad en serio. No tiene una base de datos, sino que se basa en archivos planos y algunas etiquetas de plantilla de Liquid que generan HTML simple y antiguo. Liquid es limitado, simple y extremadamente legible por humanos. Descubrí que puedo mostrarle a alguien una plantilla construida con algunas etiquetas de Liquid y, siempre que tengan un poco de experiencia con el código front-end, entienden lo que está haciendo la plantilla.
Lo bueno de esto es que no tenemos que mostrarle a nadie cómo ejecutar una base de datos, cómo conectar sus plantillas, cómo configurar el área de administración de su CMS para que funcione con sus plantillas, etc. En cambio, podemos instalar Jekyll y enseñar cómo iniciar un servidor. Si el usuario está en una Mac, existe una excelente posibilidad de que este sea un proceso de dos minutos que solo funcione la primera vez que lo intentemos.
Jekyll tampoco fuerza muchas convenciones al usuario. Tiene la libertad de crear su estructura de archivos preferida y canalización de activos, establecer sus propias relaciones entre archivos y escribir marcas de la forma que más le guste. Las pocas convenciones que posee se reconfiguran fácilmente para adaptarse a su estilo.
Uso de colecciones para crear y contener objetos
Si bien todavía se considera una característica experimental, Jekyll tiene algo llamado colecciones que nos permitirán crear el sistema que estoy describiendo.
Básicamente, crea una carpeta y la nombra según el tipo de objeto que está creando. Luego agrega archivos a esa carpeta, y cada archivo representa un objeto en esa colección. Una vez que tenga objetos, puede crear atributos para ellos usando YAML al comienzo de cada archivo. YAML es una sintaxis que le permite definir pares clave/valor que almacenan información fácilmente.
Lo bueno de este sistema es lo increíblemente simple que es. Todo es legible por humanos y funciona de una manera que es fácil de aprender para un nuevo usuario. En lugar de crear una gran cantidad de documentación sobre cómo alguien debe crear contenido y relaciones en el sistema final, simplemente puede crearlo. Los diseñadores pueden ver cuáles son los objetos y sus atributos para poder planificar su sistema de diseño. Los desarrolladores front-end tienen un sitio web en funcionamiento para diseñar su marcado y CSS.
Debido a que no están obligados a usar un sistema o convención específicos, pueden usar el que prefieran o las convenciones de la plataforma final para el proyecto. Y los desarrolladores de back-end pueden determinar fácilmente la intención del diseñador al transferir plantillas y lógica a cualquier CMS que decidan usar porque ya está escrito para ellos.
Construyamos un sitio simple con objetos y relaciones
Si vamos a probar esta idea, necesitaremos configurar un sitio simple de Jekyll y luego construir nuestros objetos y relaciones. Si desea ver el producto final, puede tomarlo de este repositorio de GitHub. (Nota: tendrá que usar la terminal para algo de esto, pero es un uso bastante básico, lo prometo).
Instalando Jekyll
Si estás en una Mac, esto es bastante fácil. Ruby ya está instalado, solo necesitas instalar Jekyll. Abre la terminal y escribe:
gem install jekyll
Esto instalará la gema Jekyll Ruby y sus dependencias. Una vez que termine de ejecutarse, eso es todo: tienes a Jekyll.
Configuración de su sitio
Ahora necesitamos comenzar un andamio Jekyll. Guardo todos mis proyectos web en una carpeta en mi Mac llamada Sitios , en la carpeta de inicio. Entonces, primero necesito navegar hasta él con:
cd ~/Sites
Luego puedo generar una carpeta con los archivos y la estructura adecuados con este comando:
jekyll new my-new-site
Puede reemplazar "mi-nuevo-sitio" con el nombre que desee para su proyecto. Lo que obtendrá es una carpeta con ese nombre y todos los archivos correctos dentro de ella.
Abre el Finder y navega a tu nueva carpeta para ver qué hay dentro. Debería ver algo como esto:

Como no necesitamos todo lo que ofrece Jekyll, primero eliminaremos algunos archivos y carpetas. Lancemos /_includes , /_posts , /_sass , about.md y feed.xml .
Configuración
Ahora configuraremos nuestras configuraciones para todo el sitio. Abra _config.yml . Hay un montón de cosas introductorias allí. Simplemente lo eliminaré y lo reemplazaré con mis configuraciones preferidas. Aquí está la nueva configuración para este proyecto:
permalink: pretty collections: projects people
Lo hice para que mis URL se vean como /ruta/al/archivo/ en lugar de /ruta/al/archivo.html, que es solo una preferencia personal. También he establecido dos colecciones: proyectos y personas . Cualquier colección nueva debe agregarse al archivo de configuración.
Ahora puedo crear carpetas para estas colecciones en mi proyecto:

Los nombres de las carpetas deben comenzar con el carácter _ (guión bajo) para que Jekyll sepa qué hacer con ellos.
Hacer algunos objetos
Los primeros objetos que haremos serán nuestra gente. Vamos a usar Markdown para crear estos archivos para que sean agradables y limpios, pero aún así generen HTML semántico adecuado. Puede ver que he creado algunos archivos para figuras de la historia estadounidense (esto puede o no estar relacionado con el hecho de que he estado escuchando a Hamilton sin parar durante un mes):

Los atributos que pondremos en nuestro archivo para una persona serán:

--- object-id: first-name: last-name: job: listing-priority: wikipedia-url: ---
Usaremos el object-id
para referirnos específicamente a cualquiera de estos objetos más adelante. Dividiremos el nombre y el apellido para que podamos seleccionar qué combinación usar en varios lugares (si su sistema lo requiere) y usaremos job
para definir lo que hacen. (Estoy evitando el 'título' porque ya es una variable que las páginas en Jekyll tienen de forma predeterminada). También he incluido un atributo para la prioridad de listado que me permitirá ordenar a cada persona según sus deseos, pero también puede ordenar por algunos métodos integrados, como alfabético o numérico. Finalmente, tenemos un campo para un enlace a la página de Wikipedia de la persona.
Todo esto está contenido entre tres guiones en la parte superior e inferior para definirlo como materia prima de YAML. El contenido de cada biografía irá después de YAML y puede ser una cantidad y estructura arbitrarias de HTML (pero usaremos el formato Markdown para mantener todo agradable y limpio).
Un objeto de persona completamente poblado se ve así (el contenido se trunca para mayor claridad):
--- object-id: alexander-hamilton first-name: Alexander last-name: Hamilton job: 1st United States Secretary of the Treasury listing-priority: 1 wikipedia-url: https://en.wikipedia.org/wiki/Alexander_Hamilton --- Alexander Hamilton (January 11, 1755 or 1757 – July 12, 1804) was...
Y aquí hay un objeto de proyecto (el contenido se trunca para mayor claridad):
--- object-id: united-states-coast-guard title: United States Coast Guard featured: true featured-priority: 2 listing-priority: 1 architect-id: alexander-hamilton wikipedia-url: https://en.wikipedia.org/wiki/United_States_Coast_Guard --- The United States Coast Guard (USCG) is...
Este tiene algunas diferencias. He establecido un atributo featured
. Si se presenta un proyecto, se incluye en la página de inicio. Todos los proyectos se enumerarán en la página de proyectos. También tenemos establecido nuestro orden de clasificación preferido para cada ubicación. Y hemos incluido una referencia a la id
de la persona que creó el proyecto, para que podamos referirnos directamente a ellos más adelante.
Generando páginas a partir de nuestros objetos
Al alterar mi archivo _config.yml puedo crear páginas para cada uno de estos objetos.
permalink: pretty collections: projects: output: true people: output: true
Establecer output: true
en cada colección hace que se genere una página para cada objeto dentro de ella. Pero debido a que nuestros objetos no tienen contenido en sus archivos, actualmente no generan ningún dato, lo que significa que solo obtendremos páginas vacías. Construyamos una plantilla de diseño para hacer eso por nosotros.
Este archivo irá en la carpeta _layouts . Pero primero, tenemos un archivo default.html ahí para tratar. Esto mantendrá cualquier marcado que sea consistente en todos nuestros archivos HTML.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>{{ page.title }}</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="/css/styles.css" /> </head> <body> <header role="banner"> ... </header> <div role="main"> <div class="container"> {{ content }} </div> </div> <footer role="contentinfo"> ... </footer> </body> </html>
Verá una etiqueta de Liquid que se ve así: {{ content }}
. Cada archivo que Jekyll representa en una página necesita una plantilla específica para ello. Una vez que especifica su plantilla, el contenido de ese archivo se representa en la ubicación de la etiqueta {{ content }}
en la plantilla de diseño. Ahora no tenemos que repetir cosas que estarán en cada página.
A continuación, crearemos una plantilla de diseño única para nuestros objetos de persona. Eso se verá así:
--- layout: default --- <header class="intro person-header"> <h1>{{ page.first-name }} {{ page.last-name }}</h1> <h2>{{ page.job }}</h2> </header> <div class="person-body"> {{ page.content }} <a href="{{ page.wikipedia-url }}">Read more about {{ page.first-name }} {{ page.last-name }} on Wikipedia</a> </div>
Este archivo especifica que su código se inserta en la plantilla de diseño predeterminada y, luego, su marcado se completa a partir de los datos de los archivos de objeto de persona.
El último paso es asegurarse de que cada objeto de persona especifique que utiliza el archivo de diseño person.html . Normalmente, solo insertaríamos eso en el YAML en nuestros archivos personales de esta manera:
--- object-id: first-name: last-name: job: listing-priority: wikipedia-url: layout: person ---
Pero prefiero hacer que los datos en mis archivos de objetos solo contengan atributos relevantes para el modelo de contenido. Afortunadamente, puedo modificar mi archivo _config.yml para manejar esto por mí:
exclude: - README.md permalink: pretty collections: projects: output: true people: output: true defaults: - scope: type: projects values: layout: project - scope: type: people values: layout: person
Ahora mi sitio sabe que cualquier objeto en la colección de proyectos debe usar la plantilla de diseño del proyecto, y cualquier objeto en la colección de personas debe usar el diseño de persona. Esto me ayuda a mantener mis objetos de contenido agradables y limpios.
Visualización de objetos en una página de listado
Ya sea que elijamos generar páginas para nuestros objetos o no, podemos enumerarlos y ordenarlos por diferentes parámetros. Así es como enumeraríamos todos nuestros proyectos en una página:
--- layout: default title: Projects --- <header class="intro"> <h1>{{ page.title }}</h1> </header> <div class="case-studies-body"> <ul class="listing"> {% assign projects = site.projects | sort: 'listing-priority' %} {% for project in projects %} <li> <h2><a href="{{ project.url }}">{{ project.title }}</a></h2> {{ project.content }} </li> {% endfor %} </ul> </div>
Lo que hemos hecho es crear un <ul>
para poner nuestra lista dentro. Luego, creamos una variable en la página llamada projects
, le asignamos todos nuestros objetos de proyecto y los ordenamos por la variable listing-priority
que creamos en cada uno. Finalmente, para cada proyecto en nuestra variable de projects
generamos un <li>
que incluye datos de los atributos en cada archivo. Esto nos da una lista altamente controlable de los objetos de nuestro proyecto con enlaces a sus páginas únicas.
En la página de inicio, en lugar de mostrar todos los proyectos, mostraremos solo los destacados:
<ul class="listing"> {% assign projects = site.projects | where: "featured", "true" | sort: 'featured-priority' %} {% for project in projects %} <li> <h3>{{ project.title }}</h3> <a href="{{ project.url }}">Learn about {{ project.title }}</a> </li> {% endfor %} </ul>
Cualquier objeto de proyecto que tenga el atributo featured
establecido en true
se representará en esta página y se clasificarán según el orden de prioridad especial que hemos establecido para los proyectos destacados.
Estos son ejemplos bastante simples de cómo generar y ordenar objetos, pero demuestran las diferentes capacidades que podemos crear para organizar contenido.
Vinculación a un objeto específico
La última característica que vamos a construir es vincular a un objeto específico. Esto es algo que quizás desee hacer si está vinculando a un autor a una publicación de blog o algo similar. En nuestro caso, vamos a adjuntar a una persona al proyecto con el que se asocia comúnmente. Si recuerda, nuestro objeto de proyecto tiene un atributo architect-id
y nuestra gente tiene cada uno un atributo object-id
. Podemos adjuntar a la persona correcta a un proyecto específico utilizando estos atributos.
Aquí está nuestra plantilla de diseño de proyecto:
--- layout: default --- {% assign architect = site.people | where: "object-id", page.architect-id | first %} <header class="intro project-header"> <h1>{{ page.title }}</h1> <p>Architected by: <a href="{{ architect.url }}">{{ architect.first-name }} {{ architect.last-name }}</a></p> </header> <div class="project-body"> {{ page.content }} <a href="{{ page.wikipedia-url }}">Read more about {{ page.title }} on Wikipedia</a> </div>
La línea 4 crea una variable llamada architect
y busca en todos nuestros objetos de personas cualquiera con una object-id
que coincida con el atributo de architect-id
de un proyecto. Deberíamos asignar object-id
s para que solo se devuelva un resultado, pero para asegurarnos de obtener solo una respuesta y referirnos a ella en lugar de nuestra lista de un elemento, tenemos que configurar | first
| first
al final de nuestra etiqueta Liquid {% assign %}
. Esto soluciona una limitación de Jekyll en la que, para empezar, los objetos de las colecciones no tienen ID únicos. Hay otra característica llamada datos que permite identificaciones únicas, pero no genera páginas fácilmente ni nos da la capacidad de ordenar nuestros objetos; trabajar alrededor de las limitaciones de las colecciones fue una forma más fácil y limpia de obtener la funcionalidad que queremos.
Ahora que la página tiene un objeto único que representa al arquitecto de ese proyecto, podemos llamar a sus atributos con cosas como el nombre del arquitecto y la URL de su página de Wikipedia. ¡Voila! Fácil vinculación a objetos por identificación única.
Terminando
Hay algunas características adicionales excelentes que se pueden establecer al profundizar en los documentos de Jekyll con más detalle, pero lo que tenemos aquí son los conceptos básicos de un buen prototipo de modelado de contenido: la capacidad de definir diferentes tipos de objetos, los atributos adjuntos a esos objetos, e IDs que nos permiten llamar a objetos específicos desde cualquier lugar. También obtenemos una lógica altamente flexible para crear plantillas y generar nuestros objetos en varios lugares. Lo mejor de todo es que todo el sistema es simple y legible por humanos, y genera HTML simple para usar en otro lugar si es necesario.
Para fines de comunicación, ahora tenemos un prototipo en el que se puede hacer clic e independiente de la plataforma (un sitio web real) que definirá el sistema mejor que un PDF con un montón de diagramas. Podemos modificar nuestro modelo de contenido sobre la marcha a medida que aprendemos cosas nuevas y necesitamos adaptarnos. Podemos hacer que el diseñador y el desarrollador ingresen al sistema para establecer sus patrones y arquitectura de front-end porque aceptará cualquier marcado y CSS que quieran usar. Incluso podemos incorporar editores de contenido configurándolos con acceso a través de una GUI de GitHub o una plataforma de alojamiento que permita el uso de un editor visual como Prose.io, GitHub Pages, CloudCannon o Netlify.
Y nada de esto vincula a una persona con el aprendizaje de formas de trabajo específicas de la plataforma, lo que les permite trabajar desde un nivel conceptual que se centra en los usuarios y no en la tecnología.