# Theme Development
# Quick Start
Sample Theme Repository: https://github.com/beikeshop/beikeshop-sample-theme
You can download the sample theme first and refer to its directory structure and code for development:
# Download the sample theme
git clone https://github.com/beikeshop/beikeshop-sample-theme.git
# Copy the SampleTheme folder to the plugins/ directory of beikeshop
# Then modify and develop according to the instructions in this document
# I. Theme Architecture Overview
BeikeShop supports developing template themes in the form of plugins. The same functionality can have completely different user interfaces.
# Template Loading Mechanism
The system adopts the following template loading strategy:
- Priority is given to the enabled theme template
- If a file does not exist in the enabled template, it falls back to the default template file under the
themes/defaultdirectory
This means you only need to override the template files you want to customize; you do not need to copy all files.
# Core Directory Structure
beikeshop/
├── plugins/ # Plugin directory
│ └── YourTheme/ # Your template plugin (folder name, PascalCase)
│ ├── config.json # Plugin configuration (required)
│ ├── Bootstrap.php # Plugin bootstrap file (required)
│ ├── Resources/ # Development source files (SCSS/JS)
│ │ └── beike/shop/your_theme/
│ │ ├── css/
│ │ │ ├── bootstrap/bootstrap.scss
│ │ │ └── app.scss
│ │ └── js/
│ │ └── app.js
│ ├── Themes/ # Blade template files
│ │ └── your_theme/
│ │ ├── layout/
│ │ │ └── master.blade.php
│ │ ├── home.blade.php
│ │ └── ...
│ ├── Static/ # Static assets (published to public)
│ │ ├── image/
│ │ │ ├── logo.png # Plugin icon
│ │ │ └── theme.jpg # Theme preview image
│ │ └── public/
│ │ └── build/beike/shop/your_theme/
│ │ ├── css/
│ │ │ ├── bootstrap.css # Compiled CSS
│ │ │ └── app.css
│ │ └── js/
│ │ └── app.js
│ └── Seeders/ # Demo data (optional)
│ └── ThemeSeeder.php
├── themes/ # System template directory (auto-copied during installation)
│ └── your_theme/ # Copied from plugins/YourTheme/Themes
└── public/ # Public resource directory (auto-copied during installation)
└── plugin/your_theme/ # Copied from plugins/YourTheme/Static
# II. Creating a Theme Plugin
# 2.1 Create the Plugin Directory
Create your template folder under the plugins/ directory, for example, Fashion:
mkdir plugins/Fashion
# 2.2 Create config.json
Create config.json in the plugin root directory. This is the core configuration file for the plugin:
{
"code": "fashion",
"name": {
"zh_cn": "Fashion Theme",
"en": "Fashion Theme"
},
"description": {
"zh_cn": "A fashionable e-commerce theme",
"en": "A fashionable e-commerce theme"
},
"type": "theme",
"version": "v1.0.0",
"icon": "/image/logo.png",
"theme": "/image/theme.jpg",
"author": {
"name": "Your Name",
"email": "your@email.com"
}
}
Important Field Descriptions:
| Field | Description | Example |
|---|---|---|
code | Template unique identifier, lowercase + underscore naming | fashion, my_theme |
name | Template name, supports multiple languages | {"zh_cn": "Fashion Theme", "en": "Fashion Theme"} |
type | Must be theme | theme |
icon | Plugin icon path, relative to the Static/ directory, size 500×500 | /image/logo.png |
theme | Template preview image path, relative to the Static/ directory, size 740×856 | /image/theme.jpg |
# 2.3 Create Bootstrap.php
Create Bootstrap.php in the plugin root directory. This is the plugin bootstrap file:
<?php
namespace Plugin\Fashion;
class Bootstrap
{
public function boot()
{
// Add hook logic here
// For example: add custom CSS/JS to the page
add_hook_blade('layout.header.code', function ($callback, $output, $data) {
return view('fashion::shop.custom-code');
});
}
}
Naming Rules:
namespacemust bePlugin\YourPluginFolderName(PascalCase)- Class name must be
Bootstrap - Must contain the
boot()method
# III. Developing Template Files
# 3.1 Blade Template Files
Template files are placed under the Themes/ directory. The directory structure should be consistent with themes/default.
Development Workflow:
Copy the template files you need to modify from
themes/defaultto your plugin directory:themes/default/home.blade.php → plugins/Fashion/Themes/fashion/home.blade.phpOnly modify the files you need to customize; files that don't need modification can remain default
System loading order:
- First look for
themes/fashion/xxx.blade.php - If it doesn't exist, fall back to
themes/default/xxx.blade.php
- First look for
Example Directory Structure:
plugins/Fashion/Themes/fashion/
├── layout/
│ ├── master.blade.php # Main layout (optional override)
│ ├── header.blade.php # Header (optional override)
│ └── footer.blade.php # Footer (optional override)
├── home.blade.php # Homepage
├── category.blade.php # Category page
├── product/
│ └── product.blade.php # Product detail page
└── cart/
└── cart.blade.php # Shopping cart page
# 3.2 SCSS/CSS Styles
Style source files are placed under Resources/beike/shop/your_theme/css/.
Directory Structure:
plugins/Fashion/Resources/beike/shop/fashion/css/
├── bootstrap/
│ └── bootstrap.scss # Bootstrap custom variables
├── app.scss # Main style file
├── global.scss # Global styles
├── header.scss # Header styles
├── footer.scss # Footer styles
└── home.scss # Homepage styles
app.scss Example:
// Import bootstrap variables
@import 'bootstrap/bootstrap';
// Import module styles
@import 'global';
@import 'header';
@import 'footer';
@import 'home';
# 3.3 JavaScript
JS source files are placed under Resources/beike/shop/your_theme/js/.
Directory Structure:
plugins/Fashion/Resources/beike/shop/fashion/js/
├── app.js # Main JS file
├── common.js # Common functions
├── header.js # Header interactions
└── product.js # Product page interactions
app.js Example:
import './common';
import './header';
import './product';
# IV. Compilation Configuration (Key Point)
# 4.1 Configure webpack.mix.js
This is the most critical step. When developing a new template, you must configure the webpack.mix.js file.
Open the webpack.mix.js file in the project root directory, find the commented-out template compilation code segment (around lines 30-55), uncomment it and modify themeFileName to your plugin folder name (PascalCase):
/* If developing a new theme, uncomment the following code and set themeFileName to your theme folder name */
const themeFileName = 'Fashion'; // ← Modify to your plugin folder name (PascalCase)
const themeCode = themeFileName.replace(/([A-Z])/g,"_$1").toLowerCase().replace(/^_/,'');
// Copy template blade files to the themes directory
if (!mix.inProduction()) {
mix.copy(`plugins/${themeFileName}/Themes`, 'themes');
}
// Compile template scss/js to public/build
mix.sass(`plugins/${themeFileName}/Resources/beike/shop/${themeCode}/css/bootstrap/bootstrap.scss`, `public/build/beike/shop/${themeCode}/css/bootstrap.css`)
.then(() => {
fs.copyFileSync(`public/build/beike/shop/${themeCode}/css/bootstrap.css`, `plugins/${themeFileName}/Static/public/build/beike/shop/${themeCode}/css/bootstrap.css`);
});
mix.sass(`plugins/${themeFileName}/Resources/beike/shop/${themeCode}/css/app.scss`, `public/build/beike/shop/${themeCode}/css/app.css`)
.then(() => {
fs.copyFileSync(`public/build/beike/shop/${themeCode}/css/app.css`, `plugins/${themeFileName}/Static/public/build/beike/shop/${themeCode}/css/app.css`);
});
mix.js(`plugins/${themeFileName}/Resources/beike/shop/${themeCode}/js/app.js`, `public/build/beike/shop/${themeCode}/js/app.js`)
.then(() => {
fs.copyFileSync(`public/build/beike/shop/${themeCode}/js/app.js`, `plugins/${themeFileName}/Static/public/build/beike/shop/${themeCode}/js/app.js`);
});
Important Notes:
| Variable | Description | Example |
|---|---|---|
themeFileName | Plugin folder name, PascalCase naming | Fashion, MyTheme |
themeCode | Auto-converted code (lowercase + underscore) | fashion, my_theme |
Conversion Rules:
Fashion → fashion
MyTheme → my_theme
Fashion4 → fashion4
# 4.2 Compilation Commands
Development Phase (watch file changes, auto-compile):
npm install # Required for the first time to install dependencies
npm run watch # Watch mode, auto-compiles after file modification
Production Environment (minified build):
npm run prod # Minified compilation of CSS/JS
# 4.3 Compilation Output Description
After compilation, the following files will be automatically generated:
public/build/beike/shop/fashion/
├── css/
│ ├── bootstrap.css
│ └── app.css
└── js/
└── app.js
At the same time, through the .then() callback, the compiled files will be automatically copied to the plugin's Static/public/build/ directory:
plugins/Fashion/Static/public/build/beike/shop/fashion/
├── css/
│ ├── bootstrap.css
│ └── app.css
└── js/
└── app.js
# 4.4 ⚠️ Must Confirm Compiled Files Are Synced Before Packaging
This is a critical point that many developers easily overlook!
Before packaging and publishing the template, you must ensure:
- The compiled CSS/JS files already exist in the
Static/public/build/directory - These files will be packaged with the plugin, so users will have styles after installation
How to ensure:
Method 1 (Recommended): Use the auto-copy function configured in
webpack.mix.js- Uncomment the template compilation code
- Run
npm run prod - Compiled files will be automatically copied to the
Static/public/build/directory
Method 2 (Manual): Manually copy compiled files
- Copy files from
public/build/beike/shop/your_theme/ - Paste to
plugins/YourTheme/Static/public/build/beike/shop/your_theme/
- Copy files from
If you forget this step, users will have no styles after installing the template!
# V. Installing and Enabling the Template
# 5.1 Install the Template
- Go to Admin Panel → Plugin List
- Find your template plugin
- Click Install
During installation, the system will automatically:
- Copy Blade templates from the
Themes/directory tothemes/your_theme/ - Copy static assets from the
Static/directory to the correspondingpublic/directory
# 5.2 Enable the Template
- Go to Admin Panel → Design → Template Settings
- Find your template and click Enable
- Optional: Check "Import Demo Data" (if the template provides Seeders)
- Confirm enable
# 5.3 Visit the Storefront
After enabling, visit the storefront to see the effect of the new template.
# VI. Template Data Seeders (Optional)
If your template needs to include demo data (such as homepage layout configuration), you can use Seeders.
# 6.1 Create a Seeder
Create ThemeSeeder.php under the Seeders/ directory:
<?php
namespace Plugin\Fashion\Seeders;
use Beike\Repositories\SettingRepo;
use Illuminate\Database\Seeder;
class ThemeSeeder extends Seeder
{
public function run()
{
$homeSetting = $this->getHomeSetting();
SettingRepo::update('system', 'base', ['design_setting' => $homeSetting]);
}
private function getHomeSetting(): array
{
// Return homepage layout configuration
// Data format references the design_setting value in the settings table
return [
// ... your homepage configuration data
];
}
}
# 6.2 How to Get Homepage Configuration Data
- Configure the homepage layout in the admin design editor
- Go to the database
settingstable, find the record wherename = 'design_setting' - Copy the JSON data from the
valuefield - Use a tool to convert JSON to PHP array: https://uutool.cn/json2php/
- Put the converted array into the
getHomeSetting()method
# 6.3 Import Data When Enabling
When users enable the template in the admin panel, check the "Import Demo Data" option, and the system will automatically run the Seeder to import data.
# VII. Static Asset Management
# 7.1 Static Directory Structure
plugins/Fashion/Static/
├── image/
│ ├── logo.png # Plugin icon (displayed in admin plugin list)
│ └── theme.jpg # Theme preview image (displayed on template settings page)
├── public/
│ └── build/beike/shop/fashion/
│ ├── css/ # Compiled CSS (must include)
│ └── js/ # Compiled JS (must include)
└── catalog/fashion/ # Images used by the template (banner, icon, etc.)
└── demo/
# 7.2 Accessing Assets
Access static assets in templates:
{{-- Access plugin static files --}}
<img src="{{ plugin_asset('fashion', 'image/logo.png') }}">
<img src="{{ asset('plugin/fashion/catalog/fashion/demo/banner.jpg') }}">
{{-- Access compiled CSS/JS (automatically loaded by the system) --}}
{{ mix('/build/beike/shop/fashion/css/app.css') }}
{{ mix('/build/beike/shop/fashion/js/app.js') }}
# VIII. Packaging and Publishing
# 8.1 Pre-Packaging Checklist
- [ ] All SCSS/JS have been compiled, and compiled files are in
Static/public/build/ - [ ]
logo.pngandtheme.jpghave been replaced with your own assets - [ ]
config.jsoninformation is complete and accurate - [ ]
Bootstrap.phpnamespace is correct - [ ] Template file paths are correct (
Themes/your_theme/) - [ ] Test installation, enable, and switch functions are working properly
# 8.2 Packaging
Package the plugin folder as a ZIP archive:
cd plugins
zip -r Fashion.zip Fashion/
# 8.3 Publishing
- Log in to the BeikeShop official website
- Go to User Center → Plugin Marketplace
- Upload the ZIP package to publish
- Other users can purchase and install it from the admin plugin marketplace
# IX. Frequently Asked Questions
# Q1: No styles after template installation?
Cause: The compiled CSS/JS files are not included in the plugin's Static/public/build/ directory.
Solution:
- Ensure the template compilation code in
webpack.mix.jsis uncommented - Run
npm run prodto compile - Confirm that compiled files exist under
plugins/YourTheme/Static/public/build/
# Q2: Modified SCSS but no changes on the storefront?
Cause: Not recompiled or cache not refreshed after compilation.
Solution:
- Use
npm run watchin the development phase to listen for auto-compilation - Wait a few seconds after modification for auto-compilation to complete
- Refresh the browser (may need force refresh Ctrl+Shift+R)
# Q3: Template file modifications not taking effect?
Cause: Blade template cache not cleared.
Solution:
php artisan view:clear
php artisan cache:clear
# Q4: How to override only some template files?
You don't need to copy all files. The system will first look for files under themes/your_theme/, and if they don't exist, fall back to themes/default/. So you only need to override the files you need to modify.
# Q5: What is the difference between themeFileName and themeCode?
themeFileName: Plugin folder name, PascalCase naming, e.g.,FashionthemeCode: Template unique identifier, lowercase + underscore, e.g.,fashion- The two are automatically converted via regex; usually you only need to modify
themeFileName
# X. Best Practices
- Only override needed files: Don't copy all default template files, only override the ones you need to modify
- Keep code clean: Follow the project's existing coding style
- Manage versions properly: Modify the
versioninconfig.jsonfor each release update - Test multilingual support: Ensure the template displays correctly in different languages
- Responsive design: Ensure the template displays well on mobile devices
- Performance optimization: Use WebP format for images, compress CSS/JS before publishing
- Backup data: Back up existing configuration data before enabling a new template
# Appendix: Naming Convention Quick Reference
| Item | Naming Rule | Example |
|---|---|---|
| Plugin folder | PascalCase | Fashion, MyTheme |
| config.json code | lowercase + underscore | fashion, my_theme |
| namespace | Plugin\FolderName | Plugin\Fashion |
| themeCode | lowercase + underscore | fashion |
| Resource path | lowercase + underscore | beike/shop/fashion/css/ |
| Blade file | lowercase + underscore | home.blade.php |