OctoberCMS如何使用Laravel开发拓展包
到现在为止,我还在为自己当初大多数人都无法正常访问安装Octobercms的情况下选择了OctoberCMS而庆幸,当时选择OctoberCMS除了其方便的特性和众多的插件之外,还基于其是基于Laravel开发的,而Laravel的生态也是大势所趋。
而后在开发过程中越来越证明我的判断是对的,每当业务逻辑需要一个新功能时,我基本都能找到合适的轮子并迅速上线,真正地专注于业务逻辑。
下面讲一讲在Octobercms中如何如何引入Laravle生态中的开发拓展包
分两种情况
分为两种情况,一种是全局安装,需要在octobercms的根目录引入composer,还有一种是在自己的插件目录局部引入,局部引入的好处是不用动全局的任务文件。
下面我们以https://github.com/mewebstudio/Purifier
为例来实例讲解下。
相关环境:
- October最新版(laravel5.*内核)
- PHP7.0
- HTMLPurifier laravel表单过滤插件(
https://github.com/mewebstudio/Purifier
)
注其它不同版本和环境也可参考同样的流程。
一、在全局安装方式
准备工作
全局安装需要你先把Octobercms的在线安装与管理模式全部改为composer来安装与维护。
如果你一开始是基于composer命令行安装(参看https://octobercms.com/docs/console/commands#console-install-composer
)的,那么恭喜你,可以直接引入Laravel包了;
如果你一开始是用的在线自动安装的话那还有点小纠结,这里不展开说了,请对照官网自行操作(参看https://octobercms.com/docs/console/commands#console-install-composer
)。
《如何在既有经典安装方式的项目上引入composer来管理》引自官网
To use composer with an October instance that has been installed using the Wizard installation, simply copy thetests/
directory,composer.json
file andserver.php
file from GitHub into your October instance and then runcomposer install
.
如何安装
那么进入到这一步就相对简单了,直接参考laravel包的安装说明即可
1、在octobercms的根目录直接用命令引入包
composer require mews/purifier
或者,如果出现下面的错误则可以用编辑composer配置文件,再更新的方式
This package can be installed via Composer by requiring the
mews/purifier
package in your project'scomposer.json
:
source-json
{
"require": {
"laravel/framework": "~5.0",
"mews/purifier": "~2.0",
}
}
再运行composer update
或composer install
,如果不也什么意外就安装好了,再接着就是如何调用了。
重点一般来说Laravel 5.0以上的很多插件引入时会自动修改配置文件,但october好像并不认,需要手动配置修改文件config/app.php
如下两处。
修改config/app.php 的providers,加入HTMLPurifier服务
'providers' => [
// ...
Mews\Purifier\PurifierServiceProvider::class,
]
修改config/app.php 中的aliases配置
'aliases' => [
// ...
'Purifier' => Mews\Purifier\Facades\Purifier::class,
]
发布配置文件
修改完配置文件后就要生成插件相关文件了,再在命令行输入:
php artisan vendor:publish --provider="Mews\Purifier\PurifierServiceProvider"
安装完毕。
2、引入laravel插件到octobercms开发文件中
在octobercms的相关文件顶部直接引入就行
//引入laravel插件Invite
use Invite;
二、在Octobercms插件开发目录独立引入
在octobercms的插件中可以为每一个当前开发的插件单独地写composer文件来管理依赖,这样就可以避免影响到全站文件,方便管理了,下面为译文,因原文的说明也有点乱,故修正下放在这里,没时间翻译了,以后再整理吧。
简单地说明下流程,就是直接在octobercms的插件目录中直接配置composer.json文件来引入,这点很简单,难的是如何引入这个插件。
composer.json写法参考:
{
"name": "luketowers/oc-laravelpackagesexample-plugin",
"type": "october-plugin",
"description": "OctoberCMS plugin for demonstrating the use of Laravel Packages within October plugins",
"homepage": "https://github.com/LukeTowers/oc-laravelpackagesexample-plugin",
"authors": [
{
"name": "Luke Towers",
"email": "octobercms@luketowers.ca"
}
],
"require": {
"mews/purifier": "~2.0"
}
}
引入方法:
在当前插件根目录的Plugin.php
文件中引入配置文件,并在其中用boot()
方法来进行调用,记得,别忘记plugin.php文件顶部文件的顶部包含必要的facades
和命名空间,另外,记得在正式请求路由之前运行boot()
。
Plugin.php文件写法参考:
<?php namespace LukeTowers\LaravelPackagesExample;
use App;
use Config;
use System\Classes\PluginBase;
use Illuminate\Foundation\AliasLoader;
/**
* Class Plugin
*/
class Plugin extends PluginBase
{
/**
* Returns information about this plugin.
*
* @return array
*/
public function pluginDetails()
{
return [
'name' => 'Laravel Packages Example',
'description' => 'OctoberCMS plugin for demonstrating the use of Laravel Packages within October plugins',
'author' => 'Luke Towers',
'icon' => 'icon-leaf'
];
}
/**
* 在请求路由之前运行 Runs right before the request route
*/
public function boot()
{
// Setup required packages
$this->bootPackages();
}
/**
* Boots (configures and registers) any packages found within this plugin's packages.load configuration value
*
* @see https://luketowers.ca/blog/how-to-use-laravel-packages-in-october-plugins
* @author Luke Towers <octobercms@luketowers.ca>
*/
public function bootPackages()
{
// Get the namespace of the current plugin to use in accessing the Config of the plugin
$pluginNamespace = str_replace('\\', '.', strtolower(__NAMESPACE__));
// Instantiate the AliasLoader for any aliases that will be loaded
$aliasLoader = AliasLoader::getInstance();
// Get the packages to boot
$packages = Config::get($pluginNamespace . '::packages');
// Boot each package
foreach ($packages as $name => $options) {
// Setup the configuration for the package, pulling from this plugin's config
if (!empty($options['config']) && !empty($options['config_namespace'])) {
Config::set($options['config_namespace'], $options['config']);
}
// Register any Service Providers for the package
if (!empty($options['providers'])) {
foreach ($options['providers'] as $provider) {
App::register($provider);
}
}
// Register any Aliases for the package
if (!empty($options['aliases'])) {
foreach ($options['aliases'] as $alias => $path) {
$aliasLoader->alias($alias, $path);
}
}
}
}
}
接着建立一个配置文件config/config.php
格式如下:
<?php return [
// This contains the Laravel Packages that you want this plugin to utilize listed under their package identifiers
'packages' => [
'mews/purifier' => [
// 这里的配置一般在laravel拓展插件的安装说明里面有Service providers to be registered by your plugin
'providers' => [
'\Mews\Purifier\PurifierServiceProvider',
],
// 这里的配置一般在laravel拓展插件的安装说明里面有Aliases to be registered by your plugin in the form of $alias => $pathToFacade
'aliases' => [
'Purifier' => '\Mews\Purifier\Facades\Purifier',
],
// 下边配置插件的命名空间The namespace to set the configuration under. For this example, this package accesses it's config via config('purifier.' . $key), so the namespace 'purifier' is what we put here
'config_namespace' => 'purifier',
// 下边定义的是Laravel包自己原有的配置,直接把目标Laravel包中的配置文件拷过来就行,如本例中对应的是https://github.com/mewebstudio/Purifier/blob/master/config/purifier.php
// The configuration file for the package itself. Start this out by copying the default one that comes with the package and then modifying what you need.
'config' => [
'encoding' => 'UTF-8',
'finalize' => true,
'cachePath' => storage_path('app/purifier'),
'cacheFileMode' => 0755,
'settings' => [
'default' => [
'HTML.Doctype' => 'XHTML 1.0 Strict',
'HTML.Allowed' => 'div,b,strong,i,em,u,a[href|title],ul,ol,li,p[style],br,span[style],img[width|height|alt|src]',
'CSS.AllowedProperties' => 'font,font-size,font-weight,font-style,font-family,text-decoration,padding-left,color,background-color,text-align',
'AutoFormat.AutoParagraph' => true,
'AutoFormat.RemoveEmpty' => true,
],
'test' => [
'Attr.EnableID' => true
],
"youtube" => [
"HTML.SafeIframe" => 'true',
"URI.SafeIframeRegexp" => "%^(http://|https://|//)(www.youtube.com/embed/|player.vimeo.com/video/)%",
],
],
],
],
],
];
引入原文:
当我在OctoberCMS中开发插件的时候,有过很多次想在其中使用Laravel开发拓展包的冲动,但问题是……
Several times while developing plugins for October, I've needed to include Laravel Packages in the plugin. The problem with doing this is that these packages assume that one will be able to configure them at a project level with things like config files for that specific package that get published to the config folder, or service providers and aliases that need to be registered with the application before you can use them.
I've written a blog post about how to deal with these packages within your October plugins in a clean and easy to use way. You can view the post here https://luketowers.ca/blog/how-to-use-laravel-packages-in-october-cms-plugins/
作者写了两篇文章关于如何在octobercms中使用laravel拓展包的文章。
http://octobercms.com/forum/post/how-to-use-laravel-packages-in-october-plugins
https://luketowers.ca/blog/how-to-use-laravel-packages-in-october-cms-plugins/
正文如下:
How to use Laravel Packages in OctoberCMS Plugins
This is just a quick guide on how to easily include Laravel Packages in OctoberCMS plugins.
Laravel Packages are often more complicated than simple classes that you can include in your project wherever. They can offer several things that are relatively easy to manage within a barebones Laravel application such as configuration files, service providers, and aliases; however things get slightly more complicated when you wish to use these packages within an October plugin.
The first thing that you’ll need to do in order to use a Laravel Package within your plugin is to require it via composer. Create a composer.json file in your plugin’s folder, and then add the packages you wish to use to the require object. An example of a composer.json for an October CMS plugin that requires a Laravel Package is below:
{
"name": "luketowers/oc-laravelpackagesexample-plugin",
"type": "october-plugin",
"description": "OctoberCMS plugin for demonstrating the use of Laravel Packages within October plugins",
"homepage": "https://github.com/LukeTowers/oc-laravelpackagesexample-plugin",
"authors": [
{
"name": "Luke Towers",
"email": "octobercms@luketowers.ca"
}
],
"require": {
"mews/purifier": "~2.0"
}
}
After you add your packages to composer.json, run composer update from the root of your project; this will pull those dependencies into your project so that you can use them. No need to run composer update or install from your plugin folder itself, if your plugin is being submitted to the October CMS marketplace the marketplace will generate the vendor folder for your plugin automatically.
现在,要做拓展包的初始设置/安装了,你不能仅仅只运行默认的扩展包安装命令就完事儿,你需要注册service providers和aliases,然后,也还要提供一个方法给你的plugin插件,用来管理拓展包的配置文件。所有这些工作都可以在Octobercms的插件项目中相对轻松地完成,但是当您想要确保您的插件可以实际用于其他人的项目时,就会遇到棘手的问题。
Now, as far as package initial setup / installation goes, you can’t just run the default installation commands for the package and be done, you need to register service providers and aliases, and then also provide a method for your plugin to manage the configuration of that package. All of these things can be done within an October project relatively painlessly, but the tricky bit comes when you want to make sure that your plugin can actually be used on other people’s projects.
但不要害怕,因为OctoberCMS包含了好几种简单的方法来动态注册包的各个组件。下面是我创建的一个方法,它可以方便地给你的plugin插件项目注册任何的Laravel拓展包。将此方法放置在当前插件根目录的Plugin.php
文件中,然后从插件的boot()方法来调用(同样在Plugin.php中操作)。
Never fear however, as October includes several easy ways to dynamically register the various components of the package. Below is a method that I’ve created that will easily register any Laravel packages for your plugin. Place this method in your plugin’s Plugin.php file, and then call it from the plugin’s boot() method (also in Plugin.php).
要确保你的plugin.php文件的顶部包含必要的facades
,参考下面的写法:
Also ensure that your Plugin.php includes the necessary facades at the top of the file below the namespace declaration as below:
use App;
use Config;
use Illuminate\Foundation\AliasLoader;
/**
* Boots (configures and registers) any packages found within this plugin's packages.load configuration value
*
* @see https://luketowers.ca/blog/how-to-use-laravel-packages-in-october-plugins
* @author Luke Towers <octobercms@luketowers.ca>
*/
public function bootPackages()
{
// Get the namespace of the current plugin to use in accessing the Config of the plugin
$pluginNamespace = str_replace('\\', '.', strtolower(__NAMESPACE__));
// Instantiate the AliasLoader for any aliases that will be loaded
$aliasLoader = AliasLoader::getInstance();
// Get the packages to boot
$packages = Config::get($pluginNamespace . '::packages');
// Boot each package
foreach ($packages as $name => $options) {
// Setup the configuration for the package, pulling from this plugin's config
if (!empty($options['config']) && !empty($options['config_namespace'])) {
Config::set($options['config_namespace'], $options['config']);
}
// Register any Service Providers for the package
if (!empty($options['providers'])) {
foreach ($options['providers'] as $provider) {
App::register($provider);
}
}
// Register any Aliases for the package
if (!empty($options['aliases'])) {
foreach ($options['aliases'] as $alias => $path) {
$aliasLoader->alias($alias, $path);
}
}
}
}
现在你可以通过在你的插件的配置文件中包含这些包来加载任何的拓展包了。
Now, you can load any packages you want by including them in your plugin’s configuration file, which is located here: /plugins/vendorName/pluginName/config/config.php.
任何在vendorName.pluginName::packages配置文件中发现的包都将自动加载。
Any packages found in the ‘vendorName.pluginName::packages’ config value will be loaded.
下边是一个用来加载 mews/purifier Laravel package的config.php的写法示例:
Below is an example of a config.php file that is configured to load the mews/purifier Laravel package.
现在,您可以通过将它们包括在你的插件的配置文件中来加载任意的包了,该文件位于这里:
/plugin s/vendorName/pluginName/config/config.php
。
config/config.php
所有的包,只要在vendorName.pluginName::packages
配置了值的,都会被加载。
下面是一份config.php
的配置文件示例,该文件被配置为加载mews/purifier Laravel package的laravel包。
<?php return [
// This contains the Laravel Packages that you want this plugin to utilize listed under their package identifiers
'packages' => [
'mews/purifier' => [
// Service providers to be registered by your plugin
'providers' => [
'\Mews\Purifier\PurifierServiceProvider',
],
// Aliases to be registered by your plugin in the form of $alias => $pathToFacade
'aliases' => [
'Purifier' => '\Mews\Purifier\Facades\Purifier',
],
// The namespace to set the configuration under. For this example, this package accesses it's config via config('purifier.' . $key), so the namespace 'purifier' is what we put here
'config_namespace' => 'purifier',
// The configuration file for the package itself. Start this out by copying the default one that comes with the package and then modifying what you need.
'config' => [
'encoding' => 'UTF-8',
'finalize' => true,
'cachePath' => storage_path('app/purifier'),
'cacheFileMode' => 0755,
'settings' => [
'default' => [
'HTML' => [
'Doctype' => 'XHTML 1.0 Strict',
'Allowed' => 'div,b,strong,i,em,a[href|title],ul,ol,li,p[style],br,span[style],img[width|height|alt|src]',
],
'CSS' => [
'AllowedProperties' => 'font,font-size,font-weight,font-style,font-family,text-decoration,padding-left,color,background-color,text-align',
],
'AutoFormat' => [
'AutoParagraph' => true,
'RemoveEmpty' => true,
],
],
'test' => [
'Attr' => ['EnableID' => true]
],
"youtube" => [
"HTML" => ["SafeIframe" => 'true'],
"URI" => ["SafeIframeRegexp" => "%^(http://|https://|//)(www.youtube.com/embed/|player.vimeo.com/video/)%"],
],
],
],
],
],
];
文件的源码参考
https://github.com/LukeTowers/oc-laravelpackagesexample-plugin
内容有些乱,给自己做个记号,下次再整理了。