在 Ghost 中制作自定义车把助手!
本文适合许多发现 Ghost (https://ghost.org/docs/themes/helpers/) 提供的标准助手不够的开发人员和主题创建者。寻找方法来扩展使用 Ghost 提供的 Handlebars 的主题的功能是完全正常的。在发表这篇文章并找到适合我的主题的解决方案之前,我搜索了整个互联网并亲自对 Ghost 的源代码进行了分析。
方法一(修改核心代码)
我发现可以使用额外的帮助程序来扩展 Ghost 的源代码。我通过在 current/core/frontend/apps 中添加一个新目录来实现这一点。我使用了一个名为 amp 的现有“应用程序”的示例,其代码非常简单,开始创建主题中可用的新助手。在这些现有的应用程序中,结构很简单,因为助手在 lib/helpers 中注册。在此过程的最后,您需要将 apps 中的目录名称添加到 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 后,一切都应该准备就绪。
方法二(不修改核心代码)
我最近开发了这个方法,您不仅可以将其应用于自托管 Ghost,还可以应用于托管提供商提供的 Ghost 实例。在后一种情况下,需要适当的架构规划并购买一台小型服务器来充当最终 Ghost 实例的代理。
我们将在此方法中使用的架构:
Nginx 服务器 ← Node.js 中间件 ← Ghost 实例
用户的浏览器向Nginx服务器发送请求,Nginx服务器包含中间件的上游。所有请求,无论位于何处,都将被代理到中间件。
中间件是一个在 Node.js 中运行的 Express 服务器,添加了express-http-proxy (https://github.com/villadora/express-http-proxy) 库,这显着简化了工作。我们配置代理来与 Ghost 实例通信。 express-http-proxy 库有一个 userResDecorator 属性,我们可以使用它来“装饰代理服务器的响应”。简单地说,我们可以在将 Ghost 的响应发送到用户的浏览器之前对其进行修改。
我们的 userResDecorator 将是异步的,以免阻塞主线程。创建助手时我们将回到异步处理的主题。目前,您需要知道并非用户浏览器请求的所有内容都需要进行修饰。因此,第一步是检查 Ghost 响应的内容类型标头。您可以按如下方式进行操作,然后比较是否为 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}}。
⚠️ 然后,我将其放在主页上的可见位置 - 但请注意当我刷新 Ghost 页面时会发生什么!
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 handbars 并将其添加到您的代码中:const handbars = 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 并在必要时渲染 Handlebars。以下是如何通过修改之前的渲染代码来保护自己的示例:
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 和handlebars 之间的版本冲突而遇到安装问题,只需将handlebars 降级到^4.7.6。不幸的是,异步帮助器库已经有一段时间没有维护了,但它在实践中仍然有效。
数据库通信和对象
如果你想在 Ghost 中进行数据库查询来获取,例如当前的帖子,这是可能的,而且并不困难。您可以使用像 knex (https://knexjs.org/) 这样的库,它是一个清晰且快速的 SQL 查询生成器。请记住,为此您需要handlebars-async-helpers。正确配置 knex 以连接到 Ghost 的数据库。
将 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、Nginx 和 Node.js 映像添加 Ghost 和数据库映像。将它们连接到共享网络(驱动程序:bridge),相应地配置 Nginx 和 Node.js 服务器 - 这一切都非常简单!
以上是在 Ghost 中制作自定义车把助手!的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

JavaScript不需要安装,因为它已内置于现代浏览器中。你只需文本编辑器和浏览器即可开始使用。1)在浏览器环境中,通过标签嵌入HTML文件中运行。2)在Node.js环境中,下载并安装Node.js后,通过命令行运行JavaScript文件。
