shop-theme-development について
shop-theme-developmentは、Bagistoの開発者向けに、ストアフロントのテーマを独立して配布・保守できるLaravelパッケージとして作る方法を案内するスキルです。ビュー、アセット、サービスプロバイダー、テーマ設定、Viteによるビルドを扱います。
主な機能
- 01独立したLaravelテーマパッケージの作成
- 02テーマのビューと静的アセットの整理
- 03サービスプロバイダーとテーマ登録の設定
- 04Viteによるテーマアセットのビルド
- 05シンボリックリンクまたは公開による開発
活用シーン
- 01Bagistoのストアフロントに独自テーマを作る
- 02既定テンプレートを置き換えページを調整する
- 03アセットの開発用・本番用ビルドを設定する
- 04保守・配布しやすいテーマをパッケージ化する
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ bagisto/ agent-skills --skill shop-theme-developmentインストール後、Claude Code で/shop-theme-developmentを入力して読み込まれたか確認します。
詳細
ショップテーマの開発
概要
Bagistoでのショップテーマ開発では、Laravelパッケージとして配布するカスタムストアフロントテーマを作成します。最終的には、個別に配布および保守できる自己完結型のパッケージになります。
適用する場面
次のような場合に、このスキルを使用してください。
- パッケージとしてカスタムストアフロントテーマを作成する
- 配布用のテーマパッケージを構築する
- Viteで管理されるアセットを扱う
- 顧客向けページをカスタマイズする
- デフォルトのショップテンプレートをオーバーライドする
Bagistoのショップテーマアーキテクチャ
主要コンポーネント
| コンポーネント | 目的 | 場所 |
|---|---|---|
| テーマ設定 | 利用可能なテーマを定義します | config/themes.php |
| ビューのパス | Bladeテンプレートファイル | テーマ設定で定義 |
| アセットのパス | CSS、JS、画像 | テーマ設定で定義 |
| テーマミドルウェア | アクティブなテーマを解決します | packages/Webkul/Shop/src/Http/Middleware/Theme.php |
| テーマファサード | テーマの操作を管理します | packages/Webkul/Theme/src/Themes.php |
主な設定プロパティ
// config/themes.php
'shop-default' => 'default',
'shop' => [
'default' => [
'name' => 'Default',
'assets_path' => 'public/themes/shop/default',
'views_path' => 'resources/themes/default/views',
'vite' => [
'hot_file' => 'shop-default-vite.hot',
'build_directory' => 'themes/shop/default/build',
'package_assets_directory' => 'src/Resources/assets',
],
],
],
ショップテーマパッケージの作成
目標:完全な自己完結型パッケージ
最終的なパッケージには、次の内容を含めます。
- パッケージ内のすべてのビュー
- パッケージ内のすべてのアセット
- 公開用のサービスプロバイダー
- アセットコンパイル用のVite設定
ステップ1:パッケージ構造を作成する
mkdir -p packages/Webkul/CustomTheme/src/{Providers,Resources/views}
ステップ2:ショップのアセット一式をコピーする
完全に制御できるよう、ショップのアセットをすべてパッケージにコピーします。
# Copy complete shop assets folder
cp -r packages/Webkul/Shop/src/Resources/assets/* packages/Webkul/CustomTheme/src/Resources/assets/
# Copy complete shop views folder
cp -r packages/Webkul/Shop/src/Resources/views/* packages/Webkul/CustomTheme/src/Resources/views/
# Copy shop package.json for dependencies
cp packages/Webkul/Shop/package.json packages/Webkul/CustomTheme/
これにより、次の内容が含まれます。
- Tailwindを使用した完全なCSS基盤
- すべてのJavaScript機能
- ショップのコンポーネントとレイアウト
- 画像、フォント、静的アセット
- 完全なBladeテンプレート構造
- アセットコンパイル用の依存関係
ステップ3:カスタムホームページを追加する(ひな形)
コピー後、新しいテーマであることを示すカスタムホームページを作成します。
ファイル: packages/Webkul/CustomTheme/src/Resources/views/home/index.blade.php
<x-shop::layouts>
<x-slot:title>
Custom Theme Home
</x-slot>
{{-- Hero Section --}}
<div class="hero-section bg-gradient-to-r from-blue-600 to-purple-600 text-white py-20">
<div class="container mx-auto px-4 text-center">
<h1 class="text-5xl font-bold mb-6">
Welcome to Our Store
</h1>
<p class="text-xl mb-8 opacity-90">
Professional theme with modern design
</p>
<a href="{{ route('shop.search.index') }}"
class="bg-white text-blue-600 font-bold py-3 px-8 rounded-lg hover:bg-gray-100 transition duration-300">
Start Shopping
</a>
</div>
</div>
{{-- Featured Products --}}
<div class="container mx-auto px-4 py-16">
<h2 class="text-3xl font-bold text-center mb-12">
Featured Products
</h2>
</div>
</x-shop::layouts>
ステップ4:カスタムレイアウトを作成する(任意)
完全に制御するには、独自のマスターレイアウトを作成します。
ファイル: packages/Webkul/CustomTheme/src/Resources/views/layouts/master.blade.php
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ $title ?? config('app.name') }}</title>
{{-- Load theme assets manually --}}
@bagistoVite([
'src/Resources/assets/css/app.css',
'src/Resources/assets/js/app.js'
])
@stack('meta')
@stack('styles')
</head>
<body class="{{ $bodyClass ?? '' }}">
@if($hasHeader ?? true)
@include('custom-theme::layouts.header')
@endif
<main class="main-content">
{{ $slot }}
</main>
@if($hasFooter ?? true)
@include('custom-theme::layouts.footer')
@endif
@stack('scripts')
</body>
</html>
ステップ5:サービスプロバイダーを作成する
ファイル: packages/Webkul/CustomTheme/src/Providers/CustomThemeServiceProvider.php
<?php
namespace Webkul\CustomTheme\Providers;
use Illuminate\Support\ServiceProvider;
class CustomThemeServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
//
}
/**
* Bootstrap services.
*/
public function boot(): void
{
// Publish views to resources/themes/custom-theme/views
$this->publishes([
__DIR__ . '/../Resources/views' => resource_path('themes/custom-theme/views'),
], 'custom-theme-views');
}
}
ステップ6:オートローディングを設定する
composer.jsonを更新します。
"autoload": {
"psr-4": {
"Webkul\\CustomTheme\\": "packages/Webkul/CustomTheme/src"
}
}
実行:composer dump-autoload
ステップ7:サービスプロバイダーを登録する
bootstrap/providers.phpに追加します。
Webkul\CustomTheme\Providers\CustomThemeServiceProvider::class,
ステップ8:テーマ設定を更新する
ファイル: config/themes.php
'shop-default' => 'custom-theme',
'shop' => [
'default' => [
'name' => 'Default',
'assets_path' => 'public/themes/shop/default',
'views_path' => 'resources/themes/default/views',
'vite' => [
'hot_file' => 'shop-default-vite.hot',
'build_directory' => 'themes/shop/default/build',
'package_assets_directory' => 'src/Resources/assets',
],
],
'custom-theme' => [
'name' => 'Custom Theme Package',
'assets_path' => 'public/themes/shop/custom-theme',
'views_path' => 'resources/themes/custom-theme/views',
'vite' => [
'hot_file' => 'custom-theme-vite.hot',
'build_directory' => 'themes/custom-theme/build',
'package_assets_directory' => 'src/Resources/assets',
],
],
],
ステップ9:ビューを公開する
php artisan vendor:publish --provider="Webkul\CustomTheme\Providers\CustomThemeServiceProvider"
ステップ10:キャッシュをクリアする
php artisan optimize:clear
ステップ11:テーマを有効化する
- 管理パネルにログインします
- 「設定」→「チャネル」に移動します
- チャネルを編集し、テーマを選択します
- 保存します
ステップ12:アセットをビルドする
# Navigate to package
cd packages/Webkul/CustomTheme
# Install dependencies
npm install
# Build assets for production
npm run build
これにより、テーマのアセットがコンパイルされ、ビルドディレクトリが作成されます。ビルド後、作成したカスタムホームページを含むカスタムテーマを使用できるようになります。
Viteで管理されるアセット
ステップ1:アセット設定ファイルを作成する
パッケージのルートに次のファイルを作成します。
ファイル: package.json
{
"name": "custom-theme",
"private": true,
"description": "Custom Theme Package for Bagisto",
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"autoprefixer": "^10.4.14",
"axios": "^1.1.2",
"laravel-vite-plugin": "^0.7.2",
"postcss": "^8.4.23",
"tailwindcss": "^3.3.2",
"vite": "^4.0.0"
}
}
ファイル: vite.config.js
import { defineConfig, loadEnv } from "vite";
import laravel from "laravel-vite-plugin";
import path from "path";
export default defineConfig(({ mode }) => {
const envDir = "../../../";
Object.assign(process.env, loadEnv(mode, envDir));
return {
build: {
emptyOutDir: true,
},
envDir,
server: {
host: process.env.VITE_HOST || "localhost",
port: process.env.VITE_PORT || 5173,
cors: true,
},
plugins: [
laravel({
hotFile: "../../../public/custom-theme-vite.hot",
publicDirectory: "../../../public",
buildDirectory: "themes/custom-theme/build",
input: [
"src/Resources/assets/css/app.css",
"src/Resources/assets/js/app.js",
],
refresh: true,
}),
],
};
});
ファイル: tailwind.config.js
module.exports = {
content: [
"./src/Resources/**/*.blade.php",
"../../../resources/themes/custom-theme/**/*.blade.php"
],
theme: {
container: {
center: true,
screens: { "2xl": "1440px" },
padding: { DEFAULT: "90px" },
},
screens: {
sm: "525px",
md: "768px",
lg: "1024px",
xl: "1240px",
"2xl": "1440px",
1180: "1180px",
1060: "1060px",
991: "991px",
},
extend: {
colors: {
navyBlue: "#060C3B",
darkGreen: "#40994A",
},
fontFamily: {
poppins: ["Poppins"],
dmserif: ["DM Serif Display"],
},
},
},
plugins: [],
safelist: [{ pattern: /icon-/ }],
};
ファイル: postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
ステップ2:BagistoのVite設定に追加する
ファイル: config/bagisto-vite.php
'custom-theme' => [
'hot_file' => 'custom-theme-vite.hot',
'build_directory' => 'themes/custom-theme/build',
'package_assets_directory' => 'src/Resources/assets',
],
開発コマンド
# Navigate to package
cd packages/Webkul/CustomTheme
# Install dependencies
npm install
# Start dev server with hot reload
npm run dev
# Build for production
npm run build
開発ワークフロー
オプションA:シンボリックリンク(推奨)
再公開せずにリアルタイムで開発するため、シンボリックリンクを作成します。
# Remove published views
rm -rf resources/themes/custom-theme/views
# Create symlink from package to resources
ln -s $(pwd)/packages/Webkul/CustomTheme/src/Resources/views resources/themes/custom-theme/views
オプションB:パッケージを直接開発する
パッケージを直接編集し、必要に応じて再公開します。
# After making changes
php artisan vendor:publish --provider="Webkul\CustomTheme\Providers\CustomThemeServiceProvider" --force
ショップのレイアウト
Blade自体を記述していますか? マークアップのルール(属性バインディングにおける
:と::の使い分け、匿名コンポーネントとVue連携コンポーネントの使い分け、インデント、コメントのスタイル、翻訳やview_render_eventフックを配置する場所)については、blade-conventionsスキルを参照してください。
ショップレイアウトの使用
<x-shop::layouts>
<x-slot:title>
Page Title
</x-slot>
{{-- Page content --}}
</x-shop::layouts>
レイアウトのプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
has-header | Boolean | true | ヘッダーナビゲーションを含めます |
has-feature | Boolean | true | 注目セクションを表示します |
has-footer | Boolean | true | フッターを含めます |
最小限のページの例
<x-shop::layouts
:has-header="false"
:has-footer="false"
>
<x-slot:title>
Minimal Page
</x-slot>
{{-- Content without header/footer --}}
</x-shop::layouts>
ショップの Blade コンポーネント
使用可能なコンポーネント
| コンポーネント | 用途 | 説明 |
|---|---|---|
<x-shop::accordion> | 折りたたみ可能なセクション | コンテンツの表示/非表示を切り替えます |
<x-shop::breadcrumbs> | ナビゲーションの経路 | 現在のページのパスを表示します |
<x-shop::button> | アクションボタン | ローディング状態に対応しています |
<x-shop::datagrid> | データテーブル | 並べ替え、フィルタリング、ページネーション |
<x-shop::drawer> | スライド表示パネル | 位置:上/下/左/右 |
<x-shop::dropdown> | ドロップダウンメニュー | 位置:左上、右下など |
<x-shop::flat-picker.date> | 日付ピッカー | Flatpickr に基づいています |
<x-shop::flat-picker.datetime> | 日時ピッカー | Flatpickr に基づいています |
<x-shop::media.images> | 画像アップロード | 複数の画像に対応しています |
<x-shop::modal> | ダイアログボックス | ヘッダー、コンテンツ、フッターのスロット |
<x-shop::quantity-changer> | 数量入力 | +/- ボタン |
<x-shop::table> | データテーブル | thead/tbody をカスタマイズできます |
<x-shop::tabs> | タブナビゲーション | 位置:左/右/中央 |
<x-shop::shimmer.*> | ローディング効果 | スケルトンローダー |
カスタムレイアウト
カスタムレイアウトの作成
ファイル: packages/Webkul/CustomTheme/src/Resources/views/layouts/master.blade.php
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ $title ?? config('app.name') }}</title>
{{-- Load assets manually for custom layouts --}}
@bagistoVite([
'src/Resources/assets/css/app.css',
'src/Resources/assets/js/app.js'
])
</head>
<body>
@if($hasHeader ?? true)
@include('custom-theme::layouts.header')
@endif
<main>
{{ $slot }}
</main>
@if($hasFooter ?? true)
@include('custom-theme::layouts.footer')
@endif
</body>
</html>
パッケージの完全な構成
packages/Webkul/CustomTheme/
├── src/
│ ├── Providers/
│ │ └── CustomThemeServiceProvider.php
│ └── Resources/
│ ├── assets/
│ │ ├── css/
│ │ │ └── app.css
│ │ ├── js/
│ │ │ └── app.js
│ │ ├── images/
│ │ └── fonts/
│ └── views/
│ ├── layouts/
│ │ └── master.blade.php
│ ├── home/
│ │ └── index.blade.php
│ ├── components/
│ └── ...
├── package.json
├── vite.config.js
├── tailwind.config.js
└── postcss.config.js
主要ファイルのリファレンス
| ファイル | 目的 |
|---|---|
config/themes.php | テーマの設定 |
config/bagisto-vite.php | Vite アセットの設定 |
packages/Webkul/Shop/src/Providers/ShopServiceProvider.php | ショップパッケージの登録 |
packages/Webkul/Shop/src/Http/Middleware/Theme.php | テーマの解決 |
packages/Webkul/Theme/src/Themes.php | テーマファサード |
packages/Webkul/Shop/src/Resources/views/components/* | ショップコンポーネント |
よくある落とし穴
- テーマ設定を変更した後にキャッシュをクリアしない
- パッケージの登録後に composer dump-autoload を実行し忘れる
- ショップのアセット(ビューとアセット)をすべてコピーしない
- カスタムレイアウトで @bagistoVite アセットを手動で読み込まない
- パッケージのソースファイルではなく、公開済みファイルを編集する
- 開発ワークフロー用のシンボリックリンクを設定し忘れる
テスト
テーマは次の手順でテストしてください:
- チャネル設定でテーマを有効化する
- ストアフロントのページにアクセスする
- レスポンシブデザインを確認する
- ショップのすべての機能が動作することを確認する
- 開発中にホットリロードをテストする