Maison > interface Web > js tutoriel > Créez des aides de guidon personnalisées dans Ghost !

Créez des aides de guidon personnalisées dans Ghost !

Barbara Streisand
Libérer: 2025-01-07 00:08:41
original
127 Les gens l'ont consulté

Make Custom Handlebar Helpers in Ghost!

Cet article s'adresse à de nombreux développeurs et créateurs de thèmes qui trouvent les aides standards proposées par Ghost (https://ghost.org/docs/themes/helpers/) insuffisantes. Il est tout à fait normal de chercher des moyens d'étendre les capacités de nos thèmes qui utilisent les guidons fournis par Ghost. Avant de publier cet article et de trouver une solution pour mon thème, j'ai parcouru tout Internet et effectué moi-même une analyse du code source de Ghost.

Méthode 1 (modification du code principal)

J'ai découvert qu'il est possible d'étendre le code source de Ghost avec des aides supplémentaires. J'y suis parvenu en ajoutant un nouveau répertoire dans current/core/frontend/apps. J'ai utilisé l'exemple d'une « application » existante appelée amp, dont le code est très simple, pour commencer à créer un nouvel assistant disponible dans le thème. Dans ces applications existantes, la structure est simple car les helpers sont enregistrés dans lib/helpers. À la fin du processus, vous devez ajouter le nom de votre répertoire dans apps à current/core/shared/config/overrides.json dans la section apps.internal JSON.

Un exemple de contenu du fichier index.js dans notre application serait :

const path = require('path');

module.exports = {
    activate: function activate(ghost) {
        ghost.helperService.registerDir(path.resolve(__dirname, './lib/helpers'));
    }
};
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ensuite, dans le répertoire lib de cette application, nous créons un dossier nommé helpers. À l’intérieur, nous créons un nouveau fichier, qui sera le nom de l’assistant à appeler dans un modèle de guidon. Par exemple, nommons-le uppercase.js.

Vous trouverez ci-dessous un exemple d'un tel code d'assistance, qui convertit simplement les lettres du texte donné dans l'argument d'assistance en majuscules :

const {SafeString, escapeExpression} = require('../../../../services/handlebars');

module.exports = function uppercase(text) {
    return `${text.toUpperCase()}`;
};
Copier après la connexion
Copier après la connexion
Copier après la connexion

N'oubliez pas d'ajouter le nom du répertoire de l'application à current/core/shared/config/overrides.json. Après avoir redémarré Ghost, tout devrait être prêt.

Méthode 2 (sans modifier le code principal)

J'ai récemment développé cette méthode, et vous pouvez l'appliquer non seulement sur Ghost auto-hébergé mais également sur les instances Ghost proposées par les hébergeurs. Dans ce dernier cas, cela nécessite une planification architecturale appropriée et l'achat d'un petit serveur qui fera office de proxy pour votre instance Ghost finale.

L'architecture que nous utiliserons dans cette méthode :
Serveur Nginx ← Middleware Node.js ← Instance Ghost

Le navigateur de l'utilisateur envoie une requête au serveur Nginx, qui contient l'amont du middleware. Toutes les demandes, quel que soit leur emplacement, seront transmises par proxy au middleware.

Le middleware est un serveur Express fonctionnant dans Node.js avec la bibliothèque express-http-proxy (https://github.com/villadora/express-http-proxy) ajoutée, ce qui simplifie considérablement le travail. Nous configurons le proxy pour communiquer avec l'instance Ghost. La bibliothèque express-http-proxy possède une propriété userResDecorator que nous pouvons utiliser pour « décorer la réponse du serveur mandaté ». En termes simples, nous pouvons modifier la réponse de Ghost avant de l'envoyer au navigateur de l'utilisateur.

Notre userResDecorator sera asynchrone afin de ne pas bloquer le thread principal. Nous reviendrons sur le sujet du traitement asynchrone lors de la création des helpers. Pour l'instant, vous devez savoir que tout ce que demande le navigateur de l'utilisateur n'a pas besoin d'être décoré. Par conséquent, la première étape consistera à vérifier l’en-tête content-type de la réponse de Ghost. Vous pouvez procéder comme suit puis comparer s'il s'agit de texte/html pour décorer uniquement les documents HTML renvoyés à l'utilisateur :

const path = require('path');

module.exports = {
    activate: function activate(ghost) {
        ghost.helperService.registerDir(path.resolve(__dirname, './lib/helpers'));
    }
};
Copier après la connexion
Copier après la connexion
Copier après la connexion

Dans cette instruction conditionnelle, nous pouvons commencer à modifier htmlContent, mais pourquoi en avons-nous besoin ? Commençons par jeter les bases de notre assistant personnalisé dans le thème Ghost !

Dans cet article, je vais créer un assistant personnalisé dans le fichier index.hbs (page d'accueil) de mon thème. Dans un emplacement visible dans le modèle de guidon, j'ajoute un exemple d'assistant personnalisé, le nommant {{hello_world}}.

⚠️ Ensuite, je le place à un endroit visible sur la page d'accueil — mais remarquez ce qui se passe lorsque j'actualise la page Ghost !

const {SafeString, escapeExpression} = require('../../../../services/handlebars');

module.exports = function uppercase(text) {
    return `${text.toUpperCase()}`;
};
Copier après la connexion
Copier après la connexion
Copier après la connexion

Dans cette variable, nous avons la réponse de l'instance Ghost comme le code HTML complet de la page. Imaginez que cette réponse soit la page d'accueil de votre instance Ghost. Le contenu HTML inclura également notre texte brut {{hello_world}}, qui est affiché sous forme de texte brut. Si notre assistant personnalisé se présente sous cette forme, nous pouvons le compiler à l'aide de Handlebars.js (https://handlebarsjs.com/) dans notre middleware. N'oubliez pas d'installer d'abord la bibliothèque via un gestionnaire de packages, par exemple npm : npm install handlebars et ajoutez-la à votre code : const handlebars = require("handlebars");.

// Where 'proxyRes' is your proxy response inside 'userResDecorator'
const contentType = proxyRes.headers['content-type'] || '';
if (!contentType.includes('text/html')) {
    // Return original content if response is not 'text/html'
    return proxyResData;
}

let htmlContent = proxyResData.toString('utf8');
// Do something with 'htmlContent' and return
return htmlContent;
Copier après la connexion

Wow ! Nous avons maintenant compilé et rendu du HTML à l'aide de guidons.js, mais nous n'avons pas encore terminé. Nous devons encore enregistrer notre assistant personnalisé {{hello_world}}. Ajoutez le code suivant, de préférence après avoir initialisé Handles.js :

{{!< default}}
<div>



<p>After refreshing, I get an error message from Ghost because the {{hello_world}} helper doesn’t exist in Ghost's default helpers. For our logic to work, we must escape this helper so that it’s not treated as a helper by Ghost’s built-in Handlebars.</p>

<p>The correct way is to write this helper as \{{hello_world}}. This way, Ghost treats it as plain text. After refreshing the Ghost homepage, you should see the plain text {{hello_world}}. If this happens, you are on the right track. Let’s now return to the middleware server file, where we will use the response decorator.</p>

<p>⚠️ Remember to escape custom helpers in your theme! Don’t forget to add the \ character.<br>
</p>

<pre class="brush:php;toolbar:false">let htmlContent = proxyResData.toString('utf8');
Copier après la connexion

Après avoir redémarré le serveur middleware et enregistré l'assistant ci-dessus, vous devriez voir l'assistant rendu dans le navigateur avec le texte renvoyé par notre assistant ainsi que la date et l'heure actuelles.

À ce stade, vous pouvez étendre votre thème Ghost avec des assistants personnalisés supplémentaires, que vous ajouterez au code du serveur middleware.

Sécurité

À un moment donné, vous souhaiterez peut-être rendre diverses choses à vos aides. Par défaut, la bibliothèque protège contre les attaques XSS, mais lorsque vous utilisez la méthode SafeString, cette protection cesse de fonctionner. Évitez de l'utiliser autant que possible.

Encore une chose ! Imaginez qu'un utilisateur ajoute une telle aide dans la section commentaires sous une publication et ajoute du contenu malveillant dans le paramètre. Soyez attentif à la sécurité. Par exemple, si vous restituez entièrement chaque code HTML, vous pourriez être vulnérable aux attaques XSS. Il est recommandé de compiler et de restituer Handles.js dans des zones spécifiques et fermées. Vous pouvez utiliser la bibliothèque cheerio (https://cheerio.js.org/) pour analyser le HTML et restituer les guidons si nécessaire. Voici un exemple de la façon dont vous pouvez vous sécuriser en modifiant le code de rendu précédent :

const path = require('path');

module.exports = {
    activate: function activate(ghost) {
        ghost.helperService.registerDir(path.resolve(__dirname, './lib/helpers'));
    }
};
Copier après la connexion
Copier après la connexion
Copier après la connexion

N'oubliez pas d'ajouter l'initialisation de la bibliothèque au début de votre script : const asyncHelpers = require('handlebars-async-helpers');. Si vous rencontrez des problèmes d'installation en raison de conflits de versions entre handlebars-async-helpers et handlebars, rétrogradez simplement handlebars vers ^4.7.6. Malheureusement, la bibliothèque d'assistance asynchrone n'a pas été maintenue depuis un certain temps, mais elle fonctionne toujours dans la pratique.

Communication et objets de base de données

Si vous souhaitez effectuer des requêtes dans la base de données dans Ghost pour récupérer, par exemple, la publication en cours, c'est possible et pas difficile. Vous pouvez utiliser une bibliothèque comme knex (https://knexjs.org/), qui est un générateur de requêtes SQL clair et rapide. N'oubliez pas que vous aurez besoin de handlebars-async-helpers pour cela. Configurez correctement knex pour vous connecter à la base de données de Ghost.

Initialisez knex comme variable db et essayez le code suivant :

const {SafeString, escapeExpression} = require('../../../../services/handlebars');

module.exports = function uppercase(text) {
    return `${text.toUpperCase()}`;
};
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ensuite, dans le modèle post.hbs du thème Ghost, ajoutez l'assistant suivant : {{post_title uuid="{{uuid}}"}}. Dans cet exemple, {{uuid}} sera récupéré et transmis en tant qu'assistant disponible dans Ghost, remplissant le champ uuid de notre assistant et provoquant l'affichage du titre du message par l'assistant personnalisé.

Vous pouvez également utiliser axios pour envoyer des requêtes HTTP à l'API Ghost Content, mais cela est nettement plus lent que la communication directe avec la base de données.

Performance

Je sais qu'une solution basée sur un middleware n'est peut-être pas la meilleure en termes de vitesse, mais j'utilise personnellement cette solution et je n'ai pas remarqué de baisse significative des temps de chargement des pages. Le temps de réponse moyen pour une seule requête était inférieur à 100 ms (selon express-status-monitor) et j'utilise un assistant personnalisé qui récupère certaines valeurs de la base de données sur chaque page.

Vous pouvez bien sûr ajouter des mécanismes de mise en cache pour améliorer les performances du middleware ou utiliser des solutions alternatives au lieu d'express-http-proxy.

Mise en œuvre de l'architecture

Utilisez Docker ou un autre mécanisme de conteneurisation. Je l'ai utilisé dans mon projet et cela fonctionne très bien. Ajoutez des images Ghost et de base de données pour Ghost, Nginx et une image Node.js. Connectez-les à un réseau partagé (driver : bridge), configurez Nginx et le serveur Node.js en conséquence — tout est très simple !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal