code16 / ozu-client
Ozu项目的配套包(https://ozu.code16.fr)
Requires
- php: 8.2.*|8.3.*
- code16/laravel-content-renderer: ^1.1.0
- illuminate/contracts: ^11.0
- intervention/image-laravel: ^1.0
- spatie/laravel-package-tools: ^1.14.0
- spatie/laravel-sluggable: ^3.6
Requires (Dev)
- laravel/pint: ^1.0
- nunomaduro/collision: ^8.0
- orchestra/testbench: ^9.0
- pestphp/pest: ^2.0
- pestphp/pest-plugin-arch: ^2.0
- pestphp/pest-plugin-laravel: ^2.0
- spatie/laravel-export: ^1.1
- spatie/laravel-ray: ^1.26
This package is auto-updated.
Last update: 2024-09-19 14:28:37 UTC
README
Ozu为开发并维护具有动态内容的静态网站提供了一个很好的解决方案,同时保持了Laravel的生产力和优秀的开发体验。
目前该项目处于私有测试阶段,但您可以通过以下链接请求访问权限: ozu.code16.fr。您还可以参考这篇博客文章了解更多关于该项目的信息。
安装
需要此包
composer require code16/ozu-client
发布配置文件
php artisan vendor:publish --tag="ozu-client-config"
使用方法
模型是Ozu集合
您想公开给Ozu的模型(意味着:您想配置内容管理工具的模型)必须遵循以下规则
首先,您的迁移必须使用Code16\OzuClient\Support\Database\MigratesOzuTable
特质,并在up()
方法中调用$this->createOzuTable('my-table');
:这将创建Ozu所需列的表,然后您可以添加自己的列。
use Code16\OzuClient\Support\Database\MigratesOzuTable; // ... return new class extends Migration { use MigratesOzuTable; public function up(): void { $this->createOzuTable('projects'); Schema::table('projects', function (Blueprint $table) { $table->string('country')->nullable(); // ... }); } };
基本的Ozu模型包含以下属性
标题
内容
slug
(自动从标题中填充)顺序
封面
(作为Media
,见下文)
其次,您的模型必须实现Code16\OzuClient\Eloquent\IsOzuModel
特质,并实现3个静态方法
configureOzuCollection
是您可以定义集合标签、图标以及一些选项的地方,如发布状态、可创建状态和可删除状态。configureOzuCollectionList
是您可以定义要在列表视图中显示的列的地方。configureOzuCollectionForm
是您可以定义要在表单视图中显示的自定义字段的地方。
以下是一个具有一个附加字段(country
)和一些基本配置的Project
模型示例
use Code16\OzuClient\Eloquent\IsOzuModel; // ... class Project extends Model { use IsOzuModel; // ... public static function configureOzuCollection(OzuCollectionConfig $config): OzuCollectionConfig { return $config ->setLabel('Projects') ->setIcon('fa-ruler-combined') ->setHasPublicationState() ->setIsCreatable() ->setIsDeletable(false); } public static function configureOzuCollectionList(OzuCollectionListConfig $config): OzuCollectionListConfig { return $config ->addColumn(OzuColumn::makeImage('cover', 1)) ->addColumn(OzuColumn::makeText('title', 5)->setLabel('Title')) ->addColumn(OzuColumn::makeText('country', 6)->setLabel('Country')) ->setIsSearchable() ->setIsReorderable(); } public static function configureOzuCollectionForm(OzuCollectionFormConfig $config): OzuCollectionFormConfig { return $config ->addCustomField( OzuField::makeText('country') ->setLabel('Country') ->setValidationRules(['required']) ); } }
注意
此配置将由Ozu用于在内容管理工具中正确显示集合。它对您的本地代码库没有影响。
处理BelongsTo
关系
一个常见的用例是在两个Ozu模型之间有一个BelongsTo
关系。有两种可能性
- 该关系不公开给Ozu,意味着您不想在CMS中处理它:在这种情况下,您可以在Laravel中像通常那样定义关系,并使用专门的外键列。
- 如果您更可能需要允许内容管理员更新此关系,那么有一个主要约束:您只能在每个模型中有一个
belongsTo
关系,该关系名为parent_id
。
以下是一个具有属于Category
模型的Project
模型的示例。首先是迁移
return new class extends Migration { use MigratesOzuTable; public function up(): void { $this->createOzuTable('projects'); Schema::table('projects', function (Blueprint $table) { $table->foreignId('parent_id')->constrained('categories')->cascadeOnDelete(); // ... }); } };
然后是Project
模型
class Project extends Model { use IsOzuModel; public function category(): BelongsTo { return $this->belongsTo(Category::class, 'parent_id'); } // ... public static function configureOzuCollectionList(OzuCollectionListConfig $config): OzuCollectionListConfig { return $config // Optionally add a filter for the Project list in the CMS ->declareBelongsToFilter(ozuModelClass: Category::class, label: 'Saison', required: true) ->addColumn(/* ... */); // ... } // ... public static function configureOzuCollectionForm(OzuCollectionFormConfig $config): OzuCollectionFormConfig { return $config // Add a BelongsTo select field in the Project form in the CMS ->declareBelongsToField(ozuModelClass: Category::class, label: 'Project Category') ->addCustomField(/* ... */); // ... } // ... }
有了这些,您可以在代码库中使用常规的$project->category
关系,而Ozu将能够在CMS中的项目表单上提供一个类别选择器。
注意
当然,如果需要,您可以在类别模型中定义此关系的相反的HasMany
。
附加的视觉元素是Media
如果您想将图像附加到模型上,请通过Code16\OzuClient\Eloquent\Media
模型使用MorphOne
或MorphMany
关系
use Code16\OzuClient\Eloquent\Media; // ... class Project extends Model { use IsOzuModel; public function visuals(): MorphMany { return $this->morphMany(Media::class, 'model') ->where('model_key', 'visuals') ->orderBy('order'); } public function ogImage(): MorphOne { return $this->morphOne(Media::class, 'model') ->where('model_key', 'ogImage'); } // ... }
您必须在关系中定义model_key
以区分您可以附加到模型上的不同类型的媒体。
您可以在视图中使用此关系来显示图片,并利用 thumbnail()
方法获取所需尺寸的图片URL。
@if(count($project->visuals)) <div class="mt-12"> <div class="grid sm:grid-cols-3 grid-cols-2 gap-4"> @foreach($project->visuals as $visual) <img class="aspect-square" src="{{ $visual->thumbnail(400, fit: true) }}" alt=""> @endforeach </div> </div> @endif
本地(开发)种子
为了简化项目开发,您可以使用 OzuSeeder
类来为您本地的数据库填充一些示例数据。
use Code16\OzuClient\Support\Database\OzuSeeder; // ... class DatabaseSeeder extends OzuSeeder { public function run(): void { // this will delete any remaining seeded Media file $this->clearMediaDirectory(); Project::factory() ->count(12) ->has(Media::factory()->image('cover')->withFile(), 'cover') ->has(Media::factory()->image('visuals')->withFile()->count(3), 'visuals') ->sequence(fn ($sequence) => [ 'order' => $sequence->index + 1, 'country' => fake()->country(), ]) ->create(); // ... } }
查看示例项目以获取示例。
您可以通过访问 Ozu 示例项目 dvlpp/ozu-demo 来了解使用 Ozu 的简单项目示例。
限制
生成静态文件意味着我们不能使用请求特定的功能,如查询参数、会话、POST 表单等。但 Ozu 提供了解决方案,以尽可能让代码接近经典的 Laravel 应用。
查询字符串
考虑这个简单的用例:我们需要显示一个可排序的项目列表。在一个经典的 Laravel 应用中,我们可能会有这样的路由
Route::get('/projects')
在控制器中,我们会检查排序项目的查询参数,例如 /projects?sort=asc
。
在一个 Ozu 项目中,像任何静态网站一样,我们无法在控制器中检查 sort
,因为我们正在生成静态 HTML 文件;您可以
- 将查询参数放在路径参数中(例如:
/projects/list/{sort}
):这将创建两个 HTML 文件projects/list/desc.html
和projects/list/asc.html
。 - 或者在前端代码中处理查询字符串(例如使用 Alpine)。
分页
出于同样的原因,?page=1
不能与生成的静态 HTML 一起使用;相反,您需要将页面作为路径段。
Route::get('/projects/index/{page}')
您仍然可以使用 {{ $projects->links() }}
或 route('projects.index', ['page' => 2])
:Ozu 覆盖了 Laravel 默认的 Paginator 来处理页面段。
会话
根据定义,会话对于静态生成的网站是不可用的。如果您确实需要存储会话数据,您可以使用 cookie 或 JavaScript 中的 localStorage。
表单
对于表单,在当前的 Ozu 状态下,您需要外部提供商来处理提交(有很多解决方案,例如 FieldGoal)。
部署到生产环境
一旦您的项目准备就绪,您就可以将其部署到 Ozu。
在 Ozu 中配置项目
首先在 config/ozu-client
配置文件中声明您的 Ozu 集合。
php artisan vendor:publish --tag="ozu-client-config"
// config/ozu-client.php return [ // ... 'collections' => [ App\Models\Project::class, // ... ], ];
然后您需要在 .env
文件中配置您的凭据。
OZU_API_KEY=[your-api-key] OZU_WEBSITE_KEY=[your-website-key]
然后启动 ozu:configure-cms
命令。
php artisan ozu:configure-cms
此命令将为您的每个声明的模型在 Ozu 中创建一个新的集合,并将配置列表和表单根据您在模型中定义的方法进行配置。每次您添加或更新 Ozu 模型时,都必须重复此命令。
在此阶段,您应该能够在 https://ozu.code16.fr/sharp 地址看到您定制的 CMS。在这里,您可以管理集合的内容。
注意
Sharp 是 Ozu 使用的底层内容管理系统框架:尽管您实际上不需要了解它就可以使用 Ozu,但如果您好奇,可以 查看其网站。
注意
目前还没有方法来填充生产数据,但它位于路线图中。
部署您的项目
一旦您已在 CMS 中输入了内容,您就可以按照以下步骤将项目作为静态网站进行部署
- 安装 Ozu Github 应用 + 授予您的存储库只读访问权限
- 在 Ozu 仪表板中配置 github 仓库 + 分支(配置菜单)
- 在 Netlify (https://app.netlify.com/user/applications/personal) 中创建一个新的个人访问令牌,将过期时间设置为“无过期”,并在 Ozu 仪表板中报告
- 在 Ozu 仪表板中创建 Netlify 网站
- (如果需要,将您最新的代码推送到您的存储库,并在 Ozu CMS 中调整您的内容)
- 点击“部署”!