」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 在Ghost中製作自定義的車把助手!

在Ghost中製作自定義的車把助手!

發佈於2025-04-08
瀏覽:441

Make Custom Handlebar Helpers in Ghost! 方法1(修改核心代码)

我发现可以使用其他帮助者扩展Ghost的源代码。我通过在Current/Core/core/Frontend/Apps中添加一个新目录来实现这一目标。我使用了一个名为AMP的现有“应用程序”的示例,该示例非常简单,以开始创建主题中可用的新帮手。在这些现有的应用程序中,该结构很简单,因为助手在LIB/助手中注册。在过程结束时,您需要将应用程序中的目录名称添加到apps.internal json部分中的当前/core/core/core/shardy/config/overrides.json。

在我们应用中的index.js文件的示例内容是:

接下来,在此应用程序的LIB目录中,我们创建了一个名为helpers的文件夹。在内部,我们创建了一个新文件,这将是在车把模板中被调用的助手的名称。例如,让我们命名为uppercase.js。


下面是这样的助手代码的一个示例,它只需将助手参数中给定文本的字母转换为大写:

const path = require('path');

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

不要忘记将应用程序目录的名称添加到当前/core/core/shardy/config/overrides.json。重新启动幽灵后,一切都应该准备就绪。

方法2(不修改核心代码)
我最近开发了这种方法,您不仅可以将其应用于自主幽灵,还可以应用于托管提供商提供的幽灵实例。在后一种情况下,它需要适当的体系结构计划,并购买一台小型服务器,该服务器将充当您的最终幽灵实例的代理。

我们将在此方法中使用的体系结构:
const {SafeString, escapeExpression} = require('../../../../services/handlebars');

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

用户的浏览器将请求发送到包含中间件上游的NGINX服务器。所有请求,无论位置如何,都将被代理到中间件。

我们的USERRESDECORATOR将是异步的,以免阻止主线程。在创建帮助者时,我们将返回异步处理的主题。目前,您需要知道,并非所有用户的浏览器请求都需要装饰的所有内容。因此,第一步是检查Ghost响应的内容类型标头。您可以按以下方式执行此操作,然后比较它是否是文本/HTML,仅装饰html文档返回给用户:

// where'proxyres'是您内部的代理响应'userresDecorator' const contentType = proxyres.headers ['content-type'] || ''; 如果(!contentType.includes('text/html')){ //返回原始内容,如果响应不是'text/html' 返回proxyresdata; } 令htmlcontent = proxyresdata.tostring('utf8'); //用“ htmlcontent”做某事并返回 返回htmlcontent;

在此条件语句中,我们可以开始修改HTMLCONTENT,但是为什么我们需要它呢?让我们从幽灵主题中为我们的自定义助手建立基础! 在本文中,我将在我主题的index.hbs文件(主页)中创建一个自定义助手。在车把模板中的可见位置中,我添加了一个示例自定义助手,将其命名{{hello_world}}。

{{!

刷新后,由于{{hello_world}} Ghost的默认帮助者中不存在助手,因此我从Ghost收到了错误消息。为了使我们的逻辑工作,我们必须逃脱这个助手,以免被Ghost的内置车把将其视为助手。

正确的方法是将此助手写为\ {{hello_world}}。这样,幽灵将其视为纯文本。刷新幽灵主页后,您应该看到纯文本{{hello_world}}。如果发生这种情况,您就在正确的轨道上。现在,让我们返回中间软件服务器文件,我们将在其中使用响应装饰器。

⚠️记住要在主题中逃脱自定义帮助者!不要忘记添加\字符。


让htmlcontent = proxyresdata.tostring('utf8');
// 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;
在此变量中,我们将Ghost实例的响应作为页面的完整HTML。想象一下,此响应是您幽灵实例的主页。 HTML内容还将包括我们的纯文本{{hello_world}},该{{hello_world}}显示为纯文本。如果我们的自定义助手处于此形式,我们可以在中间件中使用Handlebars.js(https://handlebarsjs.com/)对其进行编译。切记首先通过软件包管理器安装库,例如NPM:NPM安装式车把并将其添加到您的代码中:const hannebars = require(“ handlebars”);。

//用把手编译响应html,然后返回渲染模板 令htmlcontent = proxyresdata.tostring('utf8'); const模板= handlebars.compile(htmlcontent); htmlContent = template({});

哇!现在,我们已经使用handlebars.js编译并渲染了HTML,但我们还没有完成。我们仍然需要注册我们的自定义助手{{hello_world}}。添加以下代码,最好是在初始化handlebars.js之后:

{{!



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.

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.

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

let htmlContent = proxyResData.toString('utf8');

//仅在

内渲染车把>>>
在此代码中,我们的自定义帮助者和车把仅在
容器中呈现>> 异步处理
const path = require('path');

module.exports = {
    activate: function activate(ghost) {
        ghost.helperService.registerDir(path.resolve(__dirname, './lib/helpers'));
    }
};
如果您打算创建返回更多复杂数据的动态助手,则可能需要随着时间的推移在车把中实现异步助手。这在以下情况下很有用:


从数据库中获取值(例如,幽灵数据库)
// Returns 'Hello from middleware!' with the current timestamp
handlebars.registerHelper('hello_world', function (options) {
   return `Hello from middleware! ${new Date().toISOString()}`;
});
发送API请求并处理其响应

//用车把注册ASYNC帮助者 const hb =异步(车把); HB.RegisterHelper('Hello_world',async函数(options){ //您可以在这里使用等待! // ... });

记住在脚本开始时添加库初始化:const asynchelpers = require('handlebars-asasync-helpers');。如果您遇到由于车把-Async-Helpers和Handerbars之间的版本冲突而遇到的问题,只需将车把降低到 ^4.7.6即可。不幸的是,异步辅助库已经有一段时间没有维护,但它仍然在实践中起作用。

数据库通信和对象


如果要在Ghost中进行数据库查询以获取,例如当前帖子,这是可能的,而不是困难的。您可以使用knex(https://knexjs.org/)之类的库,这是一个清晰而快速的SQL查询构建器。请记住,为此,您将需要车把 - 迅速携带者。正确配置KNEX以连接到Ghost的数据库。

初始化knex为db变量,然后尝试以下代码:

//从数据库返回当前帖子标题 HB.RegisterHelper('post_title',async函数(options){ const uuid = options.hash.uuid; 尝试 { const {title} =等待db(“帖子”) 。选择(“标题”) 。 限制(1) 。第一的(); 返回标题; } catch(error){返回`错误:$ {error.message}`; } });

然后,在Ghost主题的post.hbs模板中,添加以下助手:\ {{post_title uuid =“ {{uuid}}}}}。在此示例中,{{uuid}}将被检索并作为幽灵中可用的助手,填充我们的助手的UUID字段,并导致自定义助手显示。
    您还可以使用AXIOS向Ghost Content API提出HTTP请求,但这比直接数据库通信要慢得多。
  • 表现
  • 我知道,基于中间件的解决方案在速度方面可能不是最好的,但是我个人使用了此解决方案,并且没有注意到页面加载时间的大幅下降。单个请求的平均响应时间不到100ms(根据Express-STATUS-MONITOR),我使用一个自定义助手,该助手从每个页面上的数据库中检索一些值。
  • 当然,您可以添加缓存机制来改善中间件性能或使用替代解决方案而不是Express-HTTP-Proxy。
实施体系结构


使用Docker或其他容器化机制。我已经在项目中使用了它,而且效果很好。为Ghost,nginx和node.js图像添加幽灵和数据库图像。将它们连接到共享网络(驱动程序:桥),配置nginx和node.js Server - 非常简单!

版本聲明 本文轉載於:https://dev.to/piotrbednarski/make-custom-handlebar-helpers-in-ghost-48nh?1如有侵犯,請聯繫[email protected]刪除
最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3