建立模型
本指南展示兩種為 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 - ✅ 權限已建立並分配
- ✅ 選用:已新增翻譯、媒體集合和可翻譯欄位