在网站建设中使用自定义模块增强网站(下)

2018-02-01 13:49


设置站点模块

那么让我们来谈谈为我们的Craft网站建设一个实际的网站模块。这里列出的所有代码都在可用的网站模块如果您想下载GitHub库。

我们所有的网站模块的作用是加载一个资源包,其中包含CSS和JavaScript,我们希望在AdminCP加载。

这允许您在登录屏幕上执行诸如拥有客户品牌背景图片之类的 功能,或者通过CSS 和  JavaScript 来调整AdminCP 的外观和功能。

工艺-资产捆绑

模块可以做得比这更多,实际上他们可以做任何插件可以做的事情。但是这个基础允许前端开发人员增强他们客户的网站,而不需要深入了解模块的工作原理。

你会发现,如果你使用的  composer create-project -s RC craftcms/craft PATH是命令  像素和  进补建议  ,以创建新的项目,他们甚至提供了一个样本  config/app.php ,并  modules/Module.php 已经为你。我们已经调整了一些东西,所以让我们开始吧!

这是项目树的样子。再次,你可以从完整的源  站点模块  GitHub的页面:

vagrant@homestead ~/webdev/craft/site-module (develop) $ tree -L 8 .
.
├── CHANGELOG.md
├── composer.json
├── config
│   └── app.php
├── LICENSE.md
├── modules
│   └── sitemodule
│       ├── CHANGELOG.md
│       ├── config
│       │   └── app.php
│       ├── LICENSE.md
│       ├── README.md
│       └── src
│           ├── assetbundles
│           │   └── sitemodule
│           │       ├── dist
│           │       │   ├── css
│           │       │   │   └── SiteModule.css
│           │       │   ├── img
│           │       │   │   └── SiteModule-icon.svg
│           │       │   └── js
│           │       │       └── SiteModule.js
│           │       └── SiteModuleAsset.php
│           ├── SiteModule.php
│           └── translations
│               └── en
│                   └── site-module.php
└── README.md

13 directories, 15 files

如果看起来很复杂,不要担心。实际上有比文件更多的组织文件夹!它基本上有3个  部分:

  1. 工艺 config/app.php
  2. 模块本身在 modules/sitemodule/src/SiteModule.php
  3. 我们加载的资产包 modules/sitemodule/src/assetbundles/SiteAsset.php

我们不需要命名空间,sitemodule/src但是我们需要一个文件夹来将我们模块中包含的所有东西组合在一起(sitemodule),以防我们有其他的模型,而且我们把所有的源代码放在一个  src子目录中。

你可以轻松地摆脱这两个目录,并把所有内容的modules/目录本身。

那么我们来看看这三个细节:

链接1.编辑CONFIG / APP.PHP

该config/目录有很多的,你已经习惯了,像配置文件general.php,db.php等用于工艺的各种设置CMS 3。但它也可以有一个app.php配置文件。

该app.php配置文件是超级强大,因为它允许您覆盖或扩展的工艺的任何部分CMS 3  的Yii 2的应用程序。再读一遍,因为它很大。使用简单的配置文件,我们可以扩展Craft CMS 3的Yii 2应用程序,或者我们可以完全替换功能。

我们只是将脚趾插入它,并添加一些代码来告诉它我们的新模块,并为我们加载它。

<?php
/**
 * Yii Application Config
 *
 * Edit this file at your own risk!
 *
 * The array returned by this file will get merged with
 * vendor/craftcms/cms/src/config/app/main.php and [web|console].php, when
 * Craft's bootstrap script is defining the configuration for the entire
 * application.
 *
 * You can define custom modules and system components, and even override the
 * built-in system components.
 */

return [

    // All environments
    '*'       => [
        'modules'   => [
            'site-module' => [
                'class' => \modules\sitemodule\SiteModule::class,
            ],
        ],
        'bootstrap' => ['site-module'],
    ],

    // Live (production) environment
    'live'    => [
    ],

    // Staging (pre-production) environment
    'staging' => [
    ],

    // Local (development) environment
    'local'   => [
    ],
];

我们给Craft模块的类,以及site 引用它的句柄,然后我们告诉它加载它的每个请求通过bootstrap。

链接2.模块类

接下来,我们有我们的Module类本身modules/sitemodule/src/SiteModule.php。这是每个请求实际加载和执行的内容:

<?php
/**
 * Site module for Craft CMS 3.x
 *
 * An example module for Craft CMS 3 that lets you enhance your websites with a custom site module
 *
 * @link      https://nystudio107.com/
 * @copyright Copyright (c) 2018 nystudio107
 */

namespace modules\sitemodule;

use modules\sitemodule\assetbundles\sitemodule\SiteModuleAsset;

use Craft;
use craft\events\RegisterTemplateRootsEvent;
use craft\events\TemplateEvent;
use craft\i18n\PhpMessageSource;
use craft\web\View;

use yii\base\Event;
use yii\base\InvalidConfigException;
use yii\base\Module;

/**
 * Class SiteModule
 *
 * @author    nystudio107
 * @package   SiteModule
 * @since     1.0.0
 *
 */
class SiteModule extends Module
{
    // Static Properties
    // =========================================================================

    /**
     * @var SiteModule
     */
    public static $instance;

    // Public Methods
    // =========================================================================

    /**
     * @inheritdoc
     */
    public function __construct($id, $parent = null, array $config = [])
    {
        Craft::setAlias('@modules/sitemodule', $this->getBasePath());
        $this->controllerNamespace = 'sitemodule\controllers';

        // Translation category
        $i18n = Craft::$app->getI18n();
        /** @noinspection UnSafeIsSetOverArrayInspection */
        if (!isset($i18n->translations[$id]) && !isset($i18n->translations[$id.'*'])) {
            $i18n->translations[$id] = [
                'class' => PhpMessageSource::class,
                'sourceLanguage' => 'en-US',
                'basePath' => '@modules/sitemodule/translations',
                'forceTranslation' => true,
                'allowOverrides' => true,
            ];
        }

        // Base template directory
        Event::on(View::class, View::EVENT_REGISTER_CP_TEMPLATE_ROOTS, function (RegisterTemplateRootsEvent $e) {
            if (is_dir($baseDir = $this->getBasePath().DIRECTORY_SEPARATOR.'templates')) {
                $e->roots[$this->id] = $baseDir;
            }
        });

        // Set this as the global instance of this module class
        static::setInstance($this);

        parent::__construct($id, $parent, $config);
    }

    /**
     * @inheritdoc
     */
    public function init()
    {
        parent::init();
        self::$instance = $this;

        if (Craft::$app->getRequest()->getIsCpRequest()) {
            Event::on(
                View::class,
                View::EVENT_BEFORE_RENDER_TEMPLATE,
                function (TemplateEvent $event) {
                    try {
                        Craft::$app->getView()->registerAssetBundle(SiteModuleAsset::class);
                    } catch (InvalidConfigException $e) {
                        Craft::error(
                            'Error registering AssetBundle - '.$e->getMessage(),
                            __METHOD__
                        );
                    }
                }
            );
        }

        Craft::info(
            Craft::t(
                'site-module',
                '{name} module loaded',
                ['name' => 'Site']
            ),
            __METHOD__
        );
    }

    // Protected Methods
    // =========================================================================
}

这个__construct()方法可能看起来有点吓人,但是我们只是在我们的Module的目录中设置一个Yii 2别名,所以我们可以稍后使用它,然后设置一些东西,这样我们的模块就可以进行翻译,并且可能在AdminCP中有模板。

只是略过了,并检查出的init()方法。

在这里我们检查一下,以确保这是一个AdminCP请求(这不是控制台/命令行请求),然后监听  EVENT_BEFORE_RENDER_TEMPLATE事件。

这个事件在即将被渲染的小枝模板之前被触发。这可以让我们加载我们的资产包, 最后加载CSS 和 JavaScript。

这是伟大的,因为我们通常要覆盖在AdminCP东西的外观或功能,并CSS特异性意味着如果我们在最后加载,我们得到的正是这样做的一个镜头。

链接3.我们的资源包

资源包只是一些任意资源的集合,例如CSS,JavaScript,图像等,需要在前端加载和使用。您可以在这里阅读关于资源包的更多信息。

这是我们的modules/sitemodule/src/assetbundles/SiteAsset.php样子:

<?php
/**
 * Site module for Craft CMS 3.x
 *
 * An example module for Craft CMS 3 that lets you enhance your websites with a custom site module
 *
 * @link      https://nystudio107.com/
 * @copyright Copyright (c) 2018 nystudio107
 */

namespace modules\sitemodule\assetbundles\SiteModule;

use Craft;
use craft\web\AssetBundle;
use craft\web\assets\cp\CpAsset;

/**
 * @author    nystudio107
 * @package   SiteModule
 * @since     1.0.0
 */
class SiteModuleAsset extends AssetBundle
{
    // Public Methods
    // =========================================================================

    /**
     * @inheritdoc
     */
    public function init()
    {
        $this->sourcePath = "@modules/sitemodule/assetbundles/sitemodule/dist";

        $this->depends = [
            CpAsset::class,
        ];

        $this->js = [
            'js/SiteModule.js',
        ];

        $this->css = [
            'css/SiteModule.css',
        ];

        parent::init();
    }
}

它只是设置sourcePath到我们的dist/目录,这意味着在dist/目录下的所有东西都是应该发布在前端web/cpresources/的哈希目录名称。

然后它说我们依赖于已经加载的AdminCP AssetBundle,并给出了 我们想要注入到AdminCP模板中的CSS 和 JavaScript 的路径。

所有你真正需要了解的是,dist/目录中的所有内容都将被发布,web/cpresources/并且 我们指定的CSS 和 JavaScript将被加载:

vagrant@homestead ~/webdev/craft/site-module/modules/sitemodule/src/assetbundles/sitemodule (develop) $ tree -L 3 .
.
├── dist
│   ├── css
│   │   └── SiteModule.css
│   ├── img
│   └── js
│       └── SiteModule.js
└── SiteModuleAsset.php

4 directories, 3 files

所以你可以修改Site.css和Site.js你的心脏的内容,它会被我们的模块在AdminCP加载。

链接使作曲家快乐

为了使作曲家高兴,我们还需要确保我们的项目composer.json文件中包含以下内容:

  "autoload": {
    "psr-4": {
      "modules\\sitemodule\\": "modules/sitemodule/src/"
    }
  },

这只是确保作曲家将知道在哪里可以找到我们的模块。你可能还需要做:

composer dump-autoload

...从项目的根目录(如果您还没有上述内容)composer.json重建Composer自动载入映射。这将自动发生,你做的任何时间  composer install或composer update为好。

链接模块在行动

下面是一个模块实例的简单示例,在我的新播客网站dev Mode .fm上: 

DEVMODE-FM-工艺-模块

使用一个小的CSS,它所做的就是把我们的彩色背景图像放在登录页面上:

/**
 * SiteModule CSS
 *
 * @author    nystudio107
 * @copyright Copyright (c) 2017 nystudio107
 * @link      https://nystudio107.com
 * @package   SiteModule
 * @since     1.0.0
 */

body.login {
    background-size: 600px;
    background-repeat: repeat;
    background-image: url('/img/site/devmode-fm-light-bg-opaque.svg');
}

body.login label, body.login #forgot-password {
    background-color: #FFF;
}

你当然可以做比模块更多的东西。最近,我重做了NYS TU DIO 107 .COM网站,你现在阅读的使用工艺CMS 3 & 顺风CSS。

作为该过程的一部分,我重写了一个特定站点的插件作为一个模块,加载一些自定义的CSS 和  JavaScript,注册一个自定义的Redactor II插件,等等。

虽然这里介绍的例子相对简单,但您可以像从插件中那样执行注册字段,添加Twig过滤器等模块。

一般的经验法则是,任何非常特定于站点的或者 “商业逻辑” -ish,你可能要重构的模块。然后只是检查到网站的主要存储库,而不是作为一个单独的插件。

如果您有网站需要建设,可以与我们取得联系。重庆网站建设


服务支持

我们珍惜您每一次在线询盘,有问必答,用专业的态度,贴心的服务。

让您真正感受到我们的与众不同!

合作流程
合作流程

重庆网站建设流程从提出需求到网站建设报价,再到网站建设,每一步都是规范和专业的。

常见问题
常见问题

什么是网站定制?网站报价如何?网站常见问题。

常见问题
售后保障

网站建设不难,难的是一如既往的热情服务及技术支持。我们知道:做网站就是做服务,就是做售后。