建立模型
本指南展示两种为 WNCMS 建立新模型的方式:
- 使用 Laravel 内建的 Artisan 产生器
- 使用 WNCMS 辅助指令
wncms:create-model(建议用于后台 CRUD)
结果将会是一个扩展 WNCMS BaseModel 的本地模型,以及管理控制器、迁移、视图、权限和路由。
开始之前
- 确保 WNCMS 已安装并自动载入。
- 确认
routes/custom_backend.php已被routes/web.php引入(WNCMS 预设会执行此操作)。 - 决定模型的单数和复数名称。本文件范例:
Article/articles。
选项 A — Laravel 内建产生器
1) 产生档案
php artisan make:model Article -m
php artisan make:controller Backend/ArticleController --resource --model=Article2) 更新模型以扩展 BaseModel
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Wncms\Models\BaseModel;
use Wncms\Translatable\Traits\HasTranslations;
class Article extends BaseModel implements HasMedia
{
use HasFactory;
use InteractsWithMedia;
use HasTranslations;
/**
* 模型键值(v6.x.x 必要)
*/
public static $modelKey = 'article';
protected $guarded = [];
/**
* 可翻译栏位
*/
protected $translatable = ['title', 'excerpt', 'content'];
/**
* 日期转型
*/
protected $casts = [
'published_at' => 'datetime',
];
/**
* 标签中继资料(取代旧的 TAG_TYPES 常数)
*/
protected static array $tagMetas = [
[
'key' => 'article_category',
'short' => 'category',
'route' => 'frontend.articles.tag',
],
[
'key' => 'article_tag',
'short' => 'tag',
'route' => 'frontend.articles.tag',
],
];
/**
* 后台 UI 的状态选项
*/
public const STATUSES = ['published', 'drafted'];
/**
* 注册媒体集合
*/
public function registerMediaCollections(): void
{
$this->addMediaCollection('article_thumbnail')->singleFile();
}
}3) 让后台控制器扩展 WNCMS BackendController
<?php
namespace App\Http\Controllers\Backend;
use Wncms\Http\Controllers\Backend\BackendController;
class ArticleController extends BackendController
{
// 基本 CRUD 通常不需要覆写任何内容。
// 您可以自订策略、验证、栏位等。
}4) 建立迁移
编辑产生的迁移(范例栏位):
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('website_id')->nullable()->index(); // 多站点支援
$table->string('title');
$table->string('slug')->unique();
$table->text('excerpt')->nullable();
$table->longText('content')->nullable();
$table->string('status')->default('drafted');
$table->timestamp('published_at')->nullable();
$table->timestamps();
});执行迁移:
php artisan migrate5) 注册路由(如果未使用下面的 WNCMS 指令)
附加到 routes/custom_backend.php:
<?php
use App\Http\Controllers\Backend\ArticleController;
Route::get('articles', [ArticleController::class, 'index'])->middleware('can:article_index')->name('articles.index');
Route::get('articles/create', [ArticleController::class, 'create'])->middleware('can:article_create')->name('articles.create');
Route::get('articles/create/{id}', [ArticleController::class, 'create'])->middleware('can:article_clone')->name('articles.clone');
Route::get('articles/{id}/edit', [ArticleController::class, 'edit'])->middleware('can:article_edit')->name('articles.edit');
Route::post('articles/store', [ArticleController::class, 'store'])->middleware('can:article_create')->name('articles.store');
Route::patch('articles/{id}', [ArticleController::class, 'update'])->middleware('can:article_edit')->name('articles.update');
Route::delete('articles/{id}', [ArticleController::class, 'destroy'])->middleware('can:article_delete')->name('articles.destroy');
Route::post('articles/bulk_delete', [ArticleController::class, 'bulk_delete'])->middleware('can:article_bulk_delete')->name('articles.bulk_delete');6) 建立后台视图
WNCMS 预期视图位于 resources/views/backend/{plural_snake}/:
resources/views/backend/articles/
├─ index.blade.php
├─ create.blade.php
└─ edit.blade.php使用复数蛇形命名法命名路由和视图(例如 backend.articles.index)以符合 WNCMS 惯例。
7) 新增权限和选单(选用但建议)
- 使用您偏好的方法或小型填充器建立权限,如
article_index、article_create等。 - 新增指向
route('articles.index')的后台选单项目。
8) 模型 ROUTES 支持 2 种格式
WNCMS 支持简单列表与详细定义两种写法,用于后台侧边栏/选单权限判断。
简单格式(权限自动推导为 {model}_{suffix}):
public const ROUTES = [
'index',
'summary',
];详细格式(可为单一路由覆写权限):
public const ROUTES = [
['name' => 'index'],
['name' => 'summary', 'permission' => 'article_index'],
];name 也可写完整路由名(例如 articles.index);若仅写后缀,WNCMS 会按模型路由前缀自动补全。
选项 B — WNCMS 快速指令(建议)
使用一体化的 WNCMS 指令来产生模型、迁移、控制器、视图、权限和路由。它还会将产生的控制器内的蛇形/驼峰命名标准化。
php artisan wncms:create-model Article它会执行以下操作:
make:model Article- 生成的模型现已扩展
Wncms\Models\BaseModel,并包含modelKey兜底逻辑(留空时会根据类名自动推导)
- 生成的模型现已扩展
make:migration create_articles_tablemake:controller Backend/ArticleController --resource --model=Article- 将视图名称(
backend.articles.*)、路由名称(articles.*)、快取标签和模型字词辅助函式重写为蛇形命名法
- 将视图名称(
wncms:create-model-view article建立index/create/edit视图wncms:create-model-permission article填充基本权限选择性地将完整路由区块附加到
routes/custom_backend.php并为控制器预先新增use语句
在附加路由之前,您会看到确认提示。
执行迁移:
php artisan migrate建立架构后
自定义模型(v6.x.x)
使用 wncms:create-model 之后,生成的模型已默认使用 BaseModel,并带有安全的 modelKey 兜底逻辑。请按功能需求继续调整:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Wncms\Models\BaseModel;
use Wncms\Translatable\Traits\HasTranslations;
class Article extends BaseModel implements HasMedia
{
use HasFactory;
use InteractsWithMedia;
use HasTranslations;
// 必要:模型键值
public static $modelKey = 'article';
protected $guarded = [];
// 选用:可翻译栏位
protected $translatable = ['title', 'excerpt', 'content'];
// 选用:日期转型
protected $casts = [
'published_at' => 'datetime',
];
// 选用:标签中继资料(v6.x.x 风格)
protected static array $tagMetas = [
[
'key' => 'article_category',
'short' => 'category',
'route' => 'frontend.articles.tag',
],
];
// 选用:状态常数
public const STATUSES = ['published', 'drafted'];
// 选用:媒体集合
public function registerMediaCollections(): void
{
$this->addMediaCollection('article_thumbnail')->singleFile();
}
}翻译键值
如果您使用 BaseModel::getModelName() 或 wncms()->getModelWord('article'),请新增翻译:
resources/lang/en/wncms.php
'word' => [
'article' => 'Article',
'articles' => 'Articles',
],或者如果您稍后将其移至套件中,请使用套件范围的键值。
标签类型(选用)
如果您的模型需要标签,请在 $tagMetas 中宣告:
protected static array $tagMetas = [
[
'key' => 'article_category',
'short' => 'category',
'route' => 'frontend.articles.tag',
],
[
'key' => 'article_tag',
'short' => 'tag',
'route' => 'frontend.articles.tag',
],
];WNCMS 会在模型启动时自动注册它们。
媒体与翻译(选用)
若要使用媒体库或翻译:
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Wncms\Translatable\Traits\HasTranslations;
class Article extends BaseModel implements HasMedia
{
use InteractsWithMedia;
use HasTranslations;
protected $translatable = ['title', 'excerpt', 'content'];
public function registerMediaCollections(): void
{
$this->addMediaCollection('article_thumbnail')->singleFile();
}
}常用提示
- 保持控制器名称为复数,并放置在
App\Http\Controllers\Backend\下。 - 路由和视图名称使用复数蛇形命名法(例如
articles.index)以符合 WNCMS 辅助函式和存根。 - 如果您的站点使用多站点,请在迁移中包含
website_id。 - 新增选单或权限时,如果它们被快取,请清除快取。
- 遵循 WNCMS 的命名:诸如
status、时间戳记和 slugs 等栏位使整合更顺畅。
快速检查清单
- ✅ 模型扩展
Wncms\Models\BaseModel - ✅ 模型定义
public static $modelKey - ✅ 模型使用
$tagMetas阵列(而非旧的TAG_TYPES) - ✅ 后台控制器扩展
Wncms\Http\Controllers\Backend\BackendController - ✅ 迁移已建立并执行,包含
website_id栏位 - ✅ 视图位于
resources/views/backend/{plural}/下 - ✅ 路由注册到
routes/custom_backend.php - ✅ 权限已建立并分配
- ✅ 选用:已新增翻译、媒体集合和可翻译栏位