KuroCMS

Template code reference

テンプレートで使える特殊コード

KuroCMS のテンプレートは、[[...]] という特殊コードを含む「未展開の HTML 原本」です。公開ビルド時に CMS がこれらを実データへ展開します。テンプレートを自作・修正する人が使える表現を、役割とサンプルつきでまとめました。

先頭マーカー必須

HTML 原本の 1 行目は必ず <!-- kurocms-template-api:1 --> で始めます。未知の値は空文字に、オブジェクトの直接出力は不可、セクションの閉じ忘れは描画エラーになります。[[html:…]] は無加工出力なので信頼できる CMS データにのみ使ってください。

1. 基本構文 [[...]]

構文動作
[[path]] / [[value:path]] 値を HTML エスケープして出力 [[site.name]]
[[html:path]] 無加工で HTML 出力(信頼できる CMS データのみ) [[html:article.bodyHtml]]
[[#if path]]…[[/if]] 値が真のとき中身を出力 [[#if page.isArticle]]…[[/if]]
[[#unless path]]…[[/unless]] 値が偽のとき中身を出力 [[#unless article.coverUrl]]…[[/unless]]
[[#each path]]…[[/each]] 配列を反復(中は相対パス / [[this]]) [[#each articles]][[title]][[/each]]
[[#each type:{slug}:{N}]]…[[/each]] 指定タイプの記事を新しい順に N 件(下の 3 章) [[#each type:news:5]]

2. データモデル(参照できるパス)

パス内容
page.isHome / isAbout / isPrivacy / isTerms / isArticle / isType / isCategory / isRecipe 現在ページの種別フラグ。記事下部の関連記事などは [[#if page.isArticle]] で囲む。isRecipe はレシピカードを持つ記事で true
site.name / site.lang / site.dir / site.basePath サイト名 / 表示言語 / 書字方向(rtl|ltr) / 公開 URL プレフィックス
content.{key} 管理画面「サイト文字編集」で編集するサイトテキスト(例 content.footer-text)
navigation.types / navigation.categories タイプ / カテゴリ配列(件数は含まない)。各項目の isCurrent は現在ページに対応する項目だけ true → ナビの現在地ハイライトに使う
articles 一覧ページの記事配列(slug, tid, title, summary, publishAt, coverUrl, categories)
article 記事詳細(上記 + type, bodyHtml, updatedAt)。記事ページ以外は null
article.recipe レシピカードの内容(下の 7 章)。カードが無い記事では null
pagination page / totalPages / prevUrl / nextUrl(旧ページング用。一覧では原則 null)
type.id / type.name · category.id / category.name 現在のタイプ / カテゴリ
integrations.blueskyHandle Bluesky ハンドル

3. テンプレートから記事を引く(データ参照) KuroCMS v1.8.79+

articlesそのページのスコープの記事しか持ちません(TOP なら全タイプの最新が混ざります)。TOP に「お知らせ枠=news」「製品枠=products」のようなタイプ別の枠を作りたいときは、テンプレートから名指しで引きます。

記法内容
[[#each type:{slug}:{N}]] 指定タイプの記事を新しい順に N 件 [[#each type:news:5]]
[[#each category:{slug}:{N}]] 指定カテゴリの記事を新しい順に N 件 [[#each category:tips:3]]
[[#each articles:latest:{N}]] 全タイプ横断で最新 N 件 [[#each articles:latest:8]]
[[#each type:all]] タイプ一覧(件数つき) [[#each type:all]][[name]][[/each]]
[[#each category:all]] カテゴリ一覧(件数つき) [[#each category:all]][[name]][[/each]]

配置例(トップページのタイプ別 2 枠)

<h2>更新情報・お知らせ</h2>
<ul>
  [[#each type:news:5]]
  <li><a href="[[site.basePath]]/[[tid]]/[[slug]]/"><time>[[date]]</time>[[title]]</a></li>
  [[/each]]
</ul>

<h2>主な製品・サービス</h2>
[[#each type:products:3]]
<a class="card" href="[[site.basePath]]/[[tid]]/[[slug]]/">
  [[#if coverUrl]]<img src="[[coverUrl]]" alt="">[[/if]]
  <h3>[[title]]</h3><p>[[summary]]</p>
</a>
[[/each]]

4. カルーセルと広告 KuroCMS v1.8.79+

画像カルーセル [[carousel:{key}|{opts}]]

「どんな見た目・サイズか」はテンプレート、「どの画像を出すか」は運用者という分担です。テンプレートに画像 ID を直書きしません。

テンプレート

[[carousel:hero|100%x320,fade,arrows,5s]]

サイトテキスト hero

img-100,img-101,img-102
  • サイズ 100% / 100%x320 / 640x360(数値だけなら px。既定 100%x320)
  • 切替 fade(既定) / slide
  • 矢印 arrows(既定) / noarrows
  • ドット dots(既定) / nodots
  • 自動送り 5s(既定) / 0s=自動送りなし
  • 順序は自由([[img-100|60%,right]] と同じカンマ区切り)
  • 画像 0 枚なら何も出力せず、1 枚なら矢印もドットも出しません

自動送りは prefers-reduced-motion とマウスホバーで停止します。ルートに class="kuro-carousel" が付くのでテンプレート側で装飾できます。

広告(Google AdSense)

テンプレートに [[ad]] を置くと AdSense の広告ユニットに展開します。預けるのは ID だけで、配布された広告コードを貼り付ける必要はありません(スクリプト本体は CMS が組み立てます)。

設定(サイトテキスト ad-adsense

ca-pub-1234567890123456,1234567890,9876543210

1 行にカンマ区切りで書きます。先頭がクライアント、以降が枠 ID です。キーを分けないのは、分けると片方の設定漏れに気付けないためです。

  • [[ad]]=1 番目の枠、[[ad:2]]=2 番目の枠(1 始まり)
  • 未設定・形式不正・枠番号が範囲外のときは何も出力しません(壊れたタグを残さない)
  • AdSense のローダーは実際に広告を出したページにだけ読み込まれます
  • ユニットには class="kuro-ad adsbygoogle" が付くので、.kuro-ad をテンプレート側で自由に装飾できます

Amazon アソシエイトは未対応です。トラッキング ID は成果の帰属に使う識別子であって、それだけで広告ユニットを描画する仕組みではありません(ネイティブショッピングウィジェットには別途インスタンス ID が必要)。

5. サイトテキスト内で使える表現

管理画面「サイト文字編集」の各値(content.{key})の中では、テンプレートパーサーに渡す前に次が展開されます。

表現内容
[[type:all]] / [[category:all]] タイプ / カテゴリ一覧 JSON
[[type:slug:N]] / [[category:slug:N]] 指定タイプ / カテゴリの記事 N 件
[[articles:latest:N]] 最新記事 N 件
[[article:slug]] 指定記事のデータ
[[mid]] 画像・動画・音声タグへ展開(例 [[img-816]])
[[sid]] 対応する SNS ウィジェットへ展開
[[lang]] 言語スイッチャ・ウィジェットへ展開(ナビ等に配置)
[[search]] 記事検索ウィジェットへ展開(ナビの TYPE 左などに配置)。PC は入力欄+検索アイコン、スマホはアイコン→タップでダイアログ
[[privacy]] / [[terms]] プライバシーポリシー / 利用規約ページへのリンクに展開。対応するサイトテキストが空なら何も出ない(デッドリンクを作らない)ので、フッターに無条件で置いてよい
[[ad]] / [[ad:2]] Google AdSense の広告ユニット(下の 4 章)
[[carousel:{key}|{opts}]] 画像カルーセル。画像はサイトテキスト {key} にメディア ID をカンマ区切りで並べる(下の 4 章)

6. 予約サイトテキスト slug

実体を保存しなくても、CMS がビルド時に自動生成する特別な content.* です。テンプレートに置くだけで機能します。

New [[html:content.related-N]]

関連記事ストリップ。記事ページで、その記事と同じカテゴリ公開日が近い記事N 枚並べます。中央の ←・→ が当記事で、左に古い記事 floor(N/2) 枚・右に新しい記事 ceil(N/2) 枚。端(最古/最新)では反対側から補充して常に N 枚を保ちます。画像とタイトルのみの小さなカードで、画面幅が狭くなっても折り返さず縮小して N 枚を維持します。

  • N は 1〜20。枚数を変えるだけ:related-2 / related-4 / related-6
  • 記事ページ以外・カテゴリ未設定・近傍記事なしのときは空文字(何も出ません)
  • データは書き換えず、表示専用。KuroCMS 本体が対応バージョン以外なら安全に無視されます

配置例(記事本文の直後 = 筆者表示の下)

[[#if page.isArticle]]
  <article>
    <div class="prose">[[html:article.bodyHtml]]</div>
    [[html:content.related-4]]
  </article>
[[/if]]
[[html:archives]] 月別アーカイブ切替の <select>。一覧ページで使用

7. レシピカード page.isRecipe

本文エディタの鍋アイコンから「レシピカード」(人数・時間・材料・手順)を挿入できます。カードを 1 枚置いた記事が、そのままレシピ記事になります — 専用の記事タイプは要りません。タイプが news でも blog でも同じように働きます。カードの中身はテンプレートからも構造化データとして取り出せるので、独自レイアウトで描き直せます。

New page.isRecipe / article.recipe KuroCMS v1.8.78+

[[html:article.bodyHtml]] を出すだけでもカードはそのまま表示されます。下の値を使うのは、テンプレートの意匠に合わせて組み直したいときだけです。

page.isRecipe レシピカードを持つ記事ページで true。タイプ名の文字列比較はせず、必ずこのフラグで分岐する
article.recipe.yield 人数(自由文字列。例「4人分」)
article.recipe.prepTimeMinutes 下準備(分)。未入力ならキーごと存在しない
article.recipe.cookTimeMinutes 調理(分)。未入力ならキーごと存在しない
article.recipe.totalMinutes 下準備+調理。どちらも未入力なら null
article.recipe.ingredients 材料の配列。[[#each]] の中で [[name]] / [[amount]](amount は省略可)
article.recipe.instructions 手順の配列。[[#each]] の中で [[text]]
  • 構造化データ(Schema.org Recipe)は KuroCMS が自動で出します。テンプレート側で JSON-LD を書かないでください(二重になります)
  • 1 記事 = 1 レシピ。2 枚目はエディタ側で挿入できないようになっています(鍋アイコンがロックされます)。料理名・説明・完成画像・公開日はカードではなく記事共通のもの(article.title / article.summary / article.coverUrl)を使います
  • amount は省略できるので [[#if amount]] で囲みます
  • カードが無い / 壊れている記事では page.isRecipe が false になり、通常記事としてそのまま描けます(構造化データも Article に戻ります)

記事ページでの表示例

[[#if page.isRecipe]]
<section class="recipe">
  <p class="meta">[[article.recipe.yield]][[#if article.recipe.totalMinutes]] ・ 合計 [[article.recipe.totalMinutes]] 分[[/if]]</p>
  <h2>材料</h2>
  <ul>
    [[#each article.recipe.ingredients]]
    <li>[[name]][[#if amount]] <span>[[amount]]</span>[[/if]]</li>
    [[/each]]
  </ul>
  <h2>作り方</h2>
  <ol>
    [[#each article.recipe.instructions]]<li>[[text]]</li>[[/each]]
  </ol>
</section>
[[/if]]

8. 記事ページの最小サンプル

<!-- kurocms-template-api:1 -->
<!doctype html>
<html lang="[[site.lang]]">
<body>
  [[#if page.isArticle]]
  <article>
    [[#if article.coverUrl]]<img src="[[article.coverUrl]]" alt="">[[/if]]
    <h1>[[article.title]]</h1>
    <div class="prose">[[html:article.bodyHtml]]</div>
    [[html:content.related-4]]
  </article>
  [[/if]]
</body>
</html>