mcpField
S
spree-admin

spree-admin

github.com/spree開発10123 回インストール4 週間前に更新
リポジトリ

spree-admin について

spree-adminは、Spree 5.xのRailsベースの旧管理画面をカスタマイズする開発者向けスキルです。リソースのスキャフォールド生成に加え、ナビゲーション、テーブル、ビュー、コントローラーの変更を扱います。

主な機能

  1. 01CRUD管理画面のスキャフォールド生成
  2. 02サイドバーナビゲーションのカスタマイズ
  3. 03テーブル列の設定
  4. 04ビューのオーバーライドとパーシャルの挿入
  5. 05管理画面用フォームヘルパーの利用

活用シーン

  1. 01モデル用の管理画面追加
  2. 02管理一覧とナビゲーションの調整
  3. 03カスタムビューによる管理画面の拡張

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/spree/agent-skills --skill spree-admin

インストール後、Claude Code で/spree-adminを入力して読み込まれたか確認します。

詳細

Spree Legacy Rails Admin (spree_admin)

以下のコマンドでは Spree CLI 形式(spree …、Docker)を使用します。CLI を使わない従来の Rails アプリ(通常は 5.4 より前)では、spree-project スキルのネイティブな対応方法を使用してください。アプリのルートから bin/rails/bundle exec rake を実行し、パスから backend/ プレフィックスを除きます。

管理画面は Rails エンジンです。ERB ビューをサーバー側でレンダリングし、インタラクティブ機能には Stimulus + Turbo、スタイルには Tailwind を使用します。(Spree 6.0 では新しい React ベースの管理画面が導入されます。Spree 5.x では spree_admin が管理画面です。)

プロジェクト構成

Rails 管理画面は spree_admin gem にあり、/admin にマウントされています。通常の Rails アプリとして扱ってください。

spree_admin gem
├── app/
│   ├── controllers/spree/admin/         # admin controllers
│   ├── views/spree/admin/<resource>/    # ERB views per resource
│   ├── helpers/spree/admin/             # view helpers
│   ├── presenters/spree/admin/          # presenter pattern for complex views
│   ├── javascript/spree/admin/          # Stimulus controllers, importmap-managed
│   └── models/spree/admin/navigation*   # nav + nav builder
└── lib/generators/spree/admin/
    ├── install/                         # bin/rails g spree:admin:install
    └── scaffold/                        # bin/rails g spree:admin:scaffold

ホストアプリ(backend/)では、同じパスにあるファイルを backend/app/ の下でオーバーライドしてカスタマイズします。Rails のビューのパス解決では、gem よりもホストアプリのファイルが優先されます。

新しい管理リソースの追加(1 コマンドで実行)

Spree には、任意のモデルの CRUD 管理画面一式を生成する管理画面スキャフォールドジェネレーターが用意されています。モデルとマイグレーションを作成した後(spree:api_resource または spree:model を使用します)に、次を実行します。

spree rails g spree:admin:scaffold Spree::Brand

次のファイルが生成されます。

ファイル用途
backend/app/controllers/spree/admin/brands_controller.rbSpree::Admin::ResourceController を継承するコントローラー
backend/app/views/spree/admin/brands/index.html.erb一覧ページ(render_table @collection, :brands をレンダリングします。列はテーブルレジストリから取得します)
backend/app/views/spree/admin/brands/new.html.erb作成フォームページ
backend/app/views/spree/admin/brands/edit.html.erb編集フォームページ
backend/app/views/spree/admin/brands/_form.html.erb共通フォームのパーシャル
backend/config/initializers/spree_admin_brands_table.rbテーブル列の登録
backend/config/initializers/spree_admin_brands_navigation.rbサイドバーナビゲーションの登録
backend/config/routes.rbadd_routes ブロックに挿入される namespace :admin { resources :brands }

ジェネレーターは、Spree::Core::Engine.add_routes do ブロック(spree-starter テンプレートに含まれています)の内側に、backend/config/routes.rb へのルートも挿入します。routes.rb にこのブロックがない場合は、手動でルートを追加してください。

# backend/config/routes.rb
Rails.application.routes.draw do
  Spree::Core::Engine.add_routes do
    namespace :admin do
      resources :brands
    end
  end

  mount Spree::Core::Engine, at: '/'
end

add_routes(生の Spree::Core::Engine.routes.append ではありません)がサポート対象の方法です。アプリの再読み込み時にルートが二重に定義されるのを防ぎます。

(API に spree:api_resource を使用する場合、API のルートは管理画面のルートとは別です。異なる名前空間にあります。)

新しいイニシャライザーとルートを読み込むため、Rails を再起動してください。

spree restart

サイドバーのカスタマイズ

サイドバーの項目はイニシャライザーで登録します。基本パターンは次のとおりです。

# backend/config/initializers/spree_admin_brands_navigation.rb
Rails.application.config.after_initialize do
  Spree.admin.navigation.sidebar.add :brands,
    label: :brands,                                       # i18n key or string
    url: :admin_brands_path,                              # symbol → route helper, or string
    icon: 'list',                                         # Tabler icon name (https://tabler.io/icons)
    position: 55,                                         # lower = earlier in sidebar
    active: -> { controller_name == 'brands' },           # when to highlight
    if: -> { can?(:manage, Spree::Brand) }                # CanCanCan visibility check
end

よく使われるナビゲーションのパターン:

# Top-level item that opens a sub-menu
Spree.admin.navigation.sidebar.add :marketing, label: :marketing, position: 30 do |nav|
  nav.add :promotions, label: :promotions, url: :admin_promotions_path, position: 10
  nav.add :coupon_codes, label: :coupon_codes, url: :admin_coupon_codes_path, position: 20
end

# Remove an existing entry
Spree.admin.navigation.sidebar.remove :reports

# Reorder an existing entry
Spree.admin.navigation.sidebar.update :products, position: 5

必要に応じて、ナビゲーション API の全容は spree/admin/app/models/spree/admin/navigation.rb でソースを確認できます。

管理画面のテーブルのカスタマイズ

管理画面の一覧ページの大半(Products、Orders、Promotions など)では、登録済みのテーブル定義を使用します。登録済みのキーは gem の config/initializers/spree_admin_tables.rb を参照してください(注:Customers ページは :users として登録されています。Payment Methods など、一部のページではテーブルレジストリを使用しません)。イニシャライザーから列を追加、削除、または並べ替えます。

# backend/config/initializers/spree_admin_products_table_customization.rb
Rails.application.config.after_initialize do
  # Add a column to the existing Products table
  Spree.admin.tables.products.add :brand_name,
    label: :brand,                                        # i18n key
    type: :string,                                        # :string | :number | :date | :datetime | :money | :status | :link | :boolean | :image | :custom | :association
    sortable: true,
    filterable: true,
    default: true,                                        # visible by default (vs opt-in via column toggle)
    position: 25

  # Remove a column
  Spree.admin.tables.products.remove :sku

  # Update an existing column
  Spree.admin.tables.products.update :name, label: :product_name
end

独自に生成したテーブル(spree:admin:scaffold を使用)では、適切なデフォルト設定(name、created_at、updated_at)を含むイニシャライザーが生成されます。ドメイン固有の列を追加してください。

カスタム列のレンダリング:列の値が直接の属性ではない場合は、モデルまたはプレゼンター/デコレーターにメソッドを定義します。列のキー(add の最初の引数)は、デフォルトで検索メソッドとして使用されます。method: を渡すと、別のメソッド名やレコードを受け取るラムダを指定できます。たとえば、Products テーブルに brand_name 列を追加する場合は、Product モデルまたはプレゼンターに brand_name を定義します。

# In your model or decorator
def brand_name
  brand&.name
end

ビューの上書き

同じパスのファイルをホストアプリに置くと、Rails はそのファイルを使用します。gem には spree/admin/app/views/spree/admin/products/index.html.erb が含まれており、backend/app/views/spree/admin/products/index.html.erb に置くと上書きできます。

注意点が 2 つあります。

  1. まずファイル全体をコピーしてから編集してください。一部だけの上書きは機能しません。Rails はホストアプリのファイルをそのまま使用します。bundle show spree_admin を使うと、gem 内のビューの場所を確認できます。

  2. ビューのファイルには、インタラクティブな動作のための data-controller Stimulus バインディングがあります。data-controller="…" 属性を削除すると、関連する JS が動作しなくなります。明示的に置き換えるのでない限り、バインディングは残してください。

軽微な上書きには、ビュー全体を上書きする代わりに、管理画面の名前付きインジェクションポイントを使用してください。ビューは render_admin_partials を使って、登録された部分テンプレートのリスト(例:head、body_end、products_header、product_form)をレンダリングします。部分テンプレート(例:backend/app/views/spree/admin/shared/_my_banner.html.erb)を作成し、イニシャライザーに登録します。

Rails.application.config.after_initialize do
  Spree.admin.partials.body_end << 'spree/admin/shared/my_banner'
end

コンソールで Spree.admin.partials.keys を実行すると、すべてのインジェクションポイントを一覧表示できます。

管理画面 UI の構築 — フォームビルダー、コンポーネント、ヘルパー

管理画面のビューや部分テンプレート(スキャフォールドで生成したリソースフォーム、挿入した product_form セクション、上書きしたビュー)を書くときは、生の Rails ヘルパーではなく、管理画面独自の UI 用語を使ってください。一貫したスタイル、ラベル、エラー表示、i18n をすぐに利用できます。

フォームビルダー(重要)

管理画面のすべての form_with は、自動的に Spree::Admin::FormBuilder(管理画面の BaseController にある default_form_builder)を使用します。設定は不要です。

<%= form_with model: [:admin, @brand] do |f| %>
  <%= f.spree_text_field :name, required: true %>
  <%= f.spree_text_field :code, help: "Leave blank to auto-generate" %>
  <%= f.spree_money_field :price, currency: current_store.default_currency %>
  <%= f.spree_collection_select :tax_category_id, Spree::TaxCategory.all, :id, :name,
        { include_blank: true, autocomplete: true }, {} %>
  <%= f.spree_check_box :active %>
  <%= f.spree_file_field :logo, width: 240, height: 240 %>
<% end %>

メソッドの全一覧:spree_text_field、spree_number_field、spree_money_field(ロケールに対応した区切り文字を使用し、送信時に小数値へ正規化して、通貨記号を追加します)、spree_email_field、spree_date_field、spree_datetime_field、spree_text_area(自動で高さを調整します)、spree_rich_text_area(Trix)、spree_select / spree_collection_select(検索可能なドロップダウンにするには autocomplete: true を渡します。選択肢が 20 個以上あるセレクトで使用してください)、spree_check_box、spree_radio_button(特定のラジオボタンにラベルを紐付けるには、明示的な :id を渡してください。指定しない場合、ラベルは値で照合されます)、spree_file_field(ドラッグ&ドロップ、プレビュー、crop: true、allowed_file_types:)。

すべてのメソッドで共通のオプション:label:(文字列、または非表示にする場合は false)、required:(アスタリスクを表示)、help:(フィールドの下に表示するテキスト)、help_bubble:(ラベルの横に表示するツールチップアイコン)、class:。バリデーションエラーはフィールドの下に自動で表示されます。ラベルは i18n(spree.<attribute>、次に activerecord.attributes.spree/<model>.<attribute>)を使って解決されます。

UI コンポーネント

ヘルパーでレンダリングする、管理画面のデザインシステムに合ったコンポーネントです。独自にマークアップを作成する代わりに、これらを使用してください。

コンポーネントヘルパー
ドロップダウンdropdown { dropdown_toggle + dropdown_menu }
ダイアログ(モーダル)/ドロワー(サイドパネル)dialog_header、dialog_close_button、dialog_discard_button;drawer_header、drawer_close_button
アイコンicon('plus') — Tabler のアイコン名
フォールバック付き画像spree_image_tag
ツールチップtooltip、help_bubble
ステータスバッジactive_badge(condition)
アバター、クリップボードへのコピー、プログレスバーrender_avatar、clipboard_component / clipboard_button、progress_bar_component
ストアのタイムゾーンでの日付spree_date、spree_time、spree_time_ago、local_time
知っておくと便利なビュー ヘルパー
  • ナビゲーション/リンク: link_to_with_icon、link_to_edit、link_to_delete(Turbo の確認機能を内蔵)、button、external_link_to、page_header_back_button
  • Turbo: turbo_save_button_tag(保存中の状態を表示して送信)、turbo_render_alerts、turbo_close_dialog
  • コンテキスト: current_store、current_currency、try_spree_current_user、supported_currencies
  • モデルの設定: preference_fields / preference_field_for — モデルの preference :x 宣言に対応するフォーム入力欄を自動的に描画します(決済方法とストアの設定フォームはこの方法で構築されています)

完全なリファレンスは、ローカルドキュメントの node_modules/@spree/docs/dist/developer/admin/form-builder.md、components.md、helper-methods.md にあります。

管理画面のコントローラーをデコレートする

Spree の管理画面コントローラーは通常の Rails コントローラーなので、ほかのコントローラーと同様にデコレートできます。spree generate controller_decorator Spree::Admin::ProductsController でファイルを生成すると、prepended フックと prepend の配線を含む backend/app/controllers/spree/admin/products_controller_decorator.rb が生成されます(ジェネレーターはモジュールをネストし、完全修飾の prepend 行を外側に配置します。手書きで同等のものを作成する場合は、こちらのほうが簡潔です)。

# backend/app/controllers/spree/admin/products_controller_decorator.rb
module Spree::Admin::ProductsControllerDecorator
  def self.prepended(base)
    base.before_action :my_custom_check, only: [:create, :update]
  end

  private

  def my_custom_check
    # ...
  end
end

Spree::Admin::ProductsController.prepend Spree::Admin::ProductsControllerDecorator

これはナビゲーションやテーブルのカスタマイズよりも影響が大きいため、アクションの動作を変更する必要がある場合に限って使用してください。まず、サブスクライバー(副作用向け)やサービスの差し替え(ビジネスロジック向け)で対応できないか確認してください。カスタマイズの判断基準の全体については、spree-project スキルを参照してください。

Stimulus コントローラー — 管理画面のインタラクティブ機能

Rails 管理画面では、クライアント側のインタラクティブ機能に Stimulus と Turbo を使用しています。既存のコントローラーは spree_admin/app/javascript/spree/admin/controllers/ にあります。

コントローラー機能
sidebar_controller.jsサイドバーの切り替えと状態の保持
variants_form_controller.js商品編集時のバリアント管理
page_builder_controller.jsCMS ページビルダーのドラッグ&ドロップ
bulk_editor_controller.js複数行のテーブル編集
dropdown_controller.jsドロップダウンメニュー

独自の Stimulus コントローラーを追加するには、backend/app/javascript/controllers/ に配置し、importmap(backend/config/importmap.rb)で登録します。ビューからは data-controller="my-controller" で参照します。

Turbo Streams(サーバーからプッシュされる UI の更新)では、Rails 7 以降の Hotwire アプリと同じパターンを使用できます。コントローラーから turbo_stream.* を描画し、ID を使ってフレームを指定します。

判断基準:どのような管理画面の変更ですか?

目的使用するもの
独自ページへのリンクをサイドバーに追加するイニシャライザーで Spree.admin.navigation.sidebar.add
管理画面のテーブルに列を追加するイニシャライザーで Spree.admin.tables.<name>.add
新しいリソースの CRUD セクションを追加するbin/rails g spree:admin:scaffold Spree::YourModel
フォームを作成または編集するf.spree_* フォームビルダーのメソッド。「管理画面の UI を構築する」を参照してください
モーダル/ドロップダウン/バッジ/ツールチップを追加するコンポーネント ヘルパー。「管理画面の UI を構築する」を参照してください
既存ページの見た目を変更するbackend/app/views/spree/admin/... のビューをオーバーライドする
コントローラーに新しいアクションを追加するデコレーター(最後の手段です。まず spree-project スキルを参照してください)
フォームの入力欄をインタラクティブにするStimulus コントローラーと、ビュー内の data-controller="..."
UI にリアルタイム更新をプッシュするサブスクライバーまたはサービスから Turbo Stream ブロードキャストを送信する
管理画面全体のスタイルを変更するbackend/app/assets/tailwind/spree_admin.css(インストーラーによって作成されます)を編集します。このファイルは gem の基本スタイルを app/assets/tailwind/spree/admin/index.css からインポートします。ここに @theme のオーバーライドとカスタム Tailwind を追加します

さらに詳しく知りたい場合

  • 管理画面のソース: bundle show spree_admin で、インストールされた gem のパスを確認できます。gem のルートにある README では、基本理念について説明しています。
  • カスタマイズのドキュメント: node_modules/@spree/docs/dist/developer/admin/ では、各種パターンを説明しています。
  • ナビゲーション API: Spree::Admin::Navigation のソースには、ナビゲーションをカスタマイズするためのメソッドがすべて記載されています。
  • テーブル API: gem 内の Spree::Admin::Table(app/models/spree/admin/table.rb)および Spree::Admin::Table::Column(app/models/spree/admin/table/column.rb)には、列の種類、オプション、並べ替え・フィルタリングの詳細が記載されています。Spree.admin.tables の背後にあるレジストリは、lib/spree/admin/engine.rb 内の Spree::Admin::Engine::TablesEnvironment です。
  • スキャフォールドジェネレーター: bundle show spree_admin/lib/generators/spree/admin/scaffold/ に、より高度なカスタマイズに使えるテンプレートファイルがあります。
  • フォームビルダー/コンポーネント/ヘルパー: node_modules/@spree/docs/dist/developer/admin/form-builder.md、components.md、helper-methods.md には、上記の「管理画面 UI の構築」で扱うすべての項目について、オプションの一覧表が記載されています。

コメント