本文へ移動
SiteKit 無料で始める
目次 直せる箇所の印(CMS)

Docs

直せる箇所の印(CMS)

data-cms 系の属性で、テキスト・写真・お知らせの一覧・記事ページ・多言語を、お店の人が直せるようにする。

考え方

HTML の要素に data-cms 系の属性を付けると、その箇所が管理画面から直せるようになります。何を直せるかは schema.json で宣言します。

  • 要素の中に書いた文言は既定の文言です。値が無いとき(未入力、または CMS に届かないとき)は、HTML がそのまま残ります
  • 値は文字としてエスケープされて入ります。お店の人の入力で HTML やスクリプトが差し込まれることはありません
  • 値の埋め込みは、Cloudflare Pages の中継(配信前)か data-embed(表示時)が行います(中継とホスティング)

印の一覧

属性働き
data-cms="key"要素の中の文字を置き換える
data-cms-html="key"同じく置き換え、改行を <br> にする
data-cms-src="key"img / video / source の src を置き換える
data-cms-attr="属性:key"任意の属性を置き換える(例: content:title、href:url)
data-cms-blocks="key"記事本文(ブロックの並び)を中に描く
data-cms-hide-empty値が空文字のとき要素ごと消す(data-cms / data-cms-html だけに効く)
<template data-cms-list="k" data-cms-limit="n">一覧の1件ごとに中身を繰り返す(n 件まで)
<template data-cms-list="k" data-cms-filter="f=v">条件に合う件だけ繰り返す
<template data-cms-empty="k">一覧が空のときだけ中身を出す
<template data-cms-entry="k">記事ページで、その記事1件を描く
<template data-cms-each="k">配列(タグなど)の要素ごとに繰り返す
data-cms-fallback="k"一覧 k が届いたら要素ごと消す(届かないときの代わりの表示)

テキスト

グループ(schema.json の groups)の値は <グループ>.<項目> で指定します。

<dd data-cms="hours.days">月〜土</dd>

<!-- 改行を <br> に。空にすると枠ごと消える -->
<p class="notice" data-cms-html="hours.notice" data-cms-hide-empty>臨時休業のお知らせはありません。</p>

写真

一覧や記事の写真(type: "image" の項目)は、絶対 URL で届きます。data-cms-src で src に入れます。

<template data-cms-list="news">
  <article>
    <img data-cms-src="thumbnail" src="/img/placeholder.jpg" alt="">
    <h3 data-cms="title">記事タイトル</h3>
  </article>
</template>

href や src などの URL を入れる属性には、javascript: / data: / vbscript: で始まる値は入りません(既定の値が残ります)。data-cms-attr で on… のイベント属性・srcdoc・formaction は書き換えられません。

お知らせなどの一覧

コレクション(schema.json の collections)は <template data-cms-list> で繰り返します。中の data-cms には、その1件の項目名を書きます。

<ul class="news">
  <template data-cms-list="news" data-cms-limit="3">
    <li>
      <time data-cms="date">2026-01-01</time>
      <a data-cms-attr="href:url" href="/news/"><span data-cms="title">記事タイトル</span></a>
    </li>
  </template>

  <!-- 1件も無いときだけ出る -->
  <template data-cms-empty="news">
    <li>お知らせはまだありません。</li>
  </template>

  <!-- 一覧が届いたら消える。CMS に届かないときはこれが残る -->
  <li data-cms-fallback="news"><span>ホームページを公開しました</span></li>
</ul>
  • 一覧の順番は schema.json の sort(例: "date desc")。無ければ管理画面で並べた順です
  • 1つの一覧に載るのは新しい順に最大 100 件です
  • 記事へのリンクは data-cms-attr="href:url" で張ります。url は schema.json には無く、中継が記事ごとに /news/<id>(言語の接頭辞つき、絶対 URL)を足したものです。data-embed では付きません
  • data-cms-limit は整数だけ("3")。それ以外は制限なしとして全件出ます

記事ごとのページ

記事ごとの URL(/news/<id>)は、中継が news/_entry.html を雛形にして描きます。ファイルを記事の数だけ置く必要はありません。Cloudflare Pages の中継を使うサイトだけの機能です。

public/news/_entry.html     記事ページの雛形
public/news/_404.html       存在しない ID のときのページ(任意)
public/en/news/_entry.html  言語ごとに用意する
<template data-cms-entry="news">
  <h1 data-cms="title">記事タイトル</h1>
  <time data-cms="date">2026-01-01</time>
  <div data-cms-blocks="body"></div>
</template>
  • URL は /news/<id> または /<言語>/news/<id>。<id> は英小文字と数字だけ・32 文字以内
  • 公開中の記事に無い ID は 404 になります(news/_404.html があればそれを返す)
  • パスとコレクションのキーは中継の環境変数 CMS_NEWS_PATH(省略時 news)

<title> と OGP は <head> にも template を置く

data-cms-entry の「その記事1件」として読めるのは template の内側だけです。<head> に直接 <title data-cms="title"> と書くと、記事ではなくサイト共通の値を読みにいきます。画面には出ないので、SNS に貼ったときに初めて気づきます。

<head>
  <template data-cms-entry="news">
    <title data-cms="title">お知らせ|店名</title>
    <meta name="description" data-cms-attr="content:lead" content="店名からのお知らせ。">
    <meta property="og:title" data-cms-attr="content:title" content="お知らせ|店名">
    <meta property="og:image" data-cms-attr="content:thumbnail" content="../assets/hero.jpg">
    <meta property="og:url" data-cms-attr="content:url" content="">
    <link rel="canonical" data-cms-attr="href:url" href="">
  </template>
  <!-- CMS に届かず template が展開されなかったときに残る題 -->
  <title data-cms-fallback="news">お知らせ|店名</title>
</head>

data-cms-fallback を付けた <title> は、template が展開されると消えます。これが無いと <title> が2つ出ます。記事の url は絶対 URL なので、og:url と canonical にそのまま入れられます。

記事本文(ブロック)

type: "blocks" の項目は data-cms-blocks で描きます。出てくる要素のクラスはすべて sk- で始まり、CSS はサイト側で当てます(スタイルシートは配りません)。

.sk-h  { font-size:1.05rem; margin:2rem 0 .5rem; }   /* 見出し */
.sk-p  { margin:0 0 1rem; }                          /* 文章 */
.sk-q  { border-left:3px solid #e5e7eb; padding-left:1rem; color:#6b7280; }
.sk-ul, .sk-ol { margin:0 0 1rem; padding-left:1.4rem; }
.sk-img img { width:100%; height:auto; }
.sk-img figcaption { color:#6b7280; font-size:.8rem; }
.sk-video { width:100%; }
.sk-embed { position:relative; padding-top:56.25%; }
.sk-embed iframe { position:absolute; inset:0; width:100%; height:100%; border:0; }
.sk-hr { border:0; border-top:1px solid #e5e7eb; }
.sk-pdf, .sk-card, .sk-video-link { display:inline-block; }

/* 文字色。クラス名は変えない。色の値はサイトの配色に合わせてよい */
.sk-c-red   { color:#c0392b; }
.sk-c-gold  { color:#b8860b; }
.sk-c-gray  { color:#6b7280; }
.sk-c-black { color:#111827; }
.sk-c-green { color:#15803d; }
.sk-c-blue  { color:#1d4ed8; }

お店の人は本文の中で次の書き方が使えます。

書き方出力
**太字**<strong>
[文字](https://…)新しいタブで開くリンク(http/https だけ)
{color:red}文字{/color}<span class="sk-c-red">(色は red / gold / gray / black / green / blue の6つ)
https://… をそのまま自動でリンク

.sk-c-* を書き忘れると、色の指定をしても見た目が変わりません。色を使うサイトでは最初に6つとも定義しておきます。

タグ

コレクションの項目を "type": "tags" にすると、記事にタグを付けられます(1件20個まで・1タグ40文字まで・/ # ? は使えない)。タグは翻訳しません。

記事ごとのタグ — data-cms-each で1つずつ出します。中継がタグを {tag, url, color} にしているので、名前とタグページへのリンクが書けます。

<template data-cms-each="tags">
  <a data-cms-attr="href:url" href="#">
    <span class="sk-tag" data-cms-attr="data-color:color" data-cms="tag">タグ</span>
  </a>
</template>

タグの一覧(ナビ) — 使われているタグが <コレクション>_tags(例: news_tags)という一覧で届きます。{tag, count, url, color} を持ちます。

<template data-cms-list="news_tags">
  <a data-cms-attr="href:url" href="#"><span class="sk-tag" data-cms="tag">タグ</span></a>
</template>

タグページ — /news/tag/<タグ>/ は、中継が news/_tag.html を雛形にして描きます。news の一覧はそのタグで絞られた状態で届きます。表示名は news.tag です。存在しないタグでも 404 にはせず、空の一覧(data-cms-empty が出る)を返します。

<h1>タグ: <span data-cms="news.tag">タグ名</span></h1>
<ul>
  <template data-cms-list="news">
    <li><a data-cms-attr="href:url" href="./"><span data-cms="title">タイトル</span></a></li>
  </template>
  <template data-cms-empty="news"><li>このタグのお知らせはまだありません。</li></template>
</ul>

タグの色は管理画面の「タグの管理」で決めます。色を決めていないタグには data-color 属性が付かず、.sk-tag の既定の見た目になります。

.sk-tag { display:inline-block; padding:.1rem .5rem; border-radius:999px;
          font-size:.75rem; background:#f3f4f6; color:#374151; text-decoration:none; }
.sk-tag[data-color=red]   { background:#fdecea; color:#c0392b; }
.sk-tag[data-color=gold]  { background:#fdf6e3; color:#8a6d1f; }
.sk-tag[data-color=gray]  { background:#f3f4f6; color:#4b5563; }
.sk-tag[data-color=black] { background:#1f2937; color:#fff; }
.sk-tag[data-color=green] { background:#e8f5ec; color:#15803d; }
.sk-tag[data-color=blue]  { background:#e8effd; color:#1d4ed8; }

data-cms-filter="tags=秋" のように書くと、タグページ以外でも絞り込めます(配列の項目は「含む」、1つの値は「等しい」で判定)。

種別のバッジ

select の選択肢には色を付けられます(schema.json)。公開 JSON には保存値に加えて <項目>_label(表示する文字)と <項目>_color(色名。色の無い選択肢では出ない)が載ります。

<span class="sk-badge" data-cms="category_label" data-cms-attr="data-color:category_color"></span>

.sk-badge[data-color=…] の CSS は .sk-tag と同じ形で6色を書きます。

多言語

  1. schema.json の locales に言語を並べます(例: ["ja", "en"])。先頭が主言語で、お店の人はこの言語で入力します
  2. 文章の項目(text / textarea / blocks)は、保存のあと AI が自動で翻訳します(AI 翻訳のあるプランのとき)。訳さない項目には "translate": false を付けます(時刻・日付・種別など)
  3. 翻訳が無い・空の項目は主言語の値が出ます
  4. 言語ごとのページを用意し、中継の CMS_LOCALES に 言語:接頭辞 を書きます(例: ja:/,en:/en)。言語は URL だけで決まり、Accept-Language は見ません

data-embed を使う場合は、<html lang> か script の data-locale の言語で取得します。

AI 翻訳の有無と回数の上限はプランで決まります(プランと上限)。

書くときの決まり

守らなくてもエラーは出ず、表示が崩れるか、何も起きないだけです。うまくいかないときはここから確かめます。

  • 印を付けた要素の中に、同じタグ名の要素を入れない。 <div data-cms="x"><div>…</div></div> は壊れます。<span> など別のタグを使います
  • 1つの要素に印は1つ。 2つ付けると後のものが勝ちます
  • data-cms-attr は1要素に1つだけ。 href:url data-color:color のように2つ書くと、どちらも書かれません。要素を分けます
  • タグ名と属性名は小文字で書く。 <DIV DATA-CMS="k"> は無視されます
  • <script> と <style> の中に印を書かない。 中身が書き換えられてしまいます(HTML コメントの中は安全です)
  • <template data-cms-list> の中に、もう1つ data-cms-list を入れない。 1件の中で繰り返すときは data-cms-each を使います
  • data-cms-filter で0件になっても data-cms-empty は出ません。 data-cms-empty が見るのは一覧そのものが空かどうかです
  • 静的な文言は、それだけ読んで意味が通る内容にする。 CMS に届かないときはそれが公開されます

このページは Markdown でも読めます。AI エージェントには llms.txt(目次)か llms-full.txt(全文)を渡してください。