”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 在Ghost中制作自定义的车把助手!

在Ghost中制作自定义的车把助手!

发布于2025-04-08
浏览:526

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]删除
最新教程 更多>
  • 同实例无需转储复制MySQL数据库方法
    同实例无需转储复制MySQL数据库方法
    在同一实例上复制一个MySQL数据库而无需转储在同一mySQL实例上复制数据库,而无需创建InterMediate sqql script。以下方法为传统的转储和IMPORT过程提供了更简单的替代方法。 直接管道数据 MySQL手动概述了一种允许将mysqldump直接输出到MySQL clie...
    编程 发布于2025-07-18
  • 左连接为何在右表WHERE子句过滤时像内连接?
    左连接为何在右表WHERE子句过滤时像内连接?
    左JOIN CONUNDRUM:WITCHING小时在数据库Wizard的领域中变成内在的加入很有趣,当将c.foobar条件放置在上面的Where子句中时,据说左联接似乎会转换为内部连接。仅当满足A.Foo和C.Foobar标准时,才会返回结果。为什么要变形?关键在于其中的子句。当左联接的右侧值...
    编程 发布于2025-07-18
  • 如何处理PHP文件系统功能中的UTF-8文件名?
    如何处理PHP文件系统功能中的UTF-8文件名?
    在PHP的Filesystem functions中处理UTF-8 FileNames 在使用PHP的MKDIR函数中含有UTF-8字符的文件很多flusf-8字符时,您可能会在Windows Explorer中遇到comploreer grounder grounder grounder gro...
    编程 发布于2025-07-18
  • 如何使用Regex在PHP中有效地提取括号内的文本
    如何使用Regex在PHP中有效地提取括号内的文本
    php:在括号内提取文本在处理括号内的文本时,找到最有效的解决方案是必不可少的。一种方法是利用PHP的字符串操作函数,如下所示: 作为替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式来搜索特...
    编程 发布于2025-07-18
  • 为什么在我的Linux服务器上安装Archive_Zip后,我找不到“ class \” class \'ziparchive \'错误?
    为什么在我的Linux服务器上安装Archive_Zip后,我找不到“ class \” class \'ziparchive \'错误?
    class'ziparchive'在Linux Server上安装Archive_zip时找不到错误 commant in lin ins in cland ins in lin.11 on a lin.1 in a lin.11错误:致命错误:在... cass中找不到类z...
    编程 发布于2025-07-18
  • 为什么我在Silverlight Linq查询中获得“无法找到查询模式的实现”错误?
    为什么我在Silverlight Linq查询中获得“无法找到查询模式的实现”错误?
    查询模式实现缺失:解决“无法找到”错误在银光应用程序中,尝试使用LINQ建立错误的数据库连接的尝试,无法找到以查询模式的实现。”当省略LINQ名称空间或查询类型缺少IEnumerable 实现时,通常会发生此错误。 解决问题来验证该类型的质量是至关重要的。在此特定实例中,tblpersoon可能需...
    编程 发布于2025-07-18
  • 如何正确使用与PDO参数的查询一样?
    如何正确使用与PDO参数的查询一样?
    在pdo 中使用类似QUERIES在PDO中的Queries时,您可能会遇到类似疑问中描述的问题:此查询也可能不会返回结果,即使$ var1和$ var2包含有效的搜索词。错误在于不正确包含%符号。通过将变量包含在$ params数组中的%符号中,您确保将%字符正确替换到查询中。没有此修改,PDO...
    编程 发布于2025-07-18
  • 编译器报错“usr/bin/ld: cannot find -l”解决方法
    编译器报错“usr/bin/ld: cannot find -l”解决方法
    错误:“ usr/bin/ld:找不到-l “ 此错误表明链接器在链接您的可执行文件时无法找到指定的库。为了解决此问题,我们将深入研究如何指定库路径并将链接引导到正确位置的详细信息。添加库搜索路径的一个可能的原因是,此错误是您的makefile中缺少库搜索路径。要解决它,您可以在链接器命令中添加...
    编程 发布于2025-07-18
  • PHP与C++函数重载处理的区别
    PHP与C++函数重载处理的区别
    作为经验丰富的C开发人员脱离谜题,您可能会遇到功能超载的概念。这个概念虽然在C中普遍,但在PHP中构成了独特的挑战。让我们深入研究PHP功能过载的复杂性,并探索其提供的可能性。在PHP中理解php的方法在PHP中,函数超载的概念(如C等语言)不存在。函数签名仅由其名称定义,而与他们的参数列表无关。...
    编程 发布于2025-07-18
  • 反射动态实现Go接口用于RPC方法探索
    反射动态实现Go接口用于RPC方法探索
    在GO 使用反射来实现定义RPC式方法的界面。例如,考虑一个接口,例如:键入myService接口{ 登录(用户名,密码字符串)(sessionId int,错误错误) helloworld(sessionid int)(hi String,错误错误) } 替代方案而不是依靠反射...
    编程 发布于2025-07-18
  • 如何在Java字符串中有效替换多个子字符串?
    如何在Java字符串中有效替换多个子字符串?
    在java 中有效地替换多个substring,需要在需要替换一个字符串中的多个substring的情况下,很容易求助于重复应用字符串的刺激力量。 However, this can be inefficient for large strings or when working with nu...
    编程 发布于2025-07-18
  • FastAPI自定义404页面创建指南
    FastAPI自定义404页面创建指南
    response = await call_next(request) if response.status_code == 404: return RedirectResponse("https://fastapi.tiangolo.com") else: ...
    编程 发布于2025-07-18
  • 如何使用Python有效地以相反顺序读取大型文件?
    如何使用Python有效地以相反顺序读取大型文件?
    在python 反向行读取器生成器 == ord('\ n'): 缓冲区=缓冲区[:-1] 剩余_size- = buf_size lines = buffer.split('\ n'....
    编程 发布于2025-07-18
  • Python读取CSV文件UnicodeDecodeError终极解决方法
    Python读取CSV文件UnicodeDecodeError终极解决方法
    在试图使用已内置的CSV模块读取Python中时,CSV文件中的Unicode Decode Decode Decode Decode decode Error读取,您可能会遇到错误的错误:无法解码字节 在位置2-3中:截断\ uxxxxxxxx逃脱当CSV文件包含特殊字符或Unicode的路径逃...
    编程 发布于2025-07-18
  • Go语言垃圾回收如何处理切片内存?
    Go语言垃圾回收如何处理切片内存?
    Garbage Collection in Go Slices: A Detailed AnalysisIn Go, a slice is a dynamic array that references an underlying array.使用切片时,了解垃圾收集行为至关重要,以避免潜在的内存泄...
    编程 发布于2025-07-18

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3