Когда речь заходит о блогах и небольших сайтах, нет сомнений, что WordPress стоит на первом месте. По большей части так сложилось из-за огромного количества плагинов, которые предоставляет его экосистема. Если вам необходим какой-то плагин для WordPress, то скорее всего он уже существует.

Я человек, который заботится о безопасности, и в этом отношении WP не подходит для меня. В сочетании с тем фактом, что большая часть кода WP создана без использования объектно-ориентированной архитектуры из-за этого иногда было очень сложно его расширять или поддерживать, заставило меня искать альтернативу.

Так я нашел BoltCMS и OctoberCMS. Обе CMS легкие в использовании для писателя (аналогично WP). Эти CMS также помогают разработчику. Код обеих систем основан на отраслевых стандартах, предоставляя разработчикам чистую среду для обслуживания системы или добавления новых функций по мере необходимости. Это также помогает дизайнерам и разработчикам внешних интерфейсов. Из коробки доступен Twig – приятный, дружественный шаблонизатор, позволяющий им донести свое видение пользовательского интерфейса до пользователей, используя гибкий, безопасный и простой в освоении синтаксис. Это упрощает переносимость шаблонов между CMS простыми.

В этой статье я расскажу только о OctoberCMS, но обязательно ознакомьтесь с BoltCMS. Если вы просто хотите посмотреть код, перейдите на GitHub по ссылке внизу статьи.

Погружение в код

Я предполагаю, что у вас уже установлен OctoberCMS, и если нет, вы можете воспользоваться ссылкой выше. Я не буду подробно описывать процесс установки OctoberCMS, потому что это простой процесс, который хорошо документирован на их собственном веб-сайте.

Достаточно вступлений и давайте перейдем к коду, расширив компонент из стороннего плагина.

В этой статье мы расширим плагин RainLab Blog, а точнее компонент Post. Мы добавим новое свойство и новый атрибут к каждой статье, которое будет содержать полный URL-адрес статьи.

Прежде чем мы начнем, нам нужно установить плагин Blog RainLab для OctoberCMS. Итак, зайдите на страницу плагина и ознакомьтесь с инструкциями по установке.

После установки плагина нам нужно будет создать наш собственный новый плагин, чтобы наша работа оставалась неизменной после обновления плагина Blog.

Итак, в консоли напишите следующую команду:

php artisan create:plugin KoderHut.BlogExtension

Вы можете заменить KoderHut своим именем или названием вашей компании.

На данный момент мы создали наш первый плагин OctoberCMS. Эта команда только создаст структуру папок и добавит класс с именем Plugin и yaml-файл с именем version.yaml, в котором будут храниться версии нашего плагина. Вы можете найти больше информации об этом в документации October CMS.

Внутри класса Plugin вы найдете метод с именем pluginDetails(). Этот метод используется OctoberCMS для отображения информации о плагине для конечного пользователя. Посмотрите и обновите информацию своими собственными данными.

Теперь давайте сообщим OctoberCMS, что нашему плагину для работы необходим плагин Блог RainLab.

Для этого просто добавьте следующую строку в класс Plugin:

    /**
    * Plugin dependecies
    *
    * @var array
    */
    public $require = ['RainLab.Blog'];

OctoberCMS читает свойство класса $require для проверки зависимостей между плагинами.

Теперь, когда мы добавили нашу зависимость, давайте продолжим и перезапишем компонент Post в RainLab. Для этого нам нужно создать новый компонент в нашем модуле. Сделать это можно, написав следующее в командной строке:

$ php artisan create:component KoderHut.BlogExtension Post

Я говорил вам, что OctoberCMS настолько облегчит жизнь разработчика?

В папке плагина была создана новая папка с именем компонента. Он содержит класс Post, папку с тем же именем и файлом Twig с именем default.htm. Файл Twig используется для визуализации HTML-кода компонента, но в нашем случае он нам не понадобится. Можете его удалить.

По умолчанию класс Post наследует класс ComponentBase. Нам нужно изменить это, чтобы вместо этого наследовался класс Post в RainLab.

Сначала изменим операторы «use»:

use Cms\Classes\ComponentBase,
    Cms\Classes\Page;
    
use RainLab\Blog\Components\Post as RainLabPost,
    RainLab\Blog\Models\Post as BlogPost;

Затем изменим определение класса:

    /**
    * Class Post
    *
    * @package KoderHut\BlogExtension\Components
    */
    class Post extends RainLabPost
    {
        /* ... */
    }

Теперь изменим определения свойств и добавим новое свойство, чтобы задать страницу, которая будет использоваться для просмотра статьи. Эта страница также содержит информацию об URL-адресе, которая нам понадобится для правильной генерации URL-адреса статьи.

Итак, добавьте следующий код в класс Post и перезапишите все существующие методы:

    /**
    * Override of original method
    * - add new setting for the post page id
    *
    * @return array
    */
    public function defineProperties()
    {
        $parentProps = parent::defineProperties();
        $properties = array_merge(
            $parentProps,
            [
                'postPage' => [
                    'title'       => 'rainlab.blog::lang.settings.posts_post',
                    'description' => 'rainlab.blog::lang.settings.posts_post_description',
                    'type'        => 'dropdown',
                    'default'     => 'blog/post',
                    'group'       => 'Links',
                ],
            ]
        );
        return is_array($properties) ? $properties : $parentProps;
    }
    
    
    /**
    * Retrieve the postPage properties
    *
    * @return string
    */
    public function getPostPageOptions()
    {
        return Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
    }

Метод defineProperties() добавляет новое свойство к компоненту, а метод getPostPageOptions() извлекает сохраненную настройку.

Теперь мы добавляем URL-адрес обратно к записи, переопределяя метод loadPost() следующим кодом:

    /**
    * Reference to the page name for linking to posts.
    * @var string
    */
    public $postPage;
    
    
    /**
    * Override of original method
    * - add the post URL to the post entity
    *
    * @return mixed
    */
    protected function loadPost()
    {
        $post     = parent::loadPost();
        $postPage = $this->property('postPage');
        if ($post instanceof BlogPost) {
            $post->setUrl($postPage, $this->controller);
        }
        return $post;
    }

Последний шаг перед началом использования нашего нового компонента — перетащите его с вкладки компонентов OctoberCMS на страницу или, если ваша страница уже содержит компонент Post, измените код определения компонента следующим образом с этого:

[blogPost]
slug = "{{ :slug }}"
postPage = "blog/post"

на этот:

[KoderHut\BlogExtension\Components\Post blogPost]
slug = "{{ :slug }}"
postPage = "blog/post"

Напоследок

Хотя на момент написания этой статьи OctoberCMS находится в стадии бета-тестирования, я уже вижу мощь и гибкость, которые она предоставляет как нетехническим конечным пользователям, так и разработчикам. Для конечных пользователей система плагинов хорошо спроектирована и проста: всего несколькими щелчками мыши можно добавить все необходимые функции. Количество плагинов быстро растет как платных, так и бесплатных, и довольно скоро я верю, что не нужно будет возвращаться к WP.

Кроме того, если его код хорошо организован, следует отраслевым стандартам и в полной мере использует преимущества инфраструктуры Laravel 5, которая обеспечивает его, а также все шаблоны проектирования и передовые практики, установленные сообществом делают жизнь разработчика по-настоящему легкой.

Если вы пропустили какой-либо шаг или просто хотите быстро получить исходный код плагина, вы можете найти его в моей учетной записи Github или перейдя по ссылке ниже.

Я надеюсь, вам понравилась статья. Любая обратная связь приветствуется и приветствуется.

Перевод статьи «Extending an OctoberCMS component» by Denis-Florin Rendler