Ghostのカスタムテーマ作成(その1)

Ghostのテーマは、content/themes/以下に配置すれば、管理機能から切り替えることができる。ghost構築直後は、Casperというシンプルなテーマが1つ入っており、テーマの自作に大いに参考になるので、一度参照すると良い。

カスタムテーマが正常に動作する為には、決められたファイル構成にしたがってファイルが配置されている必要がある。また、必須ファイルとそうでないファイルがあり、必須ファイルがないとロード時にエラーになる。下図の*requiredとあるファイルが必須ファイルで、それ以外はなくても良い。

またカスタムテーマのテンプレートファイルは*.hbsで、Handlebarsというテンプレートエンジンを採用しているらしい。

theme
├assets
│├css
││├screen.css
││└*.css
│├fonts
││└*.*
│├images
││└*.*
│└js
│  └*.js
├partials
│└*.hbs
├author.hbs
├default.hbs
├index.hbs  *required
├page.hbs
├post.hbs  *required
├tag.hbs
└package.json  *required

テーマの名称

package.jsonを開いて、テーマの名前とバージョンを記入する

{
  "name": "MyTheme",
  "version": "0.0.1"
}

default.hbs

ホームページ全体を構成するテンプレート。必須ファイルではない。
{{asset}}は、theme/assetに展開される。なのでassetディレクトリ以下にcssやjavascriptを配置すると整理しやすい仕組みになっている。また{{body}}の位置に後述するindex.hbsの内容が展開される。

<!DOCTYPE html>
<html>
<head>
	:
	<link rel="stylesheet" type="text/css" href="{{asset "css/xxx.css"}}" />
	 {{ghost_head}}
</head>
<body>
	 {{navigation}}
	<div class="site-wrapper">
		{{{body}}}
		:
	</div>
	:
	{{ghost_foot}}
	<script type="text/javascript" src="{{asset "js/xxx.js"}}"></script>
</body>
</html>

index.hbs

ホームページの顔となるレイアウトデザインになる。default.hbsの{{body}}に挿入される。
mainタグ内に投稿一覧が列挙されるが、partial/loop.hbsに処理が分担されている。
{{@blog}}は、グローバル変数のようなもので、どの位置からでも参照することができる変数で、ブログのtitleやdescriptionその他がある。

{{!< default}}
<header class="main-header" >
	<nav class="main-nav overlay clearfix">
		ナビゲーションメニュー
	</nav>
	<div class="vertical">
        <div class="main-header-content inner">
            <h1 class="page-title">{{@blog.title}}</h1>
            <h2 class="page-description">{{@blog.description}}</h2>
        </div>
    </div>
</header>
<main id="content" class="content" role="main">
	{{> "loop"}}
</main>

partials/loop.hbs

投稿一覧のレイアウトで、{{#foreach}}ヘルパーでposts(Ghostの設定で表示できる1ページあたりの最大投稿数)を列挙する処理になる。foreachループ内では、投稿ごとの{{article}},{{title}},{{image}},{{url}}
が展開される。

{{excerpt words="26"}}で、投稿内容の一部をwordsで指定した長さに従って、表示することができる。ほかにも投稿社名{{author.name}}、投稿日{{date format="DD MMMM YYYY"}}や、その投稿に付与されたN個のタグを{{#foreach tags}}で列挙できる。

<div class="center_area">
	<section id="results"></section>
	
	{{#foreach posts}}
	<div class="{{post_class}} post_entry clearfix">
		
		{{#if image}}
			<span><img class="post-img" src="{{image}}" alt="{{title}}"/></span>
		{{/if}}
		
		<header class="post-header">
			<h3 class="post-title"><a href="{{url}}">{{{title}}}</a></h3>
		</header>
		<section class="post-excerpt">
			<p>{{excerpt words="10"}} <a class="read-more" href="{{url}}">&raquo;</a></p>
		</section>
		<footer class="post-meta2">
			
			{{#if author.image}}
			<img class="author-thumb" src="{{author.image}}" alt="{{author.name}}" nopin="nopin" />
			{{else}}
			<img class="author-thumb" src="{{asset "image/user-image.png"}}" alt="{{author.name}}" nopin="nopin"/>
			{{/if}}
			
			<time class="post-date" datetime="{{date format='YYYY-MM-DD'}}">{{date format="DD MMMM YYYY"}}</time>
			{{#foreach tags}}
				<span class="label label-success"><a href="{{url}}" title="{{name}}" class="tag-{{id}}">{{name}}</a></span>
			{{/foreach}}
		</footer>
		
	</div>
	{{/foreach}}
	
	<div class="bottom_pagination_area text-center">
		{{pagination}}
	</div>
</div>

post.hbs

個別の投稿を表示するテンプレートdefault.hbsを継承する。
使えるヘルパーは、loop.hbsとほぼ同じである。

{{!< default}}
{{#post}}
<header class="main-header" >
	:
</header>
<main class="content" role="main">
	<article class="{{post_class}}">
		<header class="post-header">
			<h1 class="post-title">{{title}}</h1>
		</header>
		<section class="post-content">
            {{content}}
        </section>
		<footer class="post-footer">
			:
		</footer>
	</article>
</main>
<aside class="read-next">
	{{#next_post}}
	:
	{{/prev_post}}
</aside>
{{/post}}

tag.hbs

タグ選択したときに、そのタグが付与された投稿のインデックスページになる。
index.hbsとほぼ同じ構成でCasperの場合は、ヘッダー部分の表記が微妙に違うだけで、別途用意するのがメンドウならindex.hbsをコピーしてtag.hbsとすれば、問題なく動作する。

page.hbs

管理画面で、投稿の設定をTurn this post into a static pageにチェックを入れると、その投稿はpostsで列挙されなくなる。その代わり固定ページ扱いになって、そのページをリンクなどから開くと、page.hbsで表示されるようになる。内容は、post.hbsと似ている。

{{!< default}}
{{#post}}
<header class="main-header post-head">
:
</header>
<main>
	<article>
		<header class="post-header">
            <h1 class="post-title">{{title}}</h1>
        </header>
		<section class="post-content">
            {{content}}
        </section>
	</article>
</main>
{{/post}}

Wordpressのテーマを作成したことがある人は、すぐにピンとくるつくりになっていて違和感がほとんどない。後発だけあって、洗練された印象がある。

詳細は、公式ページを見ると良い。

Theme http://themes.ghost.org/

API http://api.ghost.org/v0.1/docs