Ghost
モダンなブログ・パブリッシングプラットフォーム。執筆体験とパフォーマンスに特化したCMS。
CMS
Ghost
概要
Ghostは、執筆体験とパフォーマンスに特化したモダンなブログ・パブリッシングプラットフォームです。
詳細
Ghost(ゴースト)は、プロフェッショナルな出版者とライターのために設計された、オープンソースのブログプラットフォームです。2013年にWordPressの代替として開発され、執筆に集中できるミニマルなインターフェースと高速なパフォーマンスが特徴です。Node.jsで構築され、完全なヘッドレスCMSとしても動作します。
Ghostの最大の特徴は「執筆ファースト」の設計思想です。直感的なWYSIWYGエディタとMarkdownサポート、カード型のコンテンツブロック、リアルタイムプレビューなど、執筆者の生産性を最大化する機能が豊富です。メンバーシップ機能が標準搭載されており、有料購読、無料会員登録、メール配信を統合的に管理できます。
技術的には、RESTful Content APIとAdmin APIを提供し、任意のフロントエンドフレームワークと組み合わせて使用できます。テーマシステムはHandlebarsベースで、SEO最適化、AMP対応、構造化データ(JSON-LD)が自動生成されます。2024年の最新バージョンでは、動画・音声ファイルの直接アップロード、多言語対応、Ghost Explorerによるコンテンツ発見機能が追加されています。
メリット・デメリット
メリット
- 優れた執筆体験: 洗練されたエディタとMarkdown対応
- 高速パフォーマンス: Node.js製で軽量・高速
- メンバーシップ統合: 有料購読とニュースレター機能を標準搭載
- SEO最適化: 構造化データとメタデータの自動生成
- ヘッドレス対応: APIファーストで柔軟な実装が可能
- 手数料0%: 収益化機能の利用に手数料なし
- オープンソース: 完全に無料で自由にカスタマイズ可能
デメリット
- ブログ特化: 汎用CMSではないため用途が限定的
- プラグイン不足: WordPressと比較して拡張機能が少ない
- 技術的ハードル: セルフホストには技術知識が必要
- 日本語サポート: 公式ドキュメントは英語中心
- カスタマイズ制限: テーマのカスタマイズにはHandlebars知識が必要
主要リンク
- Ghost公式サイト
- Ghost Documentation
- Ghost GitHub Repository
- Ghost Forum
- Ghost Marketplace
- Ghost API Reference
使い方の例
Ghostのインストールと初期設定
# Ghost-CLIのインストール
sudo npm install ghost-cli@latest -g
# Ghostプロジェクトディレクトリの作成
sudo mkdir -p /var/www/ghost
sudo chown $USER:$USER /var/www/ghost
sudo chmod 775 /var/www/ghost
cd /var/www/ghost
# Ghostのインストール(本番環境)
ghost install
# ローカル開発環境の場合
ghost install local
# 開発サーバーの起動
ghost start
Content APIを使った記事取得
// Ghost Content APIクライアントの初期化
const GhostContentAPI = require('@tryghost/content-api');
const api = new GhostContentAPI({
url: 'https://your-blog.ghost.io',
key: 'your-content-api-key',
version: 'v5.0'
});
// 最新の記事を取得
async function getLatestPosts() {
try {
const posts = await api.posts
.browse({
limit: 10,
include: 'tags,authors',
fields: 'id,title,slug,feature_image,published_at,excerpt'
});
posts.forEach(post => {
console.log(`${post.title} - ${post.url}`);
});
} catch (err) {
console.error(err);
}
}
// 特定のスラッグで記事を取得
async function getPostBySlug(slug) {
try {
const post = await api.posts
.read({slug}, {include: 'tags,authors'});
return post;
} catch (err) {
console.error(err);
}
}
メンバーシップとニュースレター設定
// Admin APIを使ったメンバー管理
const GhostAdminAPI = require('@tryghost/admin-api');
const admin = new GhostAdminAPI({
url: 'https://your-blog.ghost.io',
key: 'your-admin-api-key',
version: 'v5.0'
});
// 新規メンバーの追加
async function addMember(email, name) {
try {
const member = await admin.members.add({
email: email,
name: name,
subscribed: true,
labels: ['newsletter']
});
console.log(`メンバー追加完了: ${member.email}`);
} catch (err) {
console.error('メンバー追加エラー:', err);
}
}
// ニュースレター配信の設定
const newsletterConfig = {
title: 'Weekly Newsletter',
sender_name: 'Your Blog',
sender_email: '[email protected]',
sender_reply_to: '[email protected]',
status: 'active',
visibility: 'members',
subscribe_on_signup: true,
sort_order: 0,
header_image: null,
show_header_icon: true,
show_header_title: true,
title_font_category: 'serif',
title_alignment: 'center'
};
カスタムテーマの作成
{{!-- index.hbs - ホームページテンプレート --}}
{{!< default}}
<div class="site-content">
<header class="site-header">
<h1>{{@site.title}}</h1>
<p>{{@site.description}}</p>
</header>
<main class="post-feed">
{{#foreach posts}}
<article class="post-card">
{{#if feature_image}}
<a class="post-card-image-link" href="{{url}}">
<img class="post-card-image" src="{{feature_image}}" alt="{{title}}" />
</a>
{{/if}}
<div class="post-card-content">
<a class="post-card-content-link" href="{{url}}">
<header class="post-card-header">
{{#if primary_tag}}
<span class="post-card-tags">{{primary_tag.name}}</span>
{{/if}}
<h2 class="post-card-title">{{title}}</h2>
</header>
<section class="post-card-excerpt">
<p>{{excerpt words="33"}}</p>
</section>
</a>
<footer class="post-card-meta">
<span class="post-card-author">{{authors}}</span>
<span class="post-card-date">{{date published_at format="DD MMM YYYY"}}</span>
</footer>
</div>
</article>
{{/foreach}}
</main>
{{pagination}}
</div>
Next.jsとの統合
// pages/index.js - Next.jsでGhostブログを構築
import GhostContentAPI from '@tryghost/content-api';
const api = new GhostContentAPI({
url: process.env.GHOST_API_URL,
key: process.env.GHOST_CONTENT_API_KEY,
version: 'v5.0'
});
export async function getStaticProps() {
const posts = await api.posts.browse({
limit: 'all',
include: 'tags,authors',
fields: 'id,title,slug,feature_image,published_at,excerpt,reading_time'
});
return {
props: { posts },
revalidate: 60 // ISRで60秒ごとに再生成
};
}
export default function Home({ posts }) {
return (
<div className="container">
<h1>My Ghost Blog</h1>
<div className="posts-grid">
{posts.map(post => (
<article key={post.id} className="post-card">
{post.feature_image && (
<img src={post.feature_image} alt={post.title} />
)}
<h2>
<a href={`/posts/${post.slug}`}>{post.title}</a>
</h2>
<p>{post.excerpt}</p>
<div className="post-meta">
<time dateTime={post.published_at}>
{new Date(post.published_at).toLocaleDateString('ja-JP')}
</time>
<span>{post.reading_time} min read</span>
</div>
</article>
))}
</div>
</div>
);
}
WebhookとZapier連携
// Ghost Webhookの設定例
const webhookConfig = {
webhooks: [{
event: 'post.published',
target_url: 'https://your-app.com/webhooks/ghost/post-published'
}, {
event: 'member.added',
target_url: 'https://your-app.com/webhooks/ghost/member-added'
}]
};
// Webhook受信エンドポイントの実装
app.post('/webhooks/ghost/post-published', async (req, res) => {
const { post } = req.body;
// 新記事公開時の処理
console.log(`新記事公開: ${post.current.title}`);
// Twitter自動投稿
await postToTwitter({
text: `新しい記事を公開しました!\n\n${post.current.title}\n${post.current.url}`
});
// Slack通知
await notifySlack({
channel: '#blog-updates',
text: `新記事: ${post.current.title}`,
url: post.current.url
});
res.status(200).json({ received: true });
});
// Zapier連携での自動化例
// 1. Ghost → Zapier → Twitter
// 2. Ghost → Zapier → メールマーケティングツール
// 3. Ghost → Zapier → Google Sheets(分析データ収集)