canai-prepare について
CanAIへの後続インポートに対応した静的HTMLページを生成するスキルです。フロントエンドフレームワークやビルドツールを使わず、移植可能な自己完結型ページを作るエージェント向けに、ナビゲーションとメタデータも整えます。
主な機能
- 01ページごとに完全なHTMLファイルを生成
- 02Tailwind CSSとVanilla JSまたはAlpine.js
- 03Lucideアイコンの規約
- 04移植しやすい相対アセットパス
- 05ナビゲーションマーカーとpages.json、menus.json
活用シーン
- 01デザインモックを静的HTMLに変換
- 02SPAのルートを相互リンクするHTMLページに変換
- 03CanAIインポート用ページの準備
- 04WordPress外でプレビュー可能なファイルの作成
MCP 対応
このスキルはCanAIへの後続インポートを想定した静的HTMLを生成します。出力はcanai-mcpに渡してインポートできますが、MCPサーバーやクライアントの管理については説明されていません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ usewp/ canai --skill canai-prepareインストール後、Claude Code で/canai-prepareを入力して読み込まれたか確認します。
同梱ファイルreferences/BOILERPLATE.mdreferences/STRUCTURE-NAVIGATION.md
詳細
CanAI Prepare — 単一 HTML の静的ページ
後で CanAI にインポートするための推奨される静的マークアップを生成します。各ページは完全な HTML ドキュメントを 1 つ作成します(React/Vue/ビルドツールは使用しません)。スタイルには Tailwind CSS のユーティリティクラスのみを使用し、動作は バニラ JS または Alpine.js で実装します。アイコンには Lucide(data-lucide)を使用します。
エージェントはユーザー自身のフォルダーで実行されるものとします(WordPress のルートとは限りません)。このスキルでは、CanAI と互換性があり、統合準備が整った単一 HTML の出力のみを対象とします。WP-CLI、.env.wplocal、wp-content/ 以下への書き込みは必要ありません。
標準的なスケルトン、Alpine/Lucide のパターン、pages.json/menus.json の形式については、references/BOILERPLATE.md を参照してください。canai-prepare と canai-mcp の両方で使用する、共通の Atomic Design ナビゲーション仕様については、references/STRUCTURE-NAVIGATION.md を参照してください。
目的
- 出力先は現在の作業ディレクトリ(またはユーザーが指定した出力パス)です。ファイルでは相対アセットパスを使用するため、プロジェクトフォルダーは自己完結型でポータブルです。後から WordPress のアップロード先にコピーしたり、ローカルで配信したり、インポートのために
**canai-mcp**に引き渡したりできます。 - ファイルは CanAI の形式に沿っています。Atomic Design ナビゲーションコメント、セマンティックな領域、Twig と
_canai_css/_canai_jsに後から簡単に対応付けられるクラス名を含みます。
技術スタック(厳守)
| 許可されるもの | 備考 |
|---|---|
| セマンティック HTML5 | <header>、<nav>、<main>、<section>、<article>、<aside>、<footer> |
| Tailwind CSS | ユーティリティクラスのみ。準備済み HTML に <style> ブロックを含めないこと(CanAI は CSS を _canai_css に保存します) |
| バニラ JS | <body> の末尾に配置する、小規模な IIFE または DOMContentLoaded ハンドラー |
| Alpine.js | 状態を持つ UI(ドロップダウン、タブ、アコーディオン)を手書きの JS より簡潔にできる場合に使用します |
| Lucide | <i data-lucide="icon-name" class="h-5 w-5"></i> |
| 使用禁止のもの |
|---|
React、Vue、Svelte、Angular、バンドラー、JSX、.vue SFC |
| このスキルでの Tailwind CLI/ビルド手順(Play CDN のクラスのみ) |
| Tailwind ユーティリティ以外の重量級 CSS フレームワーク |
ライブラリの読み込み — CanAI がサイト上で処理します
WP Admin → CanAI → Settings で有効にすると、CanAI は WordPress フックを通じて同じライブラリを出力します(TailwindManager、LucideManager、AlpineManager、AssetManager)。
| 静的プレビューファイルで再現するもの | CanAI が読み込む場所 |
|---|---|
<title>…</title> | **wp_head()** — WordPress がドキュメントタイトル(ページ/投稿の SEO タイトル)を出力します。テーマ/レイアウトがすでに wp_head() 経由で出力している場合は、_canai_html 内にリテラルの <title> を重複して記述しないでください |
Tailwind Play CDN、Alpine、Lucide UMD の <script> タグ(<head> 内の WPCanAI-PREVIEW-LIBS 内) | **wp_head()** — テーマ/CanAI のパイプラインが </head> の前に出力するヘッドスクリプトをエンキュー/挿入します |
<script>lucide.createIcons();</script>(</body> の前にある WPCanAI-PREVIEW-LIBS 内) | **wp_footer()** — フッタースクリプト(アイコンの初期化など) |
すべてのサイトで同じ切り替え設定が有効になっているとは限りません。必要に応じて、Load Tailwind、Lucide、および(テンプレートで x-* を使用する場合は)Alpine を有効にするようユーザーに伝えてください。
準備した .html ファイルには、WordPress 外のブラウザーでファイルを開けるよう、これらのスクリプトのプレビュー専用コピーが含まれています。次のように囲んでください。
...
CanAI にインポートする際は、テンプレートに貼り付けるマークアップからプレビューブロックを削除してください。代わりに CanAI が **wp_head()** / **wp_footer()** 経由で Tailwind/Lucide/Alpine を提供します。ページ固有の JS はプレビューマーカーの外側に置きます(_canai_js に対応します)。
レイアウトのマッピング — ヘッダー/フッターとメインコンテンツ
完全な静的 HTML ファイルには、プレビューや SPA の分割用に <header> と <footer> を含めることができます。CanAI にインポートした後は、通常、次のように分割します。
**<header>...</header>** → header タイプのテンプレートコンポーネント(サイトナビゲーションのシェル)。慣例として、メインの layout テンプレートで使用するサイトヘッダーコンポーネントです。**<footer>...</footer>** → footer タイプのテンプレートコンポーネント。慣例として、メインの layout で使用するサイトフッターコンポーネントです。**<main>...</main>**(ページ本文)→ ページまたはタイプ固有のテンプレートの**_canai_html**(レイアウト内の{{ page_content }}内)です。
リンクでつながれた単一 HTML ファイル(ワークフロー B)を生成する場合、静的プレビュー用に各ファイルでヘッダー/フッターを重複させても問題ありません。インポート時には、共通領域を一度だけ **wpcanai_template('site-header')** / **wpcanai_template('site-footer')**(またはプロジェクトで実際に使用しているヘッダー/フッターのスラッグ)に切り出し、各ページテンプレートには <main>(およびレイアウト固有のセクション)のみを残してください。
ナビゲーション — 2つのメニューにマークを付ける
サイトのメニューは最大2つです。
primary(ヘッダーナビ)とfooter(フッターナビ)です。 両方にマークを付け、実際のリンクを維持し、3つ目のメニュー名(topnav、mobile、main、social)を決して作らないでください。インポートすると、サイトの2つの WordPress メニューになり、CanAI がハードコードされたナビを出力することはありません。
- ヘッダーナビ:
<nav data-canai-menu="primary" aria-label="Primary">の直前に `` を配置します。 - フッターナビ:
<nav data-canai-menu="footer" aria-label="Footer">の直前に `` を配置します。フッターリンクが複数の列に分かれている場合は、すべての列をその1つの<nav>で囲みます。 - 両方の中に実際の
<a href>リンクを残します(href="about.html")。これにより、ブラウザーでファイルをプレビューできます。ここに Twig やメニューのループを書かないでください。インポート時にcanai-mcpがリンクをget_menu()のループに置き換えます。 - モバイルドロワーには primary のリンクが繰り返し表示されるため、こちらにも
data-canai-menu="primary"を付けます。パンくずリストとページネーションはメニューではなくNavigationランドマークなので、data-canai-menuは付けません。 menus.jsonはpages.jsonと同じ場所に作成し、マークされた各 nav のリンクを順番に記載します:{ "primary": [ … ], "footer": [ … ] }。生成されたページへのリンク項目は{ "title", "page" }(pageはpages.jsonにあるそのページのslug)、それ以外のリンクは{ "title", "url" }です。任意で"target": "_blank"と"children": [ … ](最大3階層)を指定できます。これはwpcanai-write-menuのitemsとまったく同じ形式です。references/BOILERPLATE.md の例を参照してください。- メガメニューもメニューデータです。 列見出しやドロップダウンのトリガーがリンクでない場合は、
childrenを持ち、pageもurlも持たない項目にします。リンクの1行説明は"description"に、Lucide アイコン名は"icon"に指定します(data-lucideと同じ名前です)。パネルの実際のマークアップは HTML に残し(見出し、アイコン、説明、リンク)、同じ構造をmenus.jsonに記載します。サムネイルは HTML 内に相対パスの<img>として残し、"image"は省略します。インポート時にcanai-mcpがサムネイルをサイドロードし、添付ファイル ID を追加します。
出力パス
デフォルトでは、現在の作業ディレクトリ(またはユーザーが指定したパス)の **./<project-slug>/** の下に書き込みます。WordPress のルートディレクトリや uploads フォルダーは不要です。
<project-slug>/
index.html
about.html
...
assets/
hero.webp
...
pages.json # optional; multi-page / SPA decomposition
menus.json # the primary / footer nav links (see Navigation)
**project-slug:** ケバブケースで短くします(例:landing-q2、shop-redesign)。**assets/:** デザインからコピーするか、SPA から書き出したバイナリメディアを格納します。相対パスで参照します(src="assets/photo.jpg")。- ページ間リンク: 絶対ドメインではなく、相対パスを使います(
href="about.html")。
ワークフロー A — 画像/モックアップ → HTML
- スクリーンショット、Figma の書き出し、またはその他の参照画像を受け取ります。
- レイアウトを推測します:ヘッダー、ヒーロー、セクション、フッター、タイポグラフィのスケール、間隔、色の役割(Tailwind のパレットに対応させます。必要な場合に限り、小さなインラインスクリプト内で
tailwind.configを任意で拡張します。標準ユーティリティを優先してください)。 - 画像コンテナのクラスを選ぶ前に、以下の画像フレーミングの事前チェックを実行します。
- ユーザーが依頼した、異なるフルページデザインごとに
.htmlファイルを1つ出力します。 - ナビゲーション可能な要素には、
、、など、正確な HTML 形式でラベルを付けます。references/STRUCTURE-NAVIGATION.md の制御語彙に従ってください。 - 抽出したラスター画像を
assets/に保存し、相対パスで参照します。安定したファイル名を使用します。任意で、プロジェクトフォルダー内の短いREADME.txtにそれらを記載できます。
画像フレーミングの事前確認
コンテナのマークアップを記述する前に、意味のあるラスター画像すべてに対して実行します。ロゴ、アイコン、装飾テクスチャ、および object-contain で表示される画像は、被写体のクロップ分析を行う必要はありません。
- 参照ページだけでなく、アセット自体を確認します。 利用可能なローカル画像情報ツールで固有の幅と高さを読み取り、ホストの画像ビューアーでピクセルを確認します。アスペクト比(
width / height)と重要な領域(顔、全身、複数の被写体、手、製品、受賞歴、画像に埋め込まれたテキストなど)を記録します。アセットを確認できない場合は、破壊的なクロップを推測するのではなく、object-containまたは元画像に近いアスペクト比で表示します。 - 元画像の形状とデザイン上の役割に合わせてコンテナを選びます。 高さの浅い固定
h-*クロップより、レスポンシブなaspect-*ユーティリティを優先します。縦長の元画像 →aspect-[4/5]、aspect-[3/4]、またはaspect-square、正方形 →aspect-squareまたはaspect-[4/3]、横長 →aspect-[16/9]、aspect-[3/2]、またはaspect-[4/3]。縦長画像を横長にクロップできるのは、確認した安全な領域がすべての対象ブレークポイントで確実に収まる場合に限ります。 object-coverを使用する場合は、視覚的な焦点を設定します。 まず次の基準を使い、実際の画像を見て調整します。顔写真/単独の人物写真はobject-[center_30%](Y方向でおよそ25~35%)、座っている2人はobject-[center_58%](Y方向で55~60%)、立っているグループはobject-[center_20%]、何かを持っている人物はobject-[center_80%](Y方向で75~85%)を使い、少なくともaspect-[3/4]または同等の高さを確保します。被写体が中央から外れている場合は、たとえばobject-[80%_25%]のように両方の座標を指定します。これらは調整の出発点であり、画像確認の代わりにはなりません。- レスポンシブなクロップを検証します。 モバイルの狭い画面とデスクトップの広い画面でプレビューします。顔、頭、ほかの被写体、タスクに関係するオブジェクトが、端に押し付けられることなく表示される必要があります。構図に応じてブレークポイントごとのアスペクト比や焦点のクラスを使用します。どのクロップでも安定して表示できない場合は、より縦長のコンテナ、または元画像に合ったコンテナを使うか、
object-containを使用します。
例:
<div class="aspect-[4/5] overflow-hidden rounded-2xl sm:aspect-[3/4]">
<img src="assets/founder.webp" alt="Founder holding the product" class="h-full w-full object-cover object-[center_80%]" width="1200" height="1600" loading="lazy">
</div>
ワークフロー B — SPA / PWA → 相互リンクされた静的 HTML ページ
- ルートを特定します。ルーター設定(
react-router、Vue Router、Next.js のapp/など)、sitemap、ナビゲーションリンク、またはユーザーが指定したリストを確認します。 - 各ルートにつき、自己完結型の HTML ファイルを1つ生成します(このスキルでは、各ファイルにヘッダー/フッター/ナビゲーションを複製し、パーシャルは使用しません)。
- クライアントサイドナビゲーションを、生成したファイル間の通常の
**<a href="...">** リンクに置き換えます。 - フレームワークコンポーネントを、セマンティック HTML + Tailwind + Alpine/バニラの動作に置き換えます。
- トレーサビリティのため、
**pages.json**({ "slug", "title", "file" }の配列)を作成します。 - マークされたヘッダーとフッターのナビゲーションから
**menus.json**を作成します(「ナビゲーション — 2つのメニューをマーク」を参照)。
CanAI 互換性チェックリスト
- ナビゲーションコメントは、指定された構文と統制語彙を正確に使用します。
- すべての
<main>、<section>、<header>、<footer>、<nav>、<aside>の直前には、対応する必須のタイプが記述されています。 - ヘッダーナビゲーションは
+ `<nav data-canai-menu="primary">`、フッターナビゲーションは+<nav data-canai-menu="footer">です。ほかのdata-canai-menu値は使用せず、menus.jsonにそれぞれのリンクを記載します。 - body コンテンツ内に
<style>は使用しません。やむを得ない場合を除き、インラインのstyle=""は使用せず、ユーティリティを優先します。 - スクリプト:プレビュー用ライブラリは
WPCanAI-PREVIEW-LIBS内に配置し、ページロジックはこれらのマーカーの外側の下に配置します。 - 画像:フレーミングの事前確認を完了し、説明的な
alt、固有のwidth/height、レスポンシブなアスペクト比のコンテナを設定します。スクロールせずに見えない位置にある画像にはloading="lazy"を設定します。 - Lucide:装飾アイコンには
aria-hidden="true"を設定し、操作要素にはaria-labelを設定します。 - リンク:内容がわかりやすいリンクテキストを使用し、実際のナビゲーションに
href="#"を使用しないでください。
CanAI への引き継ぎ
- 設定: 上記のようにスクリプトが
**wp_head()**/**wp_footer()**経由で読み込まれるよう、CanAI → Settings で Tailwind、Lucide、Alpine(使用する場合)を有効にします。 - ドキュメントタイトル: WordPress のページ/投稿タイトル(および使用する場合は SEO プラグインのフィールド)を設定します。
**wp_head()**は公開サイトで<title>を出力します。レイアウトに{{ wp_head() }}がすでに含まれている場合は、インポートするテンプレートの断片に重複する<title>を含めないでください。 - レイアウト: ヘッダーのマークアップをサイトヘッダーコンポーネントのテンプレートに、フッターをサイトフッターコンポーネントに移動し、メインのレイアウトテンプレートから呼び出します(
{{ wpcanai_template('site-header') }}、{{ wpcanai_template('site-footer') }}。実際のプロジェクトで使用されているスラッグを使ってください)。 - インポート:
**canai-mcp**を使用して(HTML → Twig に変換し、_canai_html/_canai_css/_canai_jsに書き込み)、保存ルール(例:CanAI の本文にはpost_contentを使用しない)に従います。 - テンプレートに貼り付けるときは、
WPCanAI-PREVIEW-LIBSブロックを削除します(CanAI がすでに読み込む内容の重複を避けます)。 - 画像はここではなく、インポート時に ID ベースのヘルパーに変換されます。 用意する
.htmlでは、フォルダーを通常のブラウザーでプレビューできるよう、src="assets/…"の相対パスを維持します。インポート時にcanai-mcpが各アセットをサイドロードし、<img>を{{ image_attrs(id, 'src,alt') }}に(その他の箇所は{{ media_url(id, size) }}に)メディアの id で書き換えます。そのため、用意するマークアップはすっきりと差し替え可能な状態にします。アセットごとに<img>は 1 つだけにし、内容を説明するaltを指定し、分かっている場合はwidth/heightを設定し、ヘルパーの出力と競合するインラインのstyleは指定しないでください。 - ナビゲーションコメントはインポート時に 1 対 1 で対応付けられます: `` は
{# Type / Short Label #}になります。タイプとラベルはそのまま維持し、区切り記号だけを置き換えます。wpcanai-scanが成功し、エディターの Structure メタボックスが役立つ状態を保てるよう、必須のランドマーク対応付けも含めて references/STRUCTURE-NAVIGATION.md に従ってください。 - コピーは翻訳に対応できる状態にします。 ネイティブの i18n を使う対象サイトでは、後続のインポート処理で、ユーザー向けの各文が 1 つの
{{ t('…') }}翻訳ソースに変換されます。各文は、それを含むブロック要素内に 1 つの単位として記述します。文中のインラインタグは問題ありません(<p>Get <strong>free shipping</strong> today.</p>は 1 つのソースになります)。また、文の中にブロック要素を置かないでください。これは画像 →image_attrs()とセクションコメントの引き継ぎ方法と同じです。 - WooCommerce ページ — ショップ/カート/チェックアウトページでは、カート/チェックアウト領域を
のようなナビゲーション可能なプレースホルダー 1 つとして出力し、実装に関する指示は別のコメントに記述します。後続の処理(canai-mcp)でwc_*Twig ヘルパーに置き換えるため、ここでヘルパーのマークアップを組み込まないでください。 - ナビゲーションはインポート時に WordPress メニューになります。
canai-mcpは、ページの作成後にwpcanai-write-menuを使ってmenus.jsonを書き込みます(キーごとに 1 回呼び出します)。また、各マーク付き<nav data-canai-menu>のリンクをget_menu('primary')/get_menu('footer')のループに置き換えます。用意するファイルには実際のリンクを残してください。サイト所有者が後から WordPress でメニューを編集します。
関連スキル
**canai-mcp**— 設定済みサーバー上で_canai_*を扱う MCP ツール。