ホームページ >ウェブフロントエンド >jsチュートリアル >Ghost でカスタム ハンドルバー ヘルパーを作成しましょう!

Ghost でカスタム ハンドルバー ヘルパーを作成しましょう!

Barbara Streisand
Barbara Streisandオリジナル
2025-01-07 00:08:41175ブラウズ

Make Custom Handlebar Helpers in Ghost!

この記事は、Ghost が提供する標準ヘルパー (https://ghost.org/docs/themes/helpers/) では不十分だと感じている多くの開発者やテーマ作成者を対象としています。 Ghost が提供するハンドルバーを使用してテーマの機能を拡張する方法を探すのはごく普通のことです。この記事を公開してテーマの解決策を見つける前に、私はインターネット全体を検索し、Ghost のソース コードを自分で分析しました。

方法 1 (コア コードを変更する)

追加のヘルパーを使用して Ghost のソース コードを拡張できることを発見しました。これは、current/core/frontend/apps に新しいディレクトリを追加することで実現しました。コードが非常に単純な amp という既存の「アプリ」の例を使用して、テーマで使用できる新しいヘルパーの作成を開始しました。これらの既存のアプリでは、ヘルパーが lib/helpers に登録されているため、構造が簡単です。プロセスの最後に、apps.internal JSON セクションの current/core/shared/config/overrides.json にアプリ内のディレクトリの名前を追加する必要があります。

アプリ内のindex.js ファイルの内容の例は次のとおりです:

const path = require('path');

module.exports = {
    activate: function activate(ghost) {
        ghost.helperService.registerDir(path.resolve(__dirname, './lib/helpers'));
    }
};

次に、このアプリの lib ディレクトリに、helpers という名前のフォルダーを作成します。内部では、Handlebars テンプレートで呼び出されるヘルパーの名前となる新しいファイルを作成します。たとえば、uppercase.js.

という名前を付けます。

以下は、ヘルパー引数内の指定されたテキストの文字を大文字に変換するだけのヘルパー コードの例です。

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

module.exports = function uppercase(text) {
    return `${text.toUpperCase()}`;
};

アプリケーション ディレクトリの名前を current/core/shared/config/overrides.json に追加することを忘れないでください。 Ghost を再起動すると、すべての準備が整います。

方法 2 (コア コードを変更しない)

私は最近このメソッドを開発しました。セルフホストの Ghost だけでなく、ホスティングプロバイダーが提供する Ghost インスタンスにも適用できます。後者の場合、適切なアーキテクチャ計画と、最終的な Ghost インスタンスのプロキシとして機能する小規模サーバーの購入が必要です。

このメソッドで使用するアーキテクチャ:
Nginxサーバー ← Node.jsミドルウェア ← ゴーストインスタンス

ユーザーのブラウザは、ミドルウェアのアップストリームを含む Nginx サーバーにリクエストを送信します。すべてのリクエストは、場所に関係なく、ミドルウェアにプロキシされます。

このミドルウェアは、express-http-proxy (https://github.com/villadora/express-http-proxy) ライブラリが追加された Node.js で実行される Express サーバーであり、作業が大幅に簡素化されます。 Ghost インスタンスと通信するようにプロキシを構成します。 Express-http-proxy ライブラリには、「プロキシされたサーバーの応答を装飾する」ために使用できる userResDecorator プロパティがあります。簡単に言うと、Ghost からの応答をユーザーのブラウザに送信する前に変更できます。

userResDecorator はメインスレッドをブロックしないように非同期になります。ヘルパー作成時の非同期処理の話に戻ります。現時点では、ユーザーのブラウザー要求のすべてを装飾する必要があるわけではないことを知っておく必要があります。したがって、最初のステップは、Ghost からの応答の content-type ヘッダーを確認することです。これを次のように実行し、text/html であるかどうかを比較して、ユーザーに返される HTML ドキュメントのみを装飾できます。

const path = require('path');

module.exports = {
    activate: function activate(ghost) {
        ghost.helperService.registerDir(path.resolve(__dirname, './lib/helpers'));
    }
};

この条件ステートメントでは、htmlContent の変更を開始できますが、なぜそれが必要なのでしょうか? Ghost テーマのカスタム ヘルパーの基盤を構築することから始めましょう!

この記事では、テーマの Index.hbs ファイル (ホームページ) にカスタム ヘルパーを作成します。 Handlebars テンプレートの表示される場所に、サンプルのカスタム ヘルパーを追加し、{{hello_world}} という名前を付けます。

⚠️ 次に、それをホームページの目に見える場所に配置します。ただし、ゴースト ページを更新するとどうなるかに注目してください。

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

module.exports = function uppercase(text) {
    return `${text.toUpperCase()}`;
};

この変数には、Ghost インスタンスからの応答がページの完全な HTML として含まれています。この応答が Ghost インスタンスのホームページであると想像してください。 HTML コンテンツには、プレーン テキストとして表示されるプレーン テキスト {{hello_world}} も含まれます。カスタム ヘルパーがこの形式の場合は、ミドルウェアの Handlebars.js (https://handlebarsjs.com/) を使用してコンパイルできます。最初にパッケージ マネージャー (例: npm: npm install handlebars) を使用してライブラリをインストールし、コードに追加することを忘れないでください: 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;

うわー!これで、Handlebars.js を使用して HTML をコンパイルしてレンダリングできましたが、まだ完了ではありません。カスタム ヘルパー {{hello_world}} を登録する必要があります。できれば Handlebars.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');

ミドルウェア サーバーを再起動し、上記のヘルパーを登録すると、ヘルパーから返されたテキストと現在の日付と時刻を含むレンダリングされたヘルパーがブラウザーに表示されます。

この段階で、ミドルウェア サーバー コードに追加する追加のカスタム ヘルパーを使用して Ghost テーマを拡張できます。

安全

ある時点で、ヘルパーにさまざまなものを返したいと思うかもしれません。デフォルトでは、ライブラリは XSS 攻撃から保護しますが、SafeString メソッドを使用すると、この保護は機能しなくなります。可能な限り使用を避けてください。

もう一つ!ユーザーが投稿の下のコメント セクションにそのようなヘルパーを追加し、パラメータに悪意のあるコンテンツを追加すると想像してください。セキュリティに注意してください。たとえば、すべての HTML を完全にレンダリングすると、XSS 攻撃に対して脆弱になる可能性があります。 Handlebars.js を特定の閉じた領域でコンパイルしてレンダリングすることをお勧めします。必要に応じて、cheerio (https://cheerio.js.org/) ライブラリを使用して HTML を解析し、ハンドルバーをレンダリングできます。以下は、前のレンダリング コードを変更して安全を確保する方法の例です:

const path = require('path');

module.exports = {
    activate: function activate(ghost) {
        ghost.helperService.registerDir(path.resolve(__dirname, './lib/helpers'));
    }
};

スクリプトの先頭にライブラリの初期化を忘れずに追加してください: const asyncHelpers = require('handlebars-async-helpers');。 handlebars-async-helpers とハンドルバーの間のバージョンの競合によりインストール時に問題が発生した場合は、ハンドルバーを ^4.7.6 にダウングレードしてください。残念ながら、非同期ヘルパー ライブラリはしばらくメンテナンスされていませんでしたが、実際にはまだ動作しています。

データベース通信とオブジェクト

Ghost でデータベース クエリを実行して、たとえば現在の投稿を取得したい場合、それは可能であり、難しくありません。明確で高速な SQL クエリ ビルダーである knex (https://knexjs.org/) のようなライブラリを使用できます。これには handlebars-async-helpers が必要になることに注意してください。 Ghost のデータベースに接続するために knex を適切に設定します。

knex を db 変数として初期化し、次のコードを試してください:

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

module.exports = function uppercase(text) {
    return `${text.toUpperCase()}`;
};

次に、Ghost テーマの post.hbs テンプレートに、ヘルパー {{post_title uuid="{{uuid}}"}} を追加します。この例では、{{uuid}} が取得され、Ghost で使用可能なヘルパーとして渡され、ヘルパーの uuid フィールドに値が入力され、カスタム ヘルパーによって投稿タイトルが表示されます。

axios を使用して Ghost Content API への HTTP リクエストを行うこともできますが、これは直接データベース通信よりも大幅に遅くなります。

パフォーマンス

速度の点ではミドルウェアベースのソリューションが最適ではないかもしれないことは承知していますが、私は個人的にこのソリューションを使用していますが、ページの読み込み時間の大幅な短縮には気づきませんでした。単一リクエストの平均応答時間は 100 ミリ秒未満 (express-status-monitor による) で、すべてのページでデータベースから値を取得するカスタム ヘルパーを使用しています。

もちろん、キャッシュ メカニズムを追加してミドルウェアのパフォーマンスを向上させたり、express-http-proxy の代わりに代替ソリューションを使用したりすることもできます。

アーキテクチャの実装

Docker または別のコンテナ化メカニズムを使用します。私は自分のプロジェクトでそれを使用しましたが、とてもうまくいきました。 Ghost および Ghost、Nginx、Node.js イメージのデータベース イメージを追加します。それらを共有ネットワーク (ドライバー: ブリッジ) に接続し、それに応じて Nginx と Node.js サーバーを構成します。これはすべて非常に簡単です!

以上がGhost でカスタム ハンドルバー ヘルパーを作成しましょう!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。