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 the tests/ directory, composer.json file and server.php file from GitHub into your October instance and then run composer 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's composer.json:

source-json
{
    "require": {
        "laravel/framework": "~5.0",
        "mews/purifier": "~2.0",
    }
}

再运行composer updatecomposer 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

内容有些乱,给自己做个记号,下次再整理了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • Getting Started Use the Current Stable Version (7.1) Buil...
    Leonzai阅读 1,934评论 0 3
  • 原文链接 必备品 文档:Documentation API:API Reference 视频:Laracasts ...
    layjoy阅读 8,602评论 0 121
  • 是什么 如果你知道yum、apt-get、npm、bower等命令中的一种或者多种,那么,你也能很快知道compo...
    旱魃一样阅读 3,113评论 0 9
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • 一年一度的高考落下了帷幕,在这落幕时刻,有人欢喜有人忧。欢喜的当然是觉得考得好的人,忧愁当然是那些觉得考得很差的人...
    胡义华阅读 239评论 0 0