Ghost CMS
Theme
Web

Desarrollando un Ghost CMS Theme [Parte 1]

Esta es la historia de como crear un tema para el CMS Ghost. O por lo menos la configuración inicial.

Ivan Robles

4 min read
Desarrollando un Ghost CMS Theme [Parte 1]

Por fin el primer Release de mi Ghost Theme 🎉, The Sharmaz.

Desde que comencé este blog allá por 2018, quería hacer mi propio tema con juegos de azar y… Bueno a lo que me refiero es que por una cosa u otra fui dejando el crear mi propio theme para después. Sin embargo y aprovechando el sabático que me estoy aventando le dedique su debido tiempo.

Nota: Este proyecto no es desde cero, nos basamos en el tema Starter, mismo que desarrolla la gente de Ghost.

Lápiz y papel alerta!! Esto es lo que vamos a necesitar para poder crear un Tema para Ghost.

Instalar la interfaz de linea de comandos Ghost CLI de manera global:

sudo npm install -g ghost-cli@latest

Crear un proyecto de Ghost de manera local:

ghost install local

Instalar Yarn (recomendado para el tema starter).

npm install --global yarn

Ahora lo que sigue es correr el proyecto de ghost y agregar el tema que vamos a usar.

Posicionados en el folder de nuestro proyecto de Ghost ejecutamos el siguiente comando:

ghost start

Nos movemos a la carpeta de content/themes/ y aquí es donde vamos a clonar el repositorio del tema starter.

Ahora nos posicionamos en el folder del tema e instalamos dependencias:

yarn install

Ahora podemos correr el proyecto en modo de desarrollo con:

yarn dev

Con esto ya podríamos comenzar a trabajar, pero quiero tener la data, posts, imágenes, etc que ya tengo en mi blog, entonces fui a crear un respaldo de mi sitio para importarlo en el local.

En casos de querer hacerlo, hay que acceder al servidor via ssh, posicionarnos en el folder del proyecto y hacer el backup con:

ghost backup

Nos va a crear un archivo zip, para descargarlo desde el servidor con ssh hay que usar el comando:

scp <server_username>@<server_host>:<path_to_file>

Del archivo Zip necesitamos las imágenes y la data en .json, el JSON se importa con el ghost en local corriendo, en el Dashboard Admin > Settings > Labs > Import Content.

Las imágenes hay que arrojarlas a la carpeta de content/images y listo.

Revisando el proyecto del Starter Theme, cosas que están chidas y otras que están gachas:

Lo chido (lo bueno):

  • Utiliza Rollup para los builds, por lo cual es bastante rápido.
  • Tiene Hot Module Replacement, cada vez que guardas los cambios el navegador los refleja de forma automática, el tema Casper carece de eso y hay que estar recargando manualmente, quería basarme en Casper antes de usar el Starter.
  • Ya viene preparado para hacer Build, Test con el scaner de Ghost y compresion por Zip para poderlo importar.

Lo gacho (lo feo):

  • El formato de los documentos no es como me gustaría prefiero un tab size de 2 espacios, entre otras cosas.
  • No hay linter, ni un estilo de código definido.
  • Tiene un montón de custom clases CSS y por lo tanto muchos archivos CSS. En estos momentos prefiero usar TailwindCSS y evitar escribir tantos archivos .css para los estilos como pueda.

Que es lo que vamos a hacer? Lo que no hice al principio pero debí hacer, remover las cosas gachas.

Para temas de formato vamos a instalar y configurar Prettier:

yarn add --dev --exact prettier

Nos creamos un archivo de configuración .prettierrc donde vamos a agregar nuestras preferencias:

{
  "printWidth": 100,
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "none"
}

Y otro archivo para ignorar los archivos que no queremos .prettierignore :

# Ignore artifacts:
build
coverage

assets/built

Ahora es el turno de la la configuración de ESlint:

yarn add -D eslint

A seguir el asistente de configuración el cual corremos con:

npm init @eslint/config

Al final, me quedo algo como esto en el archivo .eslintrc.cjs :

module.exports = {
  env: {
    browser: true,
    es2021: true
  },
  extends: ['airbnb-base', 'prettier'],
  plugins: ['prettier'],
  rules: {
    'prettier/prettier': ['error']
  },
  overrides: [],
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module'
  }
};

Y para el final vamos a agregar TailwindCSS:

yarn add -D tailwindcss @tailwindcss/typography concurrently

Corremos el comando para crear un archivo de configuración:

npx tailwindcss init

Agregamos nuestras configuraciones al archivo tailwind.config.js :

/** @type {import('tailwindcss').Config} */
export default {
  content: ["./*.hbs", "./**/*.hbs"],
  theme: {
      extend: {}
  },
  plugins: [
      require('@tailwindcss/typography')
  ]
}

Hasta arriba del archivo /assets/css/index.css vamos a importar el CSS de tailwind:

/* Tailwind */
@tailwind base;
@tailwind components;
@tailwind utilities;

Ahora hay que remover la linea del import del css en assets/js/index.js :

// Import CSS
import "../css/index.css";

También en el rollup.config.js hay que remover las siguientes lineas que tienen que ver con PostCSS:

// CSS
// Enable the PostCSS preprocessor
import postcss from 'rollup-plugin-postcss';
// Use @import to include other CSS files
import atImport from 'postcss-import';
// Use the latest CSS features in your Rollup bundle
import postcssPresetEnv from 'postcss-preset-env';

Y estas que igual son referentes a PostCSS:

postcss({
    extract: true,
    sourceMap: true,
    plugins: [
        atImport(),
        postcssPresetEnv({})
    ], 
    minimize: true,
}),

Por ultimo hay que modificar los scripts build y dev en el package.json :

"build": "rollup -c --environment BUILD:production && npx tailwindcss -i ./assets/css/index.css -o ./assets/built/index.css --minify",
"dev": "concurrently \\"rollup -c --environment BUILD:development -w\\" \\"npx tailwindcss -i ./assets/css/index.css -o ./assets/built/index.css --watch\\" ",

Ahora si, a lo que nos truje chencha, a modificar las partes del tema.

Bueno, en realidad de eso hablaremos en otro post. Hasta aquí lo vamos a dejar por ahora, pero si les adelanto que para la próxima les explicaré sobre como se agrega Prism, una librería para resaltar el código en diferentes lenguajes de programación y también de las partes que conforman un tema de Ghost.

Nos leemos luego!!