Ghost 테마 수정 3편: Prism.js 플러그인으로 코드블록 업그레이드하기

Ghost 블로그 코드블록에 Prism.js 플러그인으로 줄 번호와 복사 버튼 추가하기. 개발 초보자도 따라할 수 있는 단계별 가이드와 삽질 경험담 포함.

Ghost 테마 수정 3편: Prism.js 플러그인으로 코드블록 업그레이드하기
prism.js plug-in

지난 편에서 Ghost 테마에 Prism.js로 문법 강조를 적용했는데, 막상 써보니 뭔가 아쉬웠습니다. 다른 개발 블로그들을 보니 코드 옆에 줄 번호도 있고, 복사 버튼도 있더라고요. "나도 저런 걸 만들 수 있을까?" 하는 마음에 또 클루드 AI와 정다운 대화를 시작했습니다.

다행히 Prism.js에는 이런 기능들을 쉽게 추가할 수 있는 플러그인들이 있다는 걸 알게 되었어요. 제가 삽질하면서 배운 과정을 정리해봤습니다.

어떤 플러그인들을 추가할까?

검색해보니 정말 다양한 플러그인들이 있더라고요. 그 중에서 실용적이고 많이 사용되는 것들을 골라봤습니다:

  • Line Numbers: 코드 줄 번호 표시
  • Copy to Clipboard: 복사 버튼 추가
  • Line Highlight: 특정 줄 강조
  • Show Language: 코드 언어 표시

욕심내서 다 넣고 싶었지만, 일단 가장 필요한 줄 번호와 복사 버튼부터 시작하기로 했습니다.

방법 1: CDN으로 간단하게 추가하기

이전 편에서 CDN 방식을 사용하셨다면, 플러그인도 CDN으로 쉽게 추가할 수 있어요.

Ghost 관리자 → Settings → Code injection → Site Footer에 추가:

<!-- 기존 Prism.js 스크립트 아래에 추가 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-numbers/prism-line-numbers.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js"></script>

Site Header에 CSS 추가:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-numbers/prism-line-numbers.min.css">

하지만 저는 이전 편에서 파일을 직접 다운로드해서 커스터마이징했으니, 이번에도 같은 방식으로 진행해보겠습니다.

방법 2: 파일 다운로드 후 직접 적용하기

1단계: 플러그인 파일 다운로드

Prism.js 다운로드 페이지에서 이번에는 플러그인도 함께 선택합니다.

선택할 플러그인:

  • ✅ Line Numbers
  • ✅ Copy to Clipboard Button
  • ✅ Show Language (보너스로 추가해봤어요)
💡 삽질 경험담: 처음에 플러그인만 따로 다운받으려고 했는데, 의존성 때문에 꼬이더라고요. 그냥 처음부터 다시 받는 게 편해요.

2단계: 개발 환경 준비

qulf.js파일을 조금 수정합니다. main.js 와 prism.js를 빌드할 때 병합하는 라인을 수저해 줍니다.

~/ghost-dev/content/themes/ruby/gulpfile.js를 열어서 아래의 내용을 수정해 줍니다.

#수정 전
jsFiles.push(src(`assets/js/main.js`));

#수정 후
jsFiles.push(src(`assets/js/*.js`));

개발서버를 실행합니다.

cd ~/ghost-dev/content/themes/ruby
yarn dev

3단계: CSS 파일 업데이트

새로 다운받은 prism.css 파일로 기존 파일을 교체합니다. 이 파일에는 플러그인 스타일도 포함되어 있어요.

assets/css/misc/prism.css 파일을 새 파일로 교체하고, 이전에 설정했던 JetBrains Mono 폰트 설정을 다시 추가합니다:

/* 코드 블록 폰트 설정 */
code[class*="language-"],
pre[class*="language-"] {
    font-family: "JetBrains Mono", Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
    font-size: 0.9em;
}

/* 줄 번호 스타일 커스터마이징 */
.line-numbers .line-numbers-rows {
    border-right: 1px solid #999;
    padding-right: 0.8em;
    margin-right: 0.8em;
}

/* 복사 버튼 스타일 */
.copy-to-clipboard-button {
    position: absolute;
    top: 0.5em;
    right: 0.5em;
    padding: 0.25em 0.5em;
    background: #f5f2f0;
    border: 1px solid #ccc;
    border-radius: 3px;
    cursor: pointer;
    font-size: 0.8em;
}

.copy-to-clipboard-button:hover {
    background: #e6e3e0;
}

4단계: JavaScript 파일 업데이트

새로 다운받은 prism.js 파일의 내용으로 assets/js/main.js를 업데이트합니다.

5단계: HTML 클래스 추가 설정

줄 번호 기능을 사용하려면 코드 블록에 특별한 클래스를 추가해야 해요. Ghost에서는 이걸 자동으로 해주는 설정이 필요합니다.

assets/js/main.js에 다음 코드를 추가합니다:

지난 포스트에서 main.js 파일에 prism.js 내용을 붙혀넣기 했는데 이번에는 원본 main.js에 필요한 코드만 넣고 prism.js는 gulp파일에서 병합하는 설정으로 변경하려고 합니다.

#원본 main.js
(function () {
    pagination(true);
})();
#아래의 내용을 main.js파일에 추가해 줍니다.
  // Prism 기능 설정
function setupPrismFeatures() {
    // 모든 code 블록 처리 (마크다운에서 생성된 것 포함)
    const allCodeBlocks = document.querySelectorAll('pre code, pre[class*="language-"]');
    
    allCodeBlocks.forEach(function(element) {
        let block = element.tagName === 'PRE' ? element : element.parentElement;
        
        // 언어 클래스 처리
        let className = element.className || block.className;
        const languageMatch = className.match(/(?:language-|lang-)(\w+)(?:\{[\d,-]+\})?/);
        
        if (languageMatch) {
            const language = languageMatch[1];
            block.className = 'language-' + language + ' line-numbers';
            element.className = 'language-' + language;
            block.setAttribute('data-language', language.toUpperCase());
            
            // 줄 강조 문법 처리 {2,4-6}
            const highlightMatch = className.match(/\{([\d,-]+)\}/);
            if (highlightMatch) {
                block.setAttribute('data-line', highlightMatch[1]);
            }
        } else {
            // 기본 코드 블록
            block.classList.add('line-numbers');
        }
    });
}

// 복사 버튼 한글화
function setupCopyButtons() {
    const copyButtons = document.querySelectorAll('.copy-to-clipboard-button');
    copyButtons.forEach(function(button) {
        button.textContent = '복사';
        button.addEventListener('click', function() {
            this.textContent = '복사됨!';
            setTimeout(() => {
                this.textContent = '복사';
            }, 2000);
        });
    });
}

// DOM 로드 후 실행
document.addEventListener('DOMContentLoaded', function() {
    // Prism 로드 대기 후 실행
    const waitForPrism = setInterval(function() {
        if (typeof Prism !== 'undefined') {
            clearInterval(waitForPrism);
            
            setupPrismFeatures();
            Prism.highlightAll();
            
            setTimeout(setupCopyButtons, 300);
        }
    }, 50);
});

🤔 왜 이런 코드가 필요할까?: Ghost의 마크다운 파서가 자동으로 line-numbers 클래스를 추가해주지 않아서, JavaScript로 직접 추가해줘야 해요. 그리고 Prism.js와의 병합에서 문제가 발생해서 적용이 되지 않았습니다.  Prism.js가 먼저 로드되어야 하는데, 현재 코드가 DOM이 로드된 직후 실행되어 Prism.js가 아직 초기화되지 않았다고 클루드AI 말해줘서 클루드AI의 도움을 받아 위의 코드를 완성했습니다.

6단계: 테마 빌드 및 적용

# 개발 서버 중지
Ctrl + C

# 테마 압축
yarn zip

실제 사용해보니 어떨까?

줄 번호 기능

코드가 길어질 때 정말 유용해요. 특히 에러 메시지에서 "15번째 줄에 문제가 있다"고 할 때 바로 찾을 수 있어서 좋더라고요.

복사 버튼

독자들이 코드를 복사할 때 정말 편해요. 마우스로 드래그해서 복사하다가 실수로 줄 번호까지 복사되는 일도 없고요.

언어 표시

코드 블록 우상단에 언어가 표시되니까 한눈에 뭔지 알 수 있어서 좋네요.

추가 커스터마이징 팁

특정 줄 강조하기

Ghost 에디터에서 코드 블록을 작성할 때 이렇게 하면 특정 줄을 강조할 수 있어요:

```javascript{2,4-6}
const message = "Hello World";
console.log(message); // 이 줄이 강조됨
const number = 42;
const array = [1, 2, 3]; // 이 줄부터
const object = {}; // 여기까지
const result = true; // 여기까지 강조됨

삽질하면서 배운 것들

  1. 플러그인 의존성: 플러그인들끼리 의존성이 있어서 순서대로 로드해야 해요
  2. 클래스 자동 추가: Ghost는 자동으로 클래스를 추가해주지 않아서 JavaScript로 직접 해줘야 함
  3. CSS 우선순위: 기존 테마 스타일과 충돌할 수 있어서 CSS 우선순위를 잘 조정해야 함
  4. 모바일 대응: 복사 버튼이 모바일에서는 잘 안 보일 수 있어서 반응형으로 조정 필요

마무리

처음에는 "이런 고급 기능은 개발자만 할 수 있는 거 아닌가?" 생각했는데, 막상 해보니 생각보다 어렵지 않더라고요. 물론 중간에 몇 번 막혔지만, 클루드AI의 도움과 시행착오를 통해 결국 해냈습니다!

이제 제 블로그 코드 블록이 훨씬 전문적으로 보이네요. 줄 번호도 있고, 복사 버튼도 있고, 언어도 표시되고... 뭔가 진짜 개발 블로그 같아졌어요! 😄

다음에는 댓글 시스템이나 검색 기능 같은 걸 추가해보고 싶은데, 그것도 차근차근 배워서 공유해보겠습니다.

혹시 따라하시다가 막히는 부분이 있으시면 댓글로 남겨주세요. 저도 초보라서 완벽하지는 않지만, 함께 해결해보면 좋을 것 같아요! 🚀


참고 자료: