Иногда требуется информация от админа. То есть не просто юзера, а юзера именно из админки. Для это используется класс BackendAuth.
useBackend\Facades\BackendAuth;BackendAuth::check()// true false проверка на юзераBackendAuth::user()// вся информация о юзереBackendAuth::user()->id// конкретное поле
Соответсвенно можете вытянуть любую нужную информацию
Например есть тестовый проект. В нем «магазин с товарами».
Я буду описывать кейс, когда уже есть лист продуктов. И только потом решили добавить сортировку. Это отличается тем, что у моих продуктов отсутствует ReorderController. При создании новой сущности, указываете, чтобы он был доступен.
При указании данного параметра создадутся вьюшка и некоторые настройки контроллера. У меня этого нет, поэтому буду делать вручную, заодно детальней.
Сначала указываю настройки reorder в контроллере, подключаю Behaivor и файл yaml.
<?phpnamespaceAlex\Store\Controllers;useBackend\Classes\Controller;useBackendMenu;classProdextendsController{public$implement=['Backend\Behaviors\ListController','Backend\Behaviors\FormController','Backend\Behaviors\ReorderController',// добавил];public$listConfig='config_list.yaml';public$formConfig='config_form.yaml';public$reorderConfig='config_reorder.yaml';// добавил public function __construct(){parent::__construct();BackendMenu::setContext('Alex.Store','main-menu-item');}}
Далее вставляю config_reorder.yaml в папке /controllers/prod. Соотв указываю заголовок, модель. NameForm скажу чуть позже для чего.
title:'Сортировка продуктов'modelClass: Alex\Store\Models\Prod
nameFrom: title
toolbar:buttons: reorder_toolbar
Добавляем собственно вьюшку reorder.htm в туже папку с нашим контроллером /controllers/prod, так как сортировка происходит на отдельной странице.
Собственно этой всей настройки можно было избежать и октобер бы сам сгенерировал как надо, при указании галочки ReorderBehavior, о чем говорил в самом начале.
Кнопка появилась, но при переходе с нее возникает ошибка, говорящая о том, что мы еще не добавили в модель Трейт сортировки.
Добавляем в нашу модель.
use\October\Rain\Database\Traits\Sortable;// Для Sortable
И далее, чтобы этот трейт корректно отрабатывал нашей моделе и соотв таблице нужно поле sort_order. Добавляем его. Тип число, nullable true.
Отлично. Заходим в сортировку. И лично у меня это выглядит так. Есть итемы, но они пустые. Это собственно поле nameForm, которое указывается в config_reorder.yaml. У меня было написано title, хотя исходя из моей таблицы нужно указать name.
Указал name. Результат
!Есть один нюанс. Он касается поля sort_order. В идеале это все делать на новой сущности. Но если мы редактируем существующую, то у поля sort_order будет стоять 0 или Null в таблице. Как было подмечено в статье https://octoclub.ru/d/21-sortable-simple-tree-nested-tree надо в ручном режиме проставить валидные значения для текущих итемов.
В моем случае все не сложно и выглядит так.
Отлично. Все почти готово. Для примера я хочу выделить классный Сыр и поставить его первым. При стандартном получении из модели, сортировка происходит автоматически.
// это из компонента Prodpublicfunctioninit(){$this->items=ProdModel::get();}
Результат
Если же вы получаете итемы другими способами, то может указать дополнительно orderBy по полю sort_order.
В первой части обсудили постановку задачи. Я привел источники, на которые можно опираться, обсудили что нам потребуется и так же сделали простой перевод статических частей сайта. Теперь перейдем к более нетривиальной задаче.
Перевод кастомных компонентов и данных из моделей
Давайте установим Билдер, чтобы сделать небольшой плагин. https://octobercms.com/plugin/rainlab-builder
В нашей демо версии создадим мини каталог-магазин.
Не будем заморачиваться, добавим простые поля товара. Нам этого хватит.
Отлично. Уж извините ничего быстрее не придумал, но буду продавать картошку и помидоры и еще что-нибудь. НО! интернационально на всех языках. Поэтому это круто. Сделал пару товаров.
Добавлю компонентик с помощью которого выведу информацию на фронтенд. Код:
Все хорошо. Только продукты я вывел на русском. Хотя мы договорились, что дефолтный язык будет английским. Это я поправлю. Теперь надо подумать как локализовать данные из компонента. Точнее как локализовать модель. Изначально я делал не столь гибко, тк не до конца разобрался. Я пошел по пути дополнения полей в модель. Это раздуло таблицу и к тому же вышло не гибко. У меня был случай на 2 языка. А что если их будет 2-5 десять?
Поэтому у RainlabTranslate реализован более гибкий подход. Мы будем использовать трейт для имплементации функционала перевода.
В данной статье я опишу мой подход к локализации сайта, который я довольно успешно применил. Я просмотрел практически всю информацию на данную тему и преобразовал ее под свои нужды. Мой подход далеко не идеальный, поэтому делитесь замечаниями и вариантами доработок, возможно мы улучшим статью.
Данный гайд основывается на версии 1, но думаю и для второй будет актуален.
В списке выше есть источник тут и тут, который прекрасно описывает как локализовать сайт, если используются стандартные плагины RainlabBlog и RainlabStaticPages. Я же буду говорить о примере, когда данные плагины практически не используются и сайт делается на своих компонентах, что я наблюдаю гораздо чаще.
Постановка задачи
локализация статического контента
локализация динамического контента в плагинах и компонентах
В моем случае я использовал смежный функционал двух плагинов: RainlabTranslate и ContentEditor. Далее я объясню как их использовать и для чего каждый.
Локализация статики
Я буду показывать на demo теме октября. Ее переводом мы и займемся.
Локализации статики — это самое простое. Для этого я использовал ContentEditor. Во первых это удобно для клиента, а во вторых он замечательно расширяется RainlabTranslate.
После установки переходим в настройку Транслейта и устанавливаем языки. Их название и локали.
Я добавил русский и сделал его по умолчанию.
Отлично. Теперь у нас доступен режим подраздела для наших локалей. Можем перейти и попробовать: http://localhost:8888/ru и http://localhost:8888/en. Пока что никаких изменений.
Теперь задаем контент эдитор. Суть плагина в том, что мы оборачиваем контент в паршил, которые хранятся в директории контента themes/demo/content. Расширение транслейта происходит за счет того, что у нас создаются поддиректории для каждого языка автоматом.
Для контент эдитора я использую твиг тег такого вида:
Отлично у нас появилась кнопка редактирования и область контента стала подсвеченной.
Теперь можем отредактировать контент под разными локалями http://localhost:8888/ru и http://localhost:8888/en. Кстати я передумал основной язык все таки будет английский а переводить будем на русский. Поэтому на локаль en оставляем без изменений, а на локали ru переводим. Как то так.
Таким же способом можно перевести и другие блоки достаточно внезависимости от сложности верстки. Тоже самое касается других страниц. При этом если мы посмотрим на директорию контент, то увидим rulang папку. Так же будет и с остальными языками.
Плюсы: — удобно для пользователя — игнорируется сложность верстки — редактирование любых страниц без использования StaticPages плагина — сколько угодно языков
Минусы — шаблон дробится на вставки из контент эдитора, что усложняет поиск элементов.
Есть список, в моем случае например товаров. Необходимо добавить какое-либо действие для обработки списка. Мне было необхдимо сделать функционал клонирования товара.
Мы идем в директорию с плагином и собственно с контроллером, который модифицируем. У меня для примера /alex/catalog/controllers/Products.php Так же нам понадобиться шаблон тулбара.
Тут уже кнопка у меня добавлена. Изначально шаблон был без нее. Шаблон находим /alex/catalog/controllers/products/_list_toolbar.htm
Как видно в шаблоны указаны все кнопки в том числе и новую мной созданную «Скопировать». На нее ставим data-request=«Ваш обработчик» и фунцкию onclick, я взял с копки удаления. Суть js забирать id-ники чекнутых итемов и передавать их на экшн.
Идем далее. Возвращаемся к контроллеру и прописываем обработчик.
/**
* @return
* Копирование товара
*/publicfunctiononCopy(){// Проверка на чекнутые товарыif(($checkedIds=post('checked'))&&is_array($checkedIds)&&count($checkedIds)){// Первый чекнутый // Делаем действия либо с одним// $copy_id = post("checked")[0];// Либо делаем действие со списком IDforeach($checkedIdsas$checkedId){// Делаем дела ........... }Flash::success('Товар скопирован');}return$this->listRefresh();}
Я обрабатывал только первый чекнутый. То есть у меня он в принципе должен быть выбрать один. Вы можете обработать несколько. На выходе я вывожу Флэш сообщение и перезагружаю список. Собственно все.
Когда я делал поля как обычно используя Page Builder, я наткнулся на ошибку: Model Alexdzen\Content\Models\Brands’ does not contain a definition for ‘image’.
Спросил в чате, оказалось, что добавления поля картинки не столь очевидно как хотелось бы.
Наше значение не указывается в таблице как поле.
Допустим моя задача сделать галлерею. Таблица состоит из Id и Image. Image — не указываем в таблице. Мы идем в нашу модель, в моем случае это Brands.php и прописываем поле image через attachOne (или attachMany).
<?phpnamespaceAlexdzen\Content\Models;useModel;/**
* Model
*/classBrandsextendsModel{use\October\Rain\Database\Traits\Validation;/*
* Disable timestamps by default.
* Remove this line if timestamps are defined in the database table.
*/public$timestamps=false;/**
* @var string The database table used by the model.
*/public$table='alexdzen_content_brands';/**
* @var array Validation rules
*/public$rules=['image'=>'required',];public$attributeNames=['image'=>'Картинка',];public$attachOne=['image'=>'System\Models\File'];}
Соответсвенно в form.yml указываем наше поле из модели.
Ну и чтобы картинка отображался в на странице Контроллера прописываем image. Значение поля я ставлю partial и путь указываю $/alexdzen/content/partials/_image3.htm.
Допустим у вас появилась задача похожую на мою. Мне было необходимо подделать метод onActivate. Соответсвенно, если мы сделаем это напрямую в плагине в классе Account, то через последующее обновление наши изменения сотрутся.
Поэтому мы идем следующем путем.
У нас есть компонент login.htm. Изначально он использует компонент Account.php Rainlab.
Допустим у вас Плагин Myplugin. В нем мы создадим свой Аккаунт компонент и отнаследуем от Rainlab.
<?phpnamespaceAlexti\Myplugin\Components;classAccount2extends\RainLab\User\Components\Account{publicfunctioncomponentDetails(){return['name'=>'Account2','description'=>'Account2'];}/**
* Activate the user
* @param string $code Activation code
*/publicfunctiononActivate($code=null){// do something}}
Соответсвенно наш компонент надо зарегистрировать в Plugin.php
Все готово. Теперь Account будет отрабатывать как обычно, но методы которые мы заоверайдили будут отрабатывать в нашем компоненте. И соответсвенно по всех шаблонах необходимо подключить наш компонент.
Пример на стандартном плагине Blog от RainLab. Допустим надо вывести посты не на страничке «все посты», а на другой и допустим не все количество? а только 15-ть.
Для этого вы воспользуемся классом плагина Post, непосредственно в нужной нам страничке в php блоке в хуке onStart. Получим все посты и занесем в переменную posts.
Далее с этой переменной делаем что нам необходимо. Во первых получим первые 15ть постов, во вторых через twig выведем их название в цикле.
==useRainLab\Blog\Models\Post;functiononStart(){$this['posts']=Post::orderBy('created_at','desc')->limit(15)->get();}=={%for post in posts %}{{post.title}}{%endfor%}
October — это бесплатная самостоятельная платформа CMS с открытым исходным кодом, основанная на PHP-фреймворке Laravel. Эта статья научит вас, как развернуть October CMS с помощью docker, но если вы хотите получить дополнительную информацию об использовании October CMS, то я бы рекомендовал перейти на страницу туториалов.
Разверните сервер Ubuntu 18.04 с объемом оперативной памяти не менее 1 ГБ. Добавьте немного подкачки, если вы находитесь на чем-то вроде DigitalOcean, который использует локальные твердотельные накопители.
Шаги
Разверните сервер Ubuntu 18.04 с объемом оперативной памяти не менее 1 ГБ.