kanopi / wordpress-core-composer-scaffold
灵活的 Composer 项目脚手架构建器。
Requires
- php: >=7.3.0
- composer-plugin-api: ^1 || ^2
Requires (Dev)
- composer/composer: ^1.8@stable
README
本项目提供 composer 插件,用于将 wordpress/core
项目的脚手架文件(如 index.php
、update.php
等)放置到 Web 根目录下的指定位置。此插件只能为单个文件生成脚手架。
脚手架文件的目的在于允许 WordPress 网站通过 Composer 完全管理,同时仍然可以将单个资源文件放置在任意位置。这样做是为了使配置良好的 composer 模板能够生成与 WordPress 8.7.x 及更早版本的 tarball 分发文件布局完全一致的文件布局。其他文件布局也是可能的;例如,一个与当前 wordpress-composer/wordpress-project 模板非常相似的项目布局也将提供。当使用这些项目之一时,用户应在解压下载的存档后立即使用 composer require
和 composer update
在 WordPress 网站上操作。
请注意,WordPress 网站的所有依赖关系只有在其顶级 composer.json 文件中明确授予了该权限时,才能生成脚手架文件。请参阅下面的 允许的包。
使用方法
WordPress Composer Scaffold 通过在项目中的 composer.json 文件的 extra
部分提供配置设置,并通过在项目中的 composer.json 文件中引入 wordpress/core-composer-scaffold
来使用。还会咨询项目依赖项的 composer.json 文件中的额外配置,以生成项目需要的文件。还可以在脚手架文件的开始或结尾处添加附加信息,正如通常对 .htaccess
和 robots.txt
文件所做的那样。有关更多信息,请参阅 修改脚手架文件。
通常,脚手架操作在需要时自动运行,例如在 composer install
之后,因此一旦在项目的 composer.json 文件中设置了配置,通常不需要进行任何不同的操作来为项目生成脚手架。要直接生成文件,请运行
composer wordpress:scaffold
允许的包
脚手架文件存储在主项目 composer.json 文件中需要的项目内部。脚手架操作在 composer install
之后发生,涉及将所需的资产复制或符号链接到目标位置。为了防止任意依赖关系通过脚手架机制复制文件,只有那些由顶级项目明确允许的项目才会用于生成文件。
示例:允许从项目 upstream/project
中生成脚手架
"name": "my/project",
...
"extra": {
"wordpress-scaffold": {
"allowed-packages": [
"upstream/project"
],
...
}
}
允许一个包生成文件也允许它将其生成脚手架的权限委派给任何它自己需要的项目。这允许包按照其认为合适的方式组织其脚手架资产。例如,如果 upstream/project
在子项目 upstream/assets
中存储其资产,则 upstream/assets
会隐式允许生成文件。
一个项目可以从多个项目中获取脚手架文件。例如,一个使用分发版的 WordPress 项目,在特定的网络托管服务提供商上安装,可能从以下内容获取其脚手架文件:
- WordPress 核心
- 其分发
- 托管提供商提供的项目
- 项目本身
每个由顶级项目允许构建的项目将依次使用,后来在 allowed-packages
列表中声明的项目将优先于之前命名的项目。 wordpress/core
是默认允许的,并将位于列表的顶部。顶级 composer.json 本身也默认允许构建文件,其构建文件具有最高优先级。
定义项目位置
顶级项目必须定义网站根目录的位置。它通过以下所示的 locations
映射来实现。
"name": "my/project",
...
"extra": {
"wordpress-scaffold": {
"locations": {
"web-root": "./docroot"
},
...
}
}
这使得配置具有不同文件布局的项目成为可能;例如,可以使用 wordpress/wordpress
文件布局来设置项目。
如果未明确定义网站根目录,则默认为 ./
。
修改构建文件
有时,一个项目可能希望使用依赖项提供的构建文件,但以某种方式修改它。支持两种修改形式:追加和修补。
以下示例显示了一个项目,将额外的条目追加到由 wordpress/core
提供的 robots.txt
文件的末尾。
"name": "my/project",
...
"extra": {
"wordpress-scaffold": {
"file-mapping": {
"[web-root]/robots.txt": {
"append": "assets/my-robots-additions.txt",
}
}
}
}
也可以通过包含一个提供要追加到构建文件的相对路径的 "prepend" 条目来在追加之前或之后预先追加到构建文件。
以下示例演示了使用 post-wordpress-scaffold-cmd
钩子通过修补来修补 .htaccess
文件。
"name": "my/project",
...
"scripts": {
"post-wordpress-scaffold-cmd": [
"cd docroot && patch -p1 <../patches/htaccess-ssl.patch"
]
}
定义构建文件
构建资产的放置受提供它们的项目的控制,但位置始终相对于由根项目定义的某些目录——通常是网站根目录。例如,以下片段中显示的构建文件 robots.txt
从其源位置 assets/robots.txt
复制到网站根目录。
{
"name": "wordpress/assets",
...
"extra": {
"wordpress-scaffold": {
"file-mapping": {
"[web-root]/robots.txt": "assets/robots.txt",
...
}
}
}
}
排除构建文件
有时,一个项目可能希望完全替换依赖项提供的构建文件,并接收不再为其更新的任何内容。这可以通过将构建文件的排除值设置为 false
来完成。
"name": "my/project",
...
"extra": {
"wordpress-scaffold": {
"file-mapping": {
"[web-root]/robots.txt": false
}
}
}
如果可能,请使用如上所述的 修改构建文件 中的 append
和 prepend
指令。排除文件意味着您的项目将不会接收到对本地修改的文件的任何错误修复或其他更新。
覆盖
默认情况下,构建文件会覆盖目标位置上的任何内容。有时,一个项目可能希望提供一个文件,该文件在后续更新中不会更改,并为其提供初始内容。这可以通过将 overwrite
标志设置为 false
来完成,如下面的示例所示。
{
"name": "service-provider/d8-scaffold-files",
"extra": {
"wordpress-scaffold": {
"file-mapping": {
"[web-root]/sites/default/settings.php": {
"mode": "replace",
"path": "assets/sites/default/settings.php",
"overwrite": false
}
}
}
}
}
请注意,overwrite
指令旨在由启动包、服务提供商等使用。单独的 WordPress 网站应通过将其值设置为 false 来排除文件。
自动加载文件
构建工具在构建操作过程中自动在 WordPress 根目录中创建所需的 autoload.php
文件。此文件不应以任何方式修改或自定义。如果将其提交到存储库,则构建工具将停止管理它。如果由于任何原因更改了 vendor
目录的位置,并且已将 autoload.php
文件提交到存储库,则手动删除它,然后运行 composer install
以更新它。
规范
以下是对 composer.json
文件 "extra" 部分 "wordpress-scaffold" 部分的配置指令的参考部分。
allowed-packages
allowed-packages
配置设置包含一个有序列表的包名称,这些包名称将在构建阶段使用。
"allowed-packages": [
"example/assets",
],
file-mapping
配置设置file-mapping
包含一个从文件的目标路径到脚本的映射,以及一组控制文件如何构建的属性。
可用的属性如下
- mode:可以是“replace”、“append”或“skip”中的一个。
- path:覆盖目标文件的源文件的路径。
- prepend:追加到目标文件的前面的源文件的路径,它必须始终是其他项目提供的脚本文件。
- append:与
prepend
类似,但追加内容而不是追加。 - overwrite:如果
false
,则在目标文件已存在的情况下,防止执行replace
操作。
模式可能可以从其他属性中推断。如果没有指定模式,则将提供以下默认值
- replace:如果存在
path
属性,或者条目的值是字符串而不是属性集,则选择。 - append:如果存在
prepend
或append
属性,则选择。 - skip:如果条目的值是布尔值
false
,则选择。
示例
"file-mapping": {
"[web-root]/sites/default/default.settings.php": {
"mode": "replace",
"path": "assets/sites/default/default.settings.php",
"overwrite": true
},
"[web-root]/sites/default/settings.php": {
"mode": "replace",
"path": "assets/sites/default/settings.php",
"overwrite": false
},
"[web-root]/robots.txt": {
"mode": "append",
"prepend": "assets/robots-prequel.txt",
"append": "assets/robots-append.txt"
},
"[web-root]/.htaccess": {
"mode": "skip",
}
}
上述示例的简短形式如下
"file-mapping": {
"[web-root]/sites/default/default.settings.php": "assets/sites/default/default.settings.php",
"[web-root]/sites/default/settings.php": {
"path": "assets/sites/default/settings.php",
"overwrite": false
},
"[web-root]/robots.txt": {
"prepend": "assets/robots-prequel.txt",
"append": "assets/robots-append.txt"
},
"[web-root]/.htaccess": false
}
请注意,没有独立的“prepend”模式;“append”模式用于同时追加和前置到脚本文件。这样做的原因是脚本文件条目在文件映射部分通过其目标路径标识,并且不可能存在多个具有相同键的条目。如果“prepend”是一个独立的模式,那么将无法同时前置和追加到同一个文件。
默认情况下,追加操作只能应用于之前评估的项目构建的文件。但是,如果在append
操作中添加了force-append
属性,那么只有当追加文本尚未出现在文件中时,才会将追加应用到非脚本文件。在此模式下,还可能提供默认内容,以防目标文件完全缺失。
以下示例演示了构建settings-custom.php
文件,并将其从现有的settings.php
文件中包含进来。
"file-mapping": {
"[web-root]/sites/default/settings-custom.php": "assets/settings-custom.php",
"[web-root]/sites/default/settings.php": {
"append": "assets/include-settings-custom.txt",
"force-append": true,
"default": "assets/initial-default-settings.txt"
}
}
请注意,上述示例如果与构建settings.php
文件的项目一起使用,仍然有效。
gitignore
gitignore
配置设置控制是否在此构建操作写入文件时管理.gitignore
文件。
- true:
.gitignore
文件将在构建脚本文件时更新。 - false:
.gitignore
文件永远不会被修改。 - 未设置:
.gitignore
文件将在目标目录是git仓库的本地工作副本,并且在该仓库中忽略vendor
目录的情况下更新。
locations
locations
配置设置包含一个用于放置脚本文件的命名位置列表。必需的位置是web-root
。如果需要,也可以定义其他位置。
"locations": {
"web-root": "./docroot"
},
symlink
symlink
属性会导致replace
操作创建到源文件的符号链接而不是复制它。这在进行核心开发时很有用,因为符号链接文件本身不应被编辑。请注意,append
操作会覆盖symlink
选项,以防止原始脚本资产被更改。
"symlink": true,
管理脚本文件
脚本文件应与处理vendor
目录的方式相同。如果您需要提交vendor
(例如,为了部署您的网站),则也应提交您的脚本文件。除非必要,否则不应提交vendor
目录或脚本文件。
如果一个依赖提供了带有 overwrite
设置为 false
的脚手架文件,该文件应提交到您的仓库。
默认情况下,当编写脚手架文件时,如果需要,.gitignore
文件将被自动更新。请参阅上方规格部分中的 gitignore
设置。
示例
以下是一些完整的示例。
依赖于使用 composer-scaffold 的包的项目 composer.json 示例
{
"name": "my/project",
"require": {
"wordpress/core-composer-scaffold": "*",
"composer/installers": "^1.9",
"cweagans/composer-patches": "^1.6.5",
"wordpress/core": "^8.8.x-dev",
"service-provider/d8-scaffold-files": "^1"
},
"config": {
"optimize-autoloader": true,
"sort-packages": true
},
"extra": {
"wordpress-scaffold": {
"locations": {
"web-root": "./docroot"
},
"symlink": true,
"file-mapping": {
"[web-root]/.htaccess": false,
"[web-root]/robots.txt": "assets/robots-default.txt"
}
}
}
}
将资源放在不同项目的 wordpress/core 的 composer.json 示例
{
"name": "wordpress/core",
"extra": {
"wordpress-scaffold": {
"allowed-packages": [
"wordpress/assets",
]
}
}
}
位于 wordpress/assets 的 composer-scaffold 文件 composer.json 示例
{
"name": "wordpress/assets",
"extra": {
"wordpress-scaffold": {
"file-mapping": {
"[web-root]/.csslintrc": "assets/.csslintrc",
"[web-root]/.editorconfig": "assets/.editorconfig",
"[web-root]/.eslintignore": "assets/.eslintignore",
"[web-root]/.eslintrc.json": "assets/.eslintrc.json",
"[web-root]/.gitattributes": "assets/.gitattributes",
"[web-root]/.ht.router.php": "assets/.ht.router.php",
"[web-root]/.htaccess": "assets/.htaccess",
"[web-root]/sites/default/default.services.yml": "assets/default.services.yml",
"[web-root]/sites/default/default.settings.php": "assets/default.settings.php",
"[web-root]/sites/example.settings.local.php": "assets/example.settings.local.php",
"[web-root]/sites/example.sites.php": "assets/example.sites.php",
"[web-root]/index.php": "assets/index.php",
"[web-root]/robots.txt": "assets/robots.txt",
"[web-root]/update.php": "assets/update.php",
"[web-root]/web.config": "assets/web.config"
}
}
}
}
实现 composer-scaffold 的库的 composer.json 示例
{
"name": "service-provider/d8-scaffold-files",
"extra": {
"wordpress-scaffold": {
"file-mapping": {
"[web-root]/sites/default/settings.php": "assets/sites/default/settings.php"
}
}
}
}
追加到 robots.txt
{
"name": "service-provider/d8-scaffold-files",
"extra": {
"wordpress-scaffold": {
"file-mapping": {
"[web-root]/robots.txt": {
"append": "assets/my-robots-additions.txt",
}
}
}
}
}
文件复制后修补文件
"post-wordpress-scaffold-cmd": [
"cd docroot && patch -p1 <../patches/htaccess-ssl.patch"
]
相关插件
wordpress-composer/wordpress-scaffold
WordPress Composer Scaffold 的早期版本(请参阅社区项目,wordpress-composer/wordpress-scaffold)直接从其分发服务器(例如 https://git.wordpresscode.org
)下载每个脚手架文件到目标目录。这是必要的,因为当时没有可用的脚手架文件的子树分割。从已由 Composer 下载的项目中复制脚手架资产更为有效,因为下载和展开存档文件比单独下载每个脚手架文件更高效。
composer/installers
与该插件类似,composer/installers 插件允许将依赖项安装到除 vendor
目录之外的位置。然而,Composer 和 composer/installers
插件有一个限制,即一个项目不能被移动到另一个项目内部。因此,如果您使用 composer/installers
将 WordPress 模块放置在 web/modules/contrib
目录中,那么您也不能使用 composer/installers
将如 index.php
和 robots.txt
等文件放入 web
目录。WordPress-scaffold 插件是为了解决这个问题而创建的。