뚝딱뚝딱 Ghost로 기술 블로그 만들기  두 번째 시리즈로 고스트 블로그 테마 수정 과정을 소개한다.  아직 고스트(Ghost) 플랫폼에 대해서 잘  모른다면, 설치와 호스팅 편을 읽고 오길 바란다. 모든 단계를 건너뛰고 바로 이 블로그에 적용된 테마를 그대로 적용하거나 수정하고 싶다면, 깃허브 저장소(casper-dev-blog-theme) 에서 소스코드를 다운받아 설치할 수 있다.

사전 설치

Node , Yarn,  Gulp가 반드시 설치되어야 한다.

ghost-cli 패키지를 전역으로 설치한다. ghost-cli는 고스트를 설치 및 구성하고 항상 최신 상태로 유지할 수 있는 명령형 인터페이스이다.

npm install ghost-cli@latest -g

고스트 블로그 설치

먼저 새로운 프로젝트 폴더를 만들고 아래 ghost install local 명령어를 실행해 고스트를 로컬에 설치한다.

$ mkdir ghost-blog && cd ghost-blog 
$ ghost install local

설치가 정상적으로 되었다면 콘솔에 아래와 같은  메시지가 보일 것이다.

Ghost was installed successfully! To complete setup of your publication, visit: 

    http://localhost:2368/ghost/

설치 후 자동으로 로컬 서버가 실행된다. http://localhost:2368 을 열어보면 고스트 블로그 첫 화면을 볼 수 있다. http://localhost:2368/ghost 에서 관리자를 생성하고 테스트 글을 작성 또는 수정해보자. ghost-cli는 SQLite3를 기본 탑재되어 있으며 모든 데이터는 /content/data 폴더에 저장된다.  

고스트는 ghost 명령어로 중지할 때까지 계속 실행된다.

  • ghost stop  고스트를 중지한다.
  • ghost start 고스트를 시작한다.
  • ghost log 로그를 출력한다.
  • ghost ls 설치된 모든 고스트 블로그 목록을 확인한다.

Casper 테마 커스터마이징

고스트 블로그 테마가 저장되는  content/themes 폴더를 열어보면 기본 테마인 casper 가 있음을 확인할 수 있다. casper 폴더 전체를 복사하고 폴더 이름을 바꾼다. (예: casper-sujin)

만약 실수로 casper 폴더가 삭제되었거나 문제가 생겼다면 content/themes 경로에서깃허브 저장소 https://github.com/TryGhost/Casper 에서 다운 받는다.

content/themes/casper-sujin 경로에서 의존 패키지를 설치하고 로컬 서버를 실행한다. (이 때 ghost 가 실행되어 있어야 한다.)

yarn install
yarn dev

gulp 가 실행되어  content/themes/ 내 css, js, hbs 파일이 변경될 때마다 소스코드가 자동으로 빌드되어assets/built/ 에 저장된다.  /assets/built 폴더는 건드리지  않는다.

관리자 화면에서 디자인 패널을 클릭해(http://localhost:2368/ghost/#/settings/design) 새로 만든 테마인 casper-sujinactivate 버튼을 클릭해 블로그 테마를 바꾼다.

이제  기본적인 설치가 끝났으니 본격적으로 커스터 마이징을 해보도록 하자.

1. disqus 댓글 플러그인 설치

https://disqus.com/admin/create/ 에서 disqus 사이트를 생성한다. 이때  내 disqus 게정 주소가 (e.g http://myblog.disqus.com)이라면 myblog가 shortname 이 된다.

이 shortname는 전역 변수를 사용해 정의할 것이다.

이제  post.hbs 파일의  87번째 줄에 비활성된 코드 <section class="post-full-comments">를 찾을 수 있을 것이다. 이 부분에 바로 disqus 스크립트를 넣을 수 있지만,댓글 컴포넌트로 만들 수 있다. partials 폴더 내  disqus.hbs 새 파일을 만들고 아래 코드를  복사 붙여넣기 한다.

<section class="post-full-comments">
  <div id="disqus_thread"></div>
  <script>
    var disqus_config = function () {
      this.page.url = "{{url absolute="true"}}";
      this.page.identifier = "ghost-{{comment_id}}"
    };
    (function () {
      var d = document, s = d.createElement('script');
      s.src = 'https://' + window.disqus_shortname + '.disqus.com/embed.js';
      s.setAttribute('data-timestamp', +new Date());
      (d.head || d.body).appendChild(s);
    })();
  </script>
</section>

게시물 템플릿인 post.hbs 에서 </article> 부분에 {{> disqus}} 를 추가한다. 이 부분이 바로 댓글 컴포넌트가 들어갈 자리이다.

관리자 페이지 메뉴 settings > code-injection 페이지로 들어가  Site Footer 부분에 스크립트 태그에 disqus_shortname을 정의한다.

<script>
    var disqus_shortname = ""
</script>

disqus 플러그인은 localhost 로컬 웹 서버를  지원하지 않기 때문에 아래와 같은 메시지가 보일 것이다.

2. 테마 교체하기

아직 해야할 일이 더 많이 남아있지만, 수정한 테마를 압축하고 반영하는 방법을 알아보자.

gulp 테스크 패키지 명령어인 zip 실행하면 dist/<테마>.zip 폴더가 만들어진다.

yarn zip

실제 운영 중인 블로그 관리자 페이지(https://블로그주소/ghost/#/settings/design/uploadtheme)에 들어가서 zip 파일을 업로드하고 activate버튼을 눌러 테마를 바꿀 수 있다.

다시 관리자 화면 내 code injection 페이지(https://블로그-주소/ghost/#/settings/code-injection)에서 전역 변수를 선언한다. 블로그 게시글 하단에 disqus 댓글 플러그인이 잘 실행되는지 확인하자.

3. Prism.js 코드 하이라이트 기능 추가하기

코드 태그 구문에 문법을 강조하기 위해 구문 하이라이트(Syntax Highlighter) 라이브러리인 Prism.js을 설치할 단계다.

https://블로그-주소/ghost/#/settings/code-injection 에서 SiteHeader과 SiteFooter에 CDN을 추가해 사용할 수 있지만, 여기서는 기존 템플릿 코드를 수정한다.

Prism.js 에서사용하고자 하는 언어를 선택한 후 각각  js와 css 파일을 다운받을 수 있다. 또는  깃허브 저장소에서 jscss 파일을 다운 받을 수 있다.  이제 themes/<테마-이름>/assets/ 에서 js, css 각 폴더에 저장한다.

앞에서 댓글 컴포넌트를 만든 것과 마찬가지로 이번에도 별도 파일을 만들어 관리할 수 있다. partials 폴더에 prism.hbs 파일을 만들어 아래 코드를 추가한다.

<link rel="stylesheet" type="text/css" href="{{asset "built/prism.css"}}" />
<script type="text/javascript" src="{{asset "built/prism.js"}}"></script>

default.hbs는  기본 템플릿으로 code-injection 에서 정의된 {{ghost_head}}, {{ghost_foot}} 을 포함한다. <header> 태그 내에 {{>prism}}추가한다.

4. 수학 수식 KaTeX 추가하기

KaTeX는 칸 아카데미에서 만든 오픈 소스 수학 입력 수식기 라이브러리이다. 기존 LaTeX는 이미지 형식으로 변환되어 깔끔하게 렌더링되지 않은 문제가 있었다. KaTeX는 수학 수식을 SVG로 그려 모든 웹 브라우저에서 사용 가능하다. 깔끔한 타이포와 빠른 성능, 서버 사이드 렌더링이 큰 장점이다. MathJax보다 렌더링 속도가 더 빠르고 기존 LaTeX 문법과 거의 유사하다.

이번에도 partials 폴더에서 katex.hbs 파일을 만들고 아래 코드를 추가한다.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.0/dist/katex.min.css"
  integrity="sha384-BdGj8xC2eZkQaxoQ8nSLefg4AV4/AwB3Fj+8SUSo7pnKP6Eoy18liIKTPn9oBYNG" crossorigin="anonymous">

<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.0/dist/katex.min.js"
  integrity="sha384-JiKN5O8x9Hhs/UE5cT5AAJqieYlOZbGT3CHws/y97o3ty4R7/O5poG9F3JoiOYw1" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.0/dist/contrib/auto-render.min.js"
  integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI" crossorigin="anonymous"></script>

<script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function () {
    renderMathInElement(document.body, {
      delimiters: [
        { left: "$$", right: "$$", display: true },
        { left: "$", right: "$", display: false },
      ]
    });
  });
</script>

구분자(delimiters) 를 지정해 마크업과 혼용해 수학수식을 사용할 수 있다. 인라인 수식일 경우 $, 블록일 경우 $$ 로 수식을 열고 닫는다.

Markdown + kaTex Render as
inline
The quadratic formula is $-b \pm \sqrt{b^2 - 4ac} \over 2a$

The quadratic formula is $-b \pm \sqrt{b^2 - 4ac} \over 2a$
block
The quadratic formula is $$-b \pm \sqrt{b^2 - 4ac} \over 2a$$
The quadratic formula is $$-b \pm \sqrt{b^2 - 4ac} \over 2a$$

default.hbs 파일 내 <head> 태그에 {{> katex}}추가한다.  수학 수식을 입력해보고 어떻게 렌더링되는지 확인해보자.

5. 폰트 수정 및 css 스타일링

한국어와 영어를 모두 지원하는 폰트로 바꿔보자. 구글 웹 폰트 CDN를 사용할 수 있지만 파일 크기가 너무 크면 웹 폰트가 적용된 글자가 화면에 표시될 때까지 시간이 지연되는 문제가 생긴다. 최적화를 위해 합축된 폰트 형식인 WOFF와 WOFF2을 셀프 호스팅해 사용하는 것이 좋다. WOFF2 형식은 30~50% 더 압축된 형식이다.  따라서 폰트 파일과 CSS 속성을 완전히 제어할 수 있어야 한다. 마리오 랜플(Mario Ranftl)이 제작한 google-webfonts-helper 을 사용해 브라우저 사양, charsets, 글꼴 타입에 따라 @font-face 이 정의된 css 코드를 자동으로 만들 수 있다.  

예를 들어, 구글 웹 폰트 중 Noto Sans KR 폰트를 사용한다고 가정해보자.  regular과 700 타입을 선택한 후 Copy CSS에서 최신 브라우저 용인 Modern Browsers를 선택한 후 다운로드 한다.

 assests 내 fonts 새 폴더를 만들고 다운 받은 폰트 파일을 저장한다. cssfonts.css 새 파일을 만들고 생성된 css를 추가한다.

default.hbs<header>fonts.css 파일을 링크한다.

<link rel="stylesheet" type="text/css" href="{{asset "built/fonts.css"}}" />

이후 글 제목, 본문에 css 폰트 속성을 Noto Sans KR 으로 바꾼다.  별도로 css 파일을 만들어 클래스 속성을 오버라이딩해 재정의하면 보다 편하게 스타일을 관리할 수 있다.

6. let's encrypt 보안 인증서 확인하기

ghost-cli는 let's encrypt 보안인증서가 기본적으로 내장되어 있다. 인증서가 만료되더라도  쉽게 갱신 가능하다. 크롬 브라우저에서 주소 창 왼쪽 자물쇠 버튼을 클릭하면 보안 인증서와 만료일을 확인할 수 있다.

만약 인증서가 만료되었거나 오류가 생겼다면, 로컬 콘솔에서 ssh로 접속해 ghost setup ssl 를 실행해 인증서를 다시 받으면 된다. ghost 명령어는 반드시 ghost가 설치된 폴더에서 실행 가능함을 잊지 말자.

$ ssh root@ip주소
$ root@ghost-blog:~#sudo -i -u ghost-mgr // ghost 관리자 계정으로 전환한다.
$ ghost-mgr@ghost-blog:/var/www$ cd /var/www/ghost // ghost가 설치된 경로로 이동한다.
$ ghost setup ssl // 인증서를 갱신한다.

만약 고스트 초기 설치 시 url이 https가 아니라 http로 설정되어 있을 경우, 크롬에서 혼합 콘텐츠 오류 메시지(Mixed Content)가 출력될 수 있다.

이미지 주소가 http를 가리키므로 https 페이지에서 혼합 콘텐츠가 있음을 경고하는 메시지이다. ghost config url https://내-블로그-주소&& ghost restart 명령어를 실행해 다시 고스트에 url를 https로 설정하고 재실행한다.

$ ghost-mgr@ghost-blog:/var/www/ghost$ ghost config url https://내-블로그-주소 && ghost restart
Successfully set 'url' to 'https://내-블로그-주소'
+ sudo systemctl is-active ghost_sujinlee-me
+ sudo systemctl restart ghost_sujinlee-me
✔ Restarting Ghost

지금까지 ghost 기본 테마인 casper에 기능을 추가하고 템플릿과 스타일을 바꾸어보면서 ghost 테마 개발 과정을 맛보았다.

나의 경우 소셜 계정 바로가기 아이콘에 미디엄, 링크드인, 깃허브 등 다양한 소셜 링크를 추가할 수 있게 개선했다. 글 목록 카드 내  {{author}} 을 없애고, disqus 댓글 수를 추가했다. 구글 애널리틱스도 추가해 블로그 방문자의 데이터를 수집하고 분석도 해보고 있다. 이처럼 casper를 보일러 플레이트 코드로 활용해 내가 원하는 디자인으로 변경하거나 여러 기능을 추가해 나에게 꼭 맞는 맞춤형 테마를 만들 수 있다.

지금까지 뚝딱뚝딱 망치질을 하며 나만의 기술 블로그를 만들어 보았다. 이제 근사한 집을 지었으니 이야기로 하나 둘씩 차곡차곡 채워가야 할 때다. 하지만 무엇을, 어떻게, 써야할지 늘 걱정이다.

최근 나는 데이터 캠프(datacamp) 수석 데이터 과학자인 데이비드 로빈슨(David Robinson)은 그의 글, '주목받는 데이터 과학자가 되는 법 : 블로그를 시작하라(Advice to aspiring data scientists: start a blog) ' 에서 그 해답을 찾을 수 있었다. 그는 글을 쓰며 '기술을 연마하고 있다(practice the relevant skills)'라고 말한다. 블로그를 본격적으로 시작하기 전 블로그 키워드와 글쓰기 주제를 먼저 정할 것을 강조했다. 그의 키워드는 데이터 정리, 통계, 머신 러닝, 시각화, 커뮤니케이션으로 실무와 프로젝트를 통해 배우고 익힌 것들을 중심으로 글을 작성하고 있다. 대학원생 시절, 그는 Bayes estimation 라는 주제로 짧은 글을 작성했다. 당시 이와 관련된 자료가 부족했기에 많은 독자들로 부터 도움이 되었다는 칭찬을 들었다. 이후 그는 자신의 블로그 글을 발전시켜 책을 완성해 출판했다. 블로그를 통해 그는 전 세계 데이터 과학자들과 네트워크를 형성했고, 더 넓은 세상과 공유하고 소통할 수 있었다.

유투브 채널 심플 프로그래머로 유명한 존 소메즈(John Somez)는 그의 최신 저서, '완벽한 개발자 인생 로드맵 (The Complete Software Developer's Career Guide)'에서 '개발자에게 블로그란 제다이의 광선검'과 같은 것이라 말했다.  그는 '블로그는 자신의 경력과 발전을 기록하는데 도움이 될 뿐만 아니라 자신이 과거에 쓴 문제해결 방법을 확인해 볼 수 있는 참고자료'이라며 블로그를 운영할 것을 적극 권장했다.

그는 이제 막 블로그를 시작하는 개발자들에게 '블로그를 직접 만들려 하지 말고 워드프레스와 같은 기성 솔루션을 써라'라고 거듭 강조했다. 맞는 말이다. 감히 주제넘게 꼬투리를 잡자면, 나는 워드프레스보다 고스트가 더 가장 유연하고 사용하기 쉬운 블로그 플랫폼이라 평한다. 자, 이제 동기부여 메시지는 그만하고 글 좀 써볼까?