使用作曲家
Introduction
使用Composer 作为使用标准一键式更新管理器的替代包管理器,建议更高级的用户和开发人员使用。
Composer 是 PHP 生态中包管理的事实标准,可以处理 Winter CMS 插件和主题,以及第三方 Laravel 包和供应商库的下载、安装和管理。
从基本安装转换
为了将 Composer 与使用向导或简单 CLI 安装过程安装的 Winter CMS 实例一起使用,只需复制最新的tests/
目录 和composer.json
文件来自GitHub 进入您的 Winter 实例,然后运行composer install
在项目的根目录中。
NOTE: 如果您对目录中的文件进行了修改
modules
目录,如果安装了对这些模块的更新,这些将被 Composer 覆盖。建议您不要 直接对模块进行修改。
开发科
如果您计划通过 GitHub 向 Winter CMS 项目提交拉取请求,或者正在积极开发基于 Winter CMS 的项目并希望与绝对最新版本保持同步,我们建议切换您的作曲家依赖项以指向develop
进行所有最新改进和错误修复的分支。这样做将使您能够在发生时立即发现可能引入的任何潜在问题(尽管它们很少见),并在您仍在积极从事项目时解决它们,而不是在几个月后才发现它们,如果他们最终将其投入生产。
"winter/storm": "dev-develop as 1.2.999",
"winter/wn-system-module": "dev-develop as 1.2.999",
"winter/wn-backend-module": "dev-develop as 1.2.999",
"winter/wn-cms-module": "dev-develop as 1.2.999",
"laravel/framework": "~9.0",
NOTE: 不要将更改提交给
composer.json
,因为此文件由 Winter CMS 维护人员处理。
部署最佳实践
将以下最佳实践与 Composer 和 Winter CMS 结合使用将使 Winter CMS 安装的部署更加顺畅:
- 储存
composer.lock
源代码管理中的文件。默认情况下,Git 会忽略此文件.gitignore
Winter CMS 包含的文件,但应与您的应用程序一起部署以加快安装和更新过程。 - 添加一个
.gitignore
里面的文件modules
文件夹忽略此文件夹中的所有更改,因为模块将由 Composer 安装和更新。 - 添加一个
.gitignore
里面的文件plugins
如果您通过 Composer 安装插件,则忽略此文件夹中的所有更改。您可以选择允许仅用于该特定项目的自定义插件。 - 使用
composer install --no-dev
在您的生产实例上专门排除任何不会在生产中使用的“开发”包和库。
通过 Composer 安装 Winter
通过 Composer 安装 Winter 很容易。您可以使用create-project
通过 Composer 命令快速设置新的 Winter 安装。
composer create-project wintercms/winter <your installation directory>
# Example:
# composer create-project wintercms/winter mywinter
如果你想安装特定版本的 Winter,你也可以指定版本。
composer create-project wintercms/winter <your installation directory> "<version>"
# Example:
# composer create-project wintercms/winter mywinter "1.0.474"
使用 Composer 安装插件或主题
使用 Composer 在 Winter CMS 中安装插件和主题可以在一定程度上控制所使用插件的版本,从而可以轻松地将 Winter CMS 同步和部署到多个环境。
您可以通过 Composer 安装主题或插件发布插件或主题 在Packagist,Composer 包的存储库。插件或主题发布后,您可以通过在项目的根目录中运行以下命令将其包含在任何启用了 Composer 的 Winter CMS 项目中:
composer require <your package name>
# Example:
# composer require winter/wn-pages-plugin
如果您希望指定要包含的插件或主题的特定版本,您也可以指定版本:
composer require <your package name> "<version constraint>"
# Example:
# composer require winter/wn-pages-plugin "^2.0.0"
您还可以选择指定一个插件或主题仅包含在“开发”环境中:
composer require --dev <your package name> "<version constraint>"
# Example:
# composer require --dev winter/wn-builder-plugin "^2.0.0"
发布插件或主题
将插件或主题发布到市场时,您可能还希望通过 Composer 提供它们。一个例子composer.json
插件的文件包含在下面:
{
"name": "winter/wn-demo-plugin",
"type": "winter-plugin",
"description": "Demo Winter CMS plugin",
"keywords": ["winter", "cms", "demo", "plugin"],
"license": "MIT",
"authors": [
{
"name": "Winter CMS Maintainers",
"url": "https://wintercms.com",
"role": "Maintainer"
}
],
"require": {
"php": ">=7.2",
"composer/installers": "~1.0"
}
}
一定要开始你的包裹name
和wn- 并结束它-plugin 或者-theme 分别 - 这将帮助其他人找到您的包裹并且符合质量方针.
这type
字段是确保您的插件或主题在安装后到达正确位置的关键定义。使用以下类型:
Product | Type |
---|---|
Plugin | winter-plugin |
Theme | winter-theme |
Module | winter-module |
Reminder:请务必在您的
composer.json
像使用$require
在中发现的财产插件注册文件
包装说明
有许多不同的移动部件组合在一起使 Winter CMS 平台正常工作。在这里,我们将描述您可能会遇到的各种包:
-
Modules 是 Winter 附带的核心包,您可以将它们视为提供核心功能的“内部插件”。模块使用包类型
winter-module
并且位于/modules
目录。它们通过配置手动加载,并且至少有一个模块必须存在于cms.loadModules
系统运行的配置项。 -
Plugins 扩展了 Winter 的核心功能并且是类型的包
winter-plugin
.它们位于/plugins
目录。这System
模块负责加载在文件系统中找到时自动发生的插件,除非它们被明确禁用。 -
Themes 包含用于管理网站前端结构和使用包类型的静态文件内容
winter-theme
.它们位于/themes
目录。这Cms
模块负责管理主题并确定当前处于活动状态的主题。 -
Vendor 包通过 Composer 包含在项目的
/vendor
目录或有时可以在特定于插件的目录中找到/vendor
目录。项目供应商目录优先于系统中出现的插件供应商目录。
市场构建
当您将插件或主题发布到市场时,服务器将方便地拉入您的 composer 文件中定义的所有包。这使得该产品可供其他人使用,即使他们不使用 Composer。它是这样工作的:
-
作为插件或主题开发人员,您可以在中定义外部依赖项和包
composer.json
,包括其他插件或主题。 -
服务器将尝试删除核心中固有的任何核心依赖项,包括 Laravel、Winter 及其相关包。
-
服务器将运行
composer install
在您的插件或主题目录中,将依赖项拉入vendor
目录,该包的本地。 -
文件
composer.json
和composer.lock
然后删除以防止包文件重复和潜在的依赖性加倍。 -
最终结果被打包并准备好供 Winter CMS 平台使用一键更新使用。
最好不要包括vendor
将插件或主题发布到市场时的目录,服务器将为您处理。
如果您正在使用插件进行开发,则可以运行composer update
从根目录。一个特殊的包叫wikimedia/composer-merge-plugin
将扫描插件目录并将依赖项合并到主作曲家文件中。
使用 Laravel 包
在 Winter CMS 插件中包含 Laravel 包时,需要注意一些事项。
配置文件
Laravel 包通常会提供配置文件,它们通常会附带将这些配置文件发布到项目配置文件夹的说明,通常是这样的php artisan vendor:publish --tag=config
.
然而,这可能会给 Winter 的面向插件的设计带来问题,因为现在核心中会有随机配置文件/config
目录。为了解决这个问题,建议您改为通过您的插件代理包含包的配置。
您可以将此代码放在您的插件注册文件中并从boot()
方法。
public function bootPackages()
{
// Get the namespace code of the current plugin
$pluginNamespace = str_replace('\\', '.', strtolower(__NAMESPACE__));
// Locate the packages to boot
$packages = \Config::get($pluginNamespace . '::packages');
// Boot each package
foreach ($packages as $name => $options) {
// Apply the configuration for the package
if (
!empty($options['config']) &&
!empty($options['config_namespace'])
) {
Config::set($options['config_namespace'], $options['config']);
}
}
}
现在您可以像使用常规插件配置值一样自由地提供包配置值。
return [
// Laravel Package Configuration
'packages' => [
'packagevendor/packagename' => [
// The accessor for the config item, for example,
// to access via Config::get('purifier.' . $key)
'config_namespace' => 'purifier',
// The configuration file for the package itself.
// Copy this from the package configuration.
'config' => [
'encoding' => 'UTF-8',
'finalize' => true,
'cachePath' => storage_path('app/purifier'),
'cacheFileMode' => 0755,
],
],
],
];
现在包配置已经包含在 Winter CMS 中,可以使用标准配置方式.
别名和服务提供商
默认情况下,Winter CMS 禁止加载已发现的包Laravel 的包发现服务, 以便在插件本身被禁用时允许插件使用的包被禁用。请注意,包中定义app.providers
即使发现被禁用,仍将被加载。
NOTE: 可以设置
app.loadDiscoveredPackages
到true
在项目配置中启用这些包的自动加载。这将导致包被加载,即使使用它们的插件被禁用。这是不建议。
为了手动注册插件使用的外部 Laravel 包提供的服务提供者和别名,你应该使用App
门面和AliasLoader
分别实例:
use App;
use Illuminate\Foundation\AliasLoader;
use System\Classes\Plugin as PluginBase;
class Plugin extends PluginBase
{
public function register()
{
// Instantiate the AliasLoader
$aliasLoader = AliasLoader::getInstance();
// Register the aliases provided by the packages used by your plugin
$aliasLoader->alias('Purifier', \Mews\Purifier\Facades\Purifier::class);
// Register the service providers provided by the packages used by your plugin
App::register(\Mews\Purifier\PurifierServiceProvider::class);
}
}
迁移和模型
与数据库交互的 Laravel 包通常会包含它们自己的数据库迁移和 Eloquent 模型。理想情况下,您应该将这些迁移和模型复制到您的插件目录,然后重新设置提供的模型类的基础以扩展基础\Winter\Storm\Database\Model
类而不是基础的 Laravel Eloquent 模型类,以利用 Winter 中发现的扩展技术特性。
您还应该努力重命名这些表,以在它们前面加上您的插件的作者代码和名称。例如,一个名为posts
应该重命名为winter_blog_posts
.
合并插件 Composer 依赖项
默认情况下,Winter CMS 包括Composer 合并插件 及其 Composer 依赖项。这是一个特殊的 Composer 插件,允许开发人员包含一个composer.json
他们正在积极开发或不想发布的插件中的文件,并且在他们的插件中指定了任何依赖项composer.json
运行时也包含文件composer install
或者composer update
在他们的项目上。
最初,这被设置为包括任何插件的composer.json
文件,但这很容易发生冲突和错误,因此从 Winter 1.2 开始,您必须明确提供一个列表composer.json
您希望与主文件合并的文件composer.json
文件。
您可以编辑include
您的以下代码块的一部分main composer.json
文件:
"extra": {
"merge-plugin": {
"include": [
"plugins/myauthor/*/composer.json"
],
"recurse": true,
"replace": false,
"merge-dev": false
}
},
例如,如果你想包含一个插件的composer.json
,您可以指定该插件的直接路径composer.json
:
"extra": {
"merge-plugin": {
"include": [
"plugins/acme/blog/composer.json"
],
"recurse": true,
"replace": false,
"merge-dev": false
}
},
或者如果你有多个插件,你可以指定多个路径:
"extra": {
"merge-plugin": {
"include": [
"plugins/acme/blog/composer.json",
"plugins/acme/forum/composer.json",
"plugins/acme/events/composer.json"
],
"recurse": true,
"replace": false,
"merge-dev": false
}
},
如果您希望包含整个自定义插件目录,您可以指定一个通配符:
"extra": {
"merge-plugin": {
"include": [
"plugins/acme/*/composer.json"
],
"recurse": true,
"replace": false,
"merge-dev": false
}
},
为防止冲突,您不得在任何一个项目中包含作为项目依赖项引入的任何插件require
或者require-dev
你的项目的块composer.json
文件。例如,如果您以前使用过composer require acme/blog
将该插件添加到您的require
块,你不应该将它包含在 Merge 插件的include
块,因为这实际上包含了插件两次,并可能导致 Composer 将其视为冲突。