在 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等概念,增強了靈活性和異步編程能力。

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務
