コミュニティイベント一覧をYAMLデータ化し、Liquidテンプレートで動的レンダリングへ移行
Rails公式サイトのコミュニティイベント一覧を、静的HTMLのハードコーディングから _data/events.yml によるデータ駆動型のLiquidテンプレートレンダリングへ移行しました。これにより、イベント追加・削除がHTMLを直接編集せずYAMLのみで完結するようになります。
背景
これまで _pages/events.html では、各コミュニティイベントの情報(イベント名・開催地・日程・URL)がHTMLカードとして個別にハードコーディングされていました。イベントを1件追加・削除するだけでもHTML構造を直接編集する必要があり、マークアップのミスや構造の崩れが起きやすい状態でした。
Jekyllが標準でサポートする _data/ ディレクトリ配下にYAMLファイルを置けば、site.data 経由でどのテンプレートからもデータを参照できます。この仕組みを活用することで、コンテンツ(イベント情報)とプレゼンテーション(HTMLカード構造)を明確に分離できます。
技術的な変更
イベント情報を管理する専用データファイルとして _data/events.yml が新設されました。各イベントは name・location・start_date・end_date・url・display_url の6フィールドを持ちます。
community_events:
- name: Tropical on Rails
location: "São Paulo, Brazil"
start_date: "2026-04-09"
end_date: "2026-04-10"
url: https://tropicalonrails.com
display_url: www.tropicalonrails.com
- name: Blastoff Rails
location: "Albuquerque, New Mexico"
start_date: "2026-06-11"
end_date: "2026-06-12"
url: https://blastoffrails.com
display_url: www.blastoffrails.com
_pages/events.html のコミュニティイベントセクションでは、静的なカードのHTML群が削除され、site.data.events.community_events をループするLiquidテンプレートに置き換えられました。注目すべき点として、過去のイベントを自動的に非表示にするフィルタリングロジックが組み込まれています。site.time と event.end_date を %Y%m%d 形式の文字列に変換して辞書順比較することで、終了済みイベントを continue でスキップします。
また、月をまたぐイベントと同月内イベントで日付表示を切り替えるロジックも含まれています。start_month == end_month の条件で分岐し、同月なら "April 9–10, 2026" 形式、異なる月なら "October 8–November 11, 2026" 形式のように presentation_date 変数を組み立てます。
変更前後のHTMLカード部分を比較すると、48行の静的HTMLが20行のLiquidテンプレートに集約されています。
変更前(イベントごとに静的HTMLを記述):
<div class="card">
<a href="https://tropicalonrails.com" title="Tropical on Rails">
<div class="card__body">
<div class="card__label">
<h6>São Paulo, Brazil</h6>
</div>
<div class="card__headline">
<h3>Tropical on Rails</h3>
</div>
<div class="card__content">
<p class="date">
<time datetime="2026-04-09">April 9–10, 2026</time>
</p>
<p class="link">www.tropicalonrails.com</p>
</div>
</div>
</a>
</div>
変更後(Liquidテンプレートで動的生成):
{% assign now = site.time | date: "%Y%m%d" %}
{% for event in site.data.events.community_events %}
{% assign event_end = event.end_date | date: "%Y%m%d" %}
{% if event_end < now %}{% continue %}{% endif %}
...
<div class="card">
<a href="{{ event.url }}" title="{{ event.name }}">
<div class="card__body">
<div class="card__label">
<h6>{{ event.location }}</h6>
</div>
<div class="card__headline">
<h3>{{ event.name }}</h3>
</div>
<div class="card__content">
<p class="date">
<time datetime="{{ event.start_date }}">{{ presentation_date }}</time>
</p>
<p class="link">{{ event.display_url }}</p>
</div>
</div>
</a>
</div>
{% endfor %}
あわせて _config.yml で jekyll-redirect-from プラグインがコメントアウトされています。このプラグインはリダイレクト機能を提供するものですが、今回の変更との直接的な因果関係はPR本文に明示されていません。
設計判断
display_url を url とは別フィールドで管理する設計 が採用されています。url はリンク先のhref属性に使用するフル形式(https:// プレフィックス付き)、display_url は表示用の短縮形(www. で始まるもの等)として分離されています。これは表示上の見た目と実際のリンク先を独立して管理できる柔軟な設計です。
過去イベントの非表示判定を ビルド時の site.time に基づく文字列比較 で実装している点も特徴的です。Jekyllはサーバーサイドで動作しないため、JavaScriptを用いずに静的サイトの制約内でフィルタリングを実現するにはビルド時評価が適切な選択です。この実装はサイトがビルドされた時点の時刻に依存して表示が切り替わる点が、設計上の特徴として挙げられます。
まとめ
コンテンツとマークアップを分離したことで、イベント情報の追加・更新がYAMLファイルの編集だけで完結するようになりました。Jekyllの _data/ 規約を活用した今回の構造は、今後コントリビューターがPRでイベントを追加する際の参入コストを大幅に下げる変更といえます。