テーマとブロックの作成に必要なスキル

Discourse テーマおよびブロックコンポーネントの構築のための Claude Code スキルリポジトリ:

:toolbox: 含まれる内容

テーマ作成スキル — Discourse テーマの構築に関する包括的な範囲をカバーします。discourse_theme CLI によるスキャフォールディング、SCSS アーキテクチャ、ビューポートライブラリ、ローカリゼーション、設定、修飾子、値変換、アイコン、CSS 変数などです。アイコン、変数、変換に関する詳細な参照ファイルは個別に含まれており、必要に応じて読み込むことができます。SKILL.md

ブロック作成スキル — ブロック API のテーマ側の機能をカバーします。@block デコレーターを使用したブロックコンポーネントの作成、引数スキーマの定義、利用可能なコアアウトレットへのブロックのレンダリング、条件、コンテナブロックとレイアウトのグルーピング、テーマの翻訳や設定をブロックの引数に統合することなどです。SKILL.md

サンプルテーマ — ブロックを使用して構築されたカスタムホームページを備えた動作するテーマで、アウトレット、条件、レイアウトの構成に関する実際のパターンを実証しています。


:jigsaw: ブロック API について

ブロック API は、テーマやプラグイン内でモジュール化され、組み合わせ可能な UI コンポーネントを構築するための Discourse の新しいフレームワークです。ブロックは、homepage-blockshero-blockssidebar-discovery などの名前付きアウトレットに登録された Glimmer コンポーネントであり、ルート、ユーザー、ビューポート、サイト設定、またはプラグインの有無に基づいて条件付きで表示できます。

このシステムの主な強みは、ブロックが小さく焦点の絞られたスコープを持ち、一貫したパターンに従っていることです。これにより、AI 支援開発に非常に適しています。ブロックスキルを持つモデルは、単一のパスで動作するブロックコンポーネントをスキャフォールディングし、それをアウトレットに登録し、条件を接続することができます。

このリポジトリのサンプルテーマは、利用可能なプラグインやコンテンツに基づいて適応するホームページを実証しています。基本的なホームページの外観は以下の通りで、ヒーローブロックと注目のトピックリストが含まれています。

追加の条件が満たされた場合(注目のタグが設定され、Discourse Events プラグインがアクティブで、Discourse Leaderboard プラグインが利用可能)、追加のブロックが条件付きでレイアウトにレンダリングされます。

ブロックはホームページに限定されません。サンプルテーマでは、sidebar-blocks アウトレットを使用して ホーム リンクを追加し、sidebar-discovery アウトレットを使用してカテゴリ固有のサイドバーコンテンツを追加し、カテゴリページの上部に category-banner ブロックを追加しています。

DevTools のブロックインスペクターは、ページ上に重ねて表示されるアウトレットラベルとブロック識別子を表示します。これにより、レイアウト構造を理解し、どこに何が表示されているかをデバッグすることが容易になります。


:art: デザインプラットフォーム MCP との併用

これらのスキルは、デザインプラットフォームの MCP(Penpot や Figma の MCP など)と非常に相性が良いです。MCP を接続すると、Claude はデザインファイルから直接コンポーネント仕様やデザイントークンを読み取り、スキルの慣習に従って実装できます。特に構造化されたデザインシステムから作業する場合は、デザインとコードの間のループがより密になります。


:fork_and_knife: フォークして調整

スキル内のいくつかの慣習は、SCSS フォルダのアーキテクチャのように、慣習というよりは好みに基づいています。リポジトリをフォークして、スキルを自身のワークフローや慣習に合わせて調整することができます。


:speech_balloon: 構築したもの共有

ぜひ試して、その結果をお知らせください!スキルをどのように使用しているか、それらで何を作成したか、どこに課題があるかなど、お聞かせいただければ幸いです。フィードバック、修正、フォークはすべて歓迎します。

Blocks 専用のトピックはありますか、それともこれがそれですか?

後者であれば、コードスニペットをいくつか追加すると役立つかもしれませんか?それとも、plugin-api.gjs ファイルに含まれているものが現在のドキュメントですか?

ありがとうございます。

コアおよびプラグインでの実装を含む、Blocks API 全体を網羅したドキュメントは引き続き存在します。Blocks を用いたテーマ化については、SKILL.md ですでに関連するすべての側面に触れられています。コンパクトで非常に読みやすい内容です。

サンプルテーマには、イニシャライザーファイルと Blocks の両方が含まれています。イニシャライザーファイルは BlockOutlet ごとにレイアウトを宣言します: discourse-theme-skills/javascripts/discourse/api-initializers at main · discourse/discourse-theme-skills · GitHub.

これで実際に楽しんでみました :winking_face_with_tongue: … 他の AI 設計ツールと同様、手作業でスケッチするにはコストがかかりすぎるアイデアを素早くプロトタイプするには非常にパフォーマンスが優れています。

コミュニティから非常に非伝統的なコンテンツを特集した、非常にブルータリズム風の編集用ホームページをリクエストしました。その結果、いくつかの非常に素晴らしいアイデアを持つフィーチャーブロックを含むこのレイアウトが生まれました。最も面白いのは、テーマを「地獄の新聞」と名付けたことです :grinning_face_with_smiling_eyes:

次に、いつも探求したかった、密度の高いブロック、パステルカラー、多数の小さなアニメーションを備えた、日本風のポータルホームページをリクエストしました。この最初の試みが気に入りました:

実際には、すべての小さなアニメーションがそれをより良く見せるため、スクリーンキャストが必要です:

flushy

やっとですね!できるだけ早く試して、実験的なテーマコンポーネントを更新します :smiley:

炎に囲まれたエルモ

素晴らしい作業で、非常に創造的です。このテーマをフォークして拡張する場合、親テーマが時間とともに Discourse のアップデートに対応しなくなることを考慮する必要がありますか?どのように取り組むべきか考え中です。

リソースを提供してくださり、ありがとうございます!

@BrianC さん、ありがとうございます!

親テーマの更新についてですが、スキルは Discourse のテーマ API と Blocks API を追跡しています。そのため、これらを積極的に使用し続けている限り、API が進化しても同期は保たれます。サンプルテーマはパターンを示すためのスナップショットに過ぎません。これをフォークすれば、そのフォークはあなたのものになります。ただし、テーマを更新する際は、スキルや新しいサンプルを参照してください。

Blocks API そのものの中心的な目標は、Discourse の更新に対してカスタマイズが堅牢であることを保証するための、安定した小さな表面積の提供です。したがって、主にカスタムブロックを追加している場合(サンプルテーマのように)、すでに安定した環境内で動作しているはずです。注意すべき点は、 outlet 名やブロック API のシグネチャの変更です。現時点では API は実験的とみなされているため、名前の変更などが起こる可能性があります。

推奨されるアプローチは以下の通りです:テーマを自由にフォークし、今後の進め方についての生きたリファレンスとしてスキルドキュメントを活用してください。

エージェント型コーディングを使わずに、これをいじり始めています。

これを、サイトのホームページのみを制御するテーマコンポーネントに変換するのは、それほど大変ではないような印象を受けます。例えば、すでにHorizonテーマを使用しているサイトの場合です。これは愚かな考えでしょうか?

また、いくつかの問題点に気づきました:

今後のイベントブロックがトピックをソートしない

単に作成日順にイベントトピックを出力するだけで、これは非常に使いにくいです!!

ask.discourse.comでは、この問題を修正するためにこの種の変更を提案しており、私が確認したところ、これは機能します(批判的な思考が欠如していることをお許しください):

@bind
async fetchEvents() {
  const count = this.args.count || 5;
  const results = await ajax("discourse-post-event/events");

  if (!results.events?.length) {
    return null;
  }

  const now = new Date();

  // 過去と未来のイベントを分離し、開始日順に昇順でソート
  const upcoming = results.events
    .filter((e) => new Date(e.starts_at) >= now)
    .sort((a, b) => new Date(a.starts_at) - new Date(b.starts_at));

  return upcoming.slice(0, count);
}

カテゴリバナーブロックが設定を反映しない

すべてのカテゴリに表示され(指定されたカテゴリのみではありません)、ナビゲーション時に更新されないようです(ページをリフレッシュした場合のみ更新されます)。

@nathank さん、試していただきありがとうございます!まだ実験的な段階ですので、APIに変更を加える可能性があります。そのため、現時点ではホームページビルダータイプのテーマコンポーネントをこの上に構築することはおすすめしません。

デモブロックは基本的な例に過ぎません。また、データの読み込み方法を改善するAPI変更も予定されています。これらが利用可能になった時点で、デモテーマのすべてのブロックに変更を反映します。

カテゴリバナーブロックはすべてのカテゴリに表示されるはずです。ご参照いただいたカテゴリピッカーは、ホームページ上の注目カテゴリブロック用のものではないでしょうか。