Cómo crear un CMS simple con Cloudflare, GitHub Actions y Metalsmith

Índice
  1. ¿Cómo se ve la pila completa?
  2. Pero antes de empezar…
  3. Estructura del proyecto
  4. Paso 1: cosas de la línea de comando
  5. Paso 2: orfebre
  6. Paso 3: agregamos algo de código
  7. Paso 4: el archivo de compilación

Construyamos nosotros mismos un CMS. Pero en lugar de crear una interfaz de usuario, ¡obtendremos esa interfaz de usuario de forma gratuita en forma del propio GitHub! Aprovecharemos GitHub como forma de administrar el contenido de nuestro generador de sitios estáticos (podría ser cualquier generador de sitios estáticos). Aquí está la esencia: GitHub será el lugar para administrar, controlar versiones y almacenar archivos, y también será el lugar donde editaremos nuestro contenido. Cuando se produzcan modificaciones, una serie de automatizaciones probarán, verificarán y, en última instancia, implementarán nuestro contenido en Cloudflare.

Puede encontrar el código completo del proyecto disponible en GitHub. Impulso mi propio sitio web, jonpauluritis.com, exactamente de esta manera.

¿Cómo se ve la pila completa?

Aquí está la pila tecnológica con la que trabajaremos en este artículo:

  • Cualquier editor de Markdown (opcional, por ejemplo, Typora.io)
  • Un generador de sitios estáticos (por ejemplo, Metalsmith)
  • Github con acciones de Github (CICD e implementación)
  • Trabajadores de Cloudflare

¿Por qué debería importarle esta configuración? Esta configuración es potencialmente la forma más sencilla, rápida, barata (~$5/mes) y más sencilla de administrar un sitio web (o sitio Jamstack). Es increíble tanto desde el punto de vista técnico como desde la perspectiva de la experiencia del usuario. Esta configuración es tan asombrosa que literalmente salí y compré acciones de Microsoft y Cloudflare.

Pero antes de empezar…

No voy a guiarte en la configuración de cuentas en estos servicios, estoy seguro de que puedes hacerlo tú mismo. Estas son las cuentas que necesitas configurar:

  • GitHub (Registrarse en GitHub Actions).
  • Sitios de trabajadores de Cloudflare (este es el que cuesta $5 al mes).

También recomendaría Typora para disfrutar de una increíble experiencia de escritura en Markdown, pero los editores de Markdown son algo muy personal, así que utilice el editor que le parezca adecuado.

Estructura del proyecto

Para darle una idea de hacia dónde nos dirigimos, aquí está la estructura del proyecto completada:

├── build.js├── .github/workflows│  ├── deploy.yml│  └── nodejs.js├── layouts│  ├── about.hbs│  ├── article.hbs│  ├── index.hbs│  └── partials│    └── navigation.hbs├── package-lock.json├── package.json├── public├── src│  ├── about.md│  ├── articles│  │  ├── post1.md│  │  └── post2.md│  └── index.md├── workers-site└── wrangler.toml

Paso 1: cosas de la línea de comando

En una terminal, cambie el directorio al lugar donde guarde este tipo de proyectos y escriba esto:

$ mkdir cms  cd cms  npm init -y

Eso creará un nuevo directorio, entrará en él e inicializará el uso de npm.

Lo siguiente que queremos hacer es subirnos a hombros de gigantes. Usaremos varios paquetes npm que nos ayudan a hacer cosas, cuyo núcleo es usar el generador de sitios estáticos Metalsmith :

$ npm install --save-dev metalsmith metalsmith-markdown metalsmith-layouts metalsmith-collections metalsmith-permalinks handlebars jstransformer-handlebars

Junto con Metalsmith, hay un par de detalles más útiles. ¿Por qué Metalsmith? Hablemos de eso.

Paso 2: orfebre

He estado probando generadores de sitios estáticos durante 2 o 3 años y todavía no he encontrado “el indicado”. Todos los grandes nombres, como Eleventy, Gatsby, Hugo, Jekyll, Hexo y Vuepress, son totalmente geniales, pero no puedo superar la simplicidad y extensibilidad de Metalsmith.

Como ejemplo, este código le construirá un sitio:

// EXAMPLE... NOT WHAT WE ARE USING FOR THIS TUTORIALMetalsmith(__dirname)           .source('src')         .destination('dest')       .use(markdown())               .use(layouts())             .build((err) = if (err) throw err);

Bastante genial, ¿verdad?

En aras de la brevedad, escriba esto en la terminal y crearemos una estructura y archivos para empezar.

Primero, crea los directorios:

$ mkdir -p src/articles   mkdir -p layouts/partials 

Luego, cree el archivo de compilación:

$ touch build.js

A continuación, crearemos algunos archivos de diseño:

$ touch layouts/index.hbs  touch layouts/about.hbs  touch layouts/article.hbs  touch layouts/partials/navigation.hbt

Y, finalmente, configuraremos nuestros recursos de contenido:

$ touch src/index.md  touch src/about.md  touch src/articles/post1.md  touch src/articles/post1.md touch src/articles/post2.md

La carpeta del proyecto debería verse así:

├── build.js├── layouts│   ├── about.hbs│   ├── article.hbs│   ├── index.hbs│   └── partials│       └── navigation.hbs├── package-lock.json├── package.json└── src    ├── about.md    ├── articles    │   ├── post1.md    │   └── post2.md    └── index.md

Paso 3: agregamos algo de código

Para ahorrar espacio (y tiempo), puede utilizar los siguientes comandos para crear el contenido de nuestro sitio web ficticio. Siéntete libre de acceder a los “artículos” y crear tus propias publicaciones de blog. La clave es que las publicaciones necesitan algunos metadatos (también llamados “Front Matter”) para poder generarse correctamente. Los archivos que querrás editar son index.md, post1.mdy post2.md.

Los metadatos deben verse así:

---title: 'Post1'layout: article.hbs ---## Post content here....

O, si eres vago como yo, usa estos comandos de terminal para agregar contenido simulado de GitHub Gists a tu sitio:

$ curl https://gist.githubusercontent.com/jppope/35dd682f962e311241d2f502e3d8fa25/raw/ec9991fb2d5d2c2095ea9d9161f33290e7d9bb9e/index.md  src/index.md$ curl https://gist.githubusercontent.com/jppope/2f6b3a602a3654b334c4d8df047db846/raw/88d90cec62be6ad0b3ee113ad0e1179dfbbb132b/about.md  src/about.md$ curl https://gist.githubusercontent.com/jppope/98a31761a9e086604897e115548829c4/raw/6fc1a538e62c237f5de01a926865568926f545e1/post1.md  src/articles/post1.md$ curl https://gist.githubusercontent.com/jppope/b686802621853a94a8a7695eb2bc4c84/raw/9dc07085d56953a718aeca40a3f71319d14410e7/post2.md  src/articles/post2.md

A continuación, crearemos nuestros diseños y diseños parciales (“parciales”). Usaremos Manillars.js para nuestro lenguaje de plantillas en este tutorial, pero puedes usar cualquier lenguaje de plantillas que te convenga. Metalsmith puede trabajar con casi todos ellos y no tengo ninguna opinión firme sobre los lenguajes de plantillas.

Construya el diseño del índice

!DOCTYPE htmlhtml  head    style      /* Keeping it simple for the tutorial */      body {        font-family: 'Avenir', Helvetica, Arial, sans-serif;        -webkit-font-smoothing: antialiased;        -moz-osx-font-smoothing: grayscale;        text-align: center;        color: #2c3e50;        margin-top: 60px;      }      .navigation {        display: flex;        justify-content: center;        margin: 2rem 1rem;      }      .button {        margin: 1rem;        border: solid 1px #ccc;        border-radius: 4px;                padding: 0.5rem 1rem;        text-decoration: none;      }    /style  /head  body    {{navigation }}    div       {{#each articles }}        a href="{{path}}"h3{{ title }}/h3/a        p{{ description }}/p       {{/each }}    /div  /body/html

Un par de notas:

  • Nuestra “navegación” aún no ha sido definida, pero eventualmente reemplazará el área donde {{navigation }}residemos.
  • {{#each }}iterará a través de la “colección” de artículos que metalsmith generará durante su proceso de construcción.
  • Metalsmith tiene muchos complementos que puedes usar para cosas como hojas de estilo, etiquetas, etc., pero este tutorial no trata de eso, así que lo dejaremos para que lo explore.

Crear la página Acerca de

Agregue lo siguiente a su about.hbspágina:

!DOCTYPE htmlhtml  head    style      /* Keeping it simple for the tutorial */      body {        font-family: 'Avenir', Helvetica, Arial, sans-serif;        -webkit-font-smoothing: antialiased;        -moz-osx-font-smoothing: grayscale;        text-align: center;        color: #2c3e50;        margin-top: 60px;      }      .navigation {        display: flex;        justify-content: center;        margin: 2rem 1rem;      }      .button {        margin: 1rem;        border: solid 1px #ccc;        border-radius: 4px;                padding: 0.5rem 1rem;        text-decoration: none;      }        /style  /head  body    {{navigation }}    div      {{{contents}}}    /div  /body/html

Construya el diseño de los artículos.

!DOCTYPE htmlhtml  head    style      /* Keeping it simple for the tutorial */      body {        font-family: 'Avenir', Helvetica, Arial, sans-serif;        -webkit-font-smoothing: antialiased;        -moz-osx-font-smoothing: grayscale;        text-align: center;        color: #2c3e50;        margin-top: 60px;      }      .navigation {        display: flex;        justify-content: center;        margin: 2rem 1rem;      }      .button {        margin: 1rem;        border: solid 1px #ccc;        border-radius: 4px;                padding: 0.5rem 1rem;        text-decoration: none;      }    /style  /head  body    {{navigation }}    div      {{{contents}}}    /div  /body/html

Es posible que hayas notado que este es exactamente el mismo diseño que la página Acerca de. Es. Solo quería cómo cubrir páginas adicionales para que sepas cómo hacerlo. Si quieres que este sea diferente, hazlo.

Agregar navegación

Agregue lo siguiente al layouts/partials/navigation.hbsarchivo

div  div    a href="/"Home/a    a href="/about"About/a  /div/div

Seguro que no hay mucho que decir… pero realmente no se supone que sea un tutorial de Metalsmith/SSG. ¯_(ツ)_/¯

Paso 4: el archivo de compilación

El corazón y el alma de Metalsmith es el archivo de construcción. Para ser más exhaustivo, lo repasaré línea por línea.

Empezamos importando las dependencias.

Nota rápida: Metalsmith se creó en 2014 y el sistema de módulos predominante en ese momento era common.js, por lo que me quedaré con las declaraciones requeridas en lugar de los módulos ES. También vale la pena señalar que la mayoría de los otros tutoriales también utilizan declaraciones requeridas, por lo que omitir un paso de compilación con Babel hará que la vida sea un poco menos compleja aquí.

// What we use to glue everything togetherconst Metalsmith = require('metalsmith');
// compile from markdown (you can use targets as well)const markdown = require('metalsmith-markdown');
// compiles layoutsconst layouts = require('metalsmith-layouts');
// used to build collections of articlesconst collections = require('metalsmith-collections');
// permalinks to clean up routesconst permalinks = require('metalsmith-permalinks');
// templatingconst handlebars = require('handlebars');
// register the navigationconst fs = require('fs');handlebars.registerPartial('navigation', fs.readFileSync(__dirname + '/layouts/partials/navigation.hbt').toString());
// NOTE: Uncomment if you want a server for development// const serve = require('metalsmith-serve');// const watch = require('metalsmith-watch');

A continuación, incluiremos a Metalsmith y le indicaremos dónde encontrar sus objetivos de compilación:

// MetalsmithMetalsmith(__dirname)              // where your markdown files are  .source('src')        // where you want the compliled files to be rendered  .destination('public')

Hasta ahora, todo bien. Una vez que tengamos el origen y el destino configurados, configuraremos la representación de rebajas, la representación de diseños y le informaremos a Metalsmith que utiliza “Colecciones”. Éstas son una forma de agrupar archivos. Un ejemplo sencillo sería algo así como “publicaciones de blog”, pero en realidad podría ser cualquier cosa, por ejemplo recetas, reseñas de whisky o lo que sea. En el ejemplo anterior, llamamos a la colección “artículos”.

 // previous code would go here
  // collections create groups of similar content  .use(collections({     articles: {      pattern: 'articles/*.md',    },  }))  // compile from markdown  .use(markdown())  // nicer looking links  .use(permalinks({    pattern: ':collection/:title'  }))  // build layouts using handlebars templates  // also tell metalsmith where to find the raw input  .use(layouts({    engine: 'handlebars',    directory: './layouts',    default: 'article.html',    pattern: ["*/*/*html", "*/*html", "*html"],    partials: {      navigation: 'partials/navigation',    }  }))
// NOTE: Uncomment if you want a server for development// .use(serve({//   port: 8081,//   verbose: true// }))// .use(watch({//   paths: {//     "${source}/**/*": true,//     "layouts/**/*": "**/*",//   }// }))      

A continuación, agregaremos el complemento Markdown, para que podamos usar Markdown para compilar el contenido en HTML.

A partir de ahí, usamos el complemento de diseños para envolver nuestro contenido sin procesar en el diseño que definimos en la carpeta de diseños. Puede leer más sobre los aspectos prácticos de esto en el sitio oficial del complemento, pero el resultado es que podemos usarlo {{{contents}}}en una plantilla y simplemente funcionará.

La última adición a nuestro pequeño script de compilación será el método de compilación:

// Everything else would be above this.build(function(err) {  if (err) {    console.error(err)  }  else {    console.log('build completed!');  }});

Al juntar todo, deberíamos obtener un script de compilación similar a este:

const Metalsmith = require('metalsmith');const markdown = require('metalsmith-markdown');const layouts = require('metalsmith-layouts');const collections = require('metalsmith-collections');const permalinks = require('metalsmith-permalinks');const handlebars = require('handlebars');const fs = require('fs');
// Navigationhandlebars.registerPartial('navigation', fs.readFileSync(__dirname + '/layouts/partials/navigation.hbt').toString());
Metalsmith(__dirname)  .source('src')  .destination('public')  .use(collections({    articles: {      pattern: 'articles/*.md',    },  }))  .use(markdown())  .use(permalinks({    pattern: ':collection/:title'  }))  .use(layouts({    engine: 'handlebars',    directory: './layouts',    default: 'article.html',    pattern: ["*/*/*html", "*/*html", "*html"],    partials: {      navigation: 'partials/navigation',    }  }))  .build(function (err) {    if (err) {      console.error(err)    }    else {      console.log('build completed!');    }  });

Soy un fanático de lo simple y limpio y, en mi humilde opinión, no hay nada más simple o limpio que una construcción de Metalsmith. Sólo necesitamos hacer una actualización rápida del package.jsonarchivo y podremos ejecutarlo:

 "name": "buffaloTraceRoute",  "version": "1.0.0",  "description": "",  "main": "index.js",  "scripts": {    "build": "node build.js",    "test": "echo "No Tests Yet!"" ""  }

No related posts.

SUSCRÍBETE A NUESTRO BOLETÍN 
No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion