>웹 프론트엔드 >JS 튜토리얼 >Ghost에서 맞춤형 핸들바 도우미를 만들어보세요!

Ghost에서 맞춤형 핸들바 도우미를 만들어보세요!

Barbara Streisand
Barbara Streisand원래의
2025-01-07 00:08:41141검색

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 미들웨어 ← Ghost 인스턴스

사용자의 브라우저는 미들웨어의 업스트림이 포함된 Nginx 서버에 요청을 보냅니다. 위치에 관계없이 모든 요청은 미들웨어로 프록시 처리됩니다.

미들웨어는 express-http-proxy(https://github.com/villadora/express-http-proxy) 라이브러리가 추가된 Node.js에서 실행되는 Express 서버로, 작업을 대폭 단순화합니다. 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()}`;
};

이 변수에는 페이지의 전체 HTML로 Ghost 인스턴스의 응답이 있습니다. 이 응답이 Ghost 인스턴스의 홈페이지라고 상상해 보세요. HTML 콘텐츠에는 일반 텍스트로 표시되는 일반 텍스트 {{hello_world}}도 포함됩니다. 사용자 정의 도우미가 이 형식인 경우 미들웨어에서 Handlebars.js(https://handlebarsjs.com/)를 사용하여 컴파일할 수 있습니다. 먼저 패키지 관리자를 통해 라이브러리를 설치해야 합니다(예: npm: npm install handlerbars). 그리고 이를 코드에 추가합니다: const handlerbars = 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를 컴파일하고 렌더링하는 것이 좋습니다. 필요한 경우 HTML을 구문 분석하고 핸들바를 렌더링하기 위해 Cherio(https://cheerio.js.org/) 라이브러리를 사용할 수 있습니다. 다음은 이전 렌더링 코드를 수정하여 자신을 보호할 수 있는 방법의 예입니다.

const path = require('path');

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

스크립트 시작 부분에 라이브러리 초기화를 추가하는 것을 잊지 마세요: const asyncHelpers = require('handlebars-async-helpers');. handlerbars-async-helpers와 핸들바 간의 버전 충돌로 인해 설치하는 데 문제가 발생하는 경우 핸들바를 ^4.7.6으로 다운그레이드하세요. 안타깝게도 비동기 도우미 라이브러리는 한동안 유지되지 않았지만 실제로는 여전히 작동합니다.

데이터베이스 통신 및 개체

예를 들어 현재 게시물을 가져오기 위해 Ghost에서 데이터베이스 쿼리를 만들고 싶다면 가능하며 어렵지 않습니다. 명확하고 빠른 SQL 쿼리 빌더인 knex(https://knexjs.org/)와 같은 라이브러리를 사용할 수 있습니다. 이를 위해서는 handlerbars-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 요청을 할 수도 있지만 이는 직접 데이터베이스 통신보다 속도가 상당히 느립니다.

성능

미들웨어 기반 솔루션이 속도 측면에서 최고가 아닐 수도 있다는 것을 알고 있지만 개인적으로 이 솔루션을 사용하고 있는데 페이지 로드 시간이 크게 떨어지는 것을 느끼지 못했습니다. 단일 요청의 평균 응답 시간은 100ms 미만이었고(express-status-monitor에 따르면) 모든 페이지의 데이터베이스에서 일부 값을 검색하는 사용자 지정 도우미를 사용합니다.

물론 캐싱 메커니즘을 추가하여 미들웨어 성능을 향상하거나 express-http-proxy 대신 대체 솔루션을 사용할 수도 있습니다.

아키텍처 구현

Docker 또는 다른 컨테이너화 메커니즘을 사용합니다. 나는 그것을 내 프로젝트에 사용했는데 훌륭하게 작동합니다. Ghost, Nginx 및 Node.js 이미지용 Ghost 및 데이터베이스 이미지를 추가합니다. 공유 네트워크(드라이버: 브리지)에 연결하고 그에 따라 Nginx와 Node.js 서버를 구성하세요. 모두 매우 간단합니다!

위 내용은 Ghost에서 맞춤형 핸들바 도우미를 만들어보세요!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.