В первой части обсудили постановку задачи. Я привел источники, на которые можно опираться, обсудили что нам потребуется и так же сделали простой перевод статических частей сайта.
Теперь перейдем к более нетривиальной задаче.
Перевод кастомных компонентов и данных из моделей
Давайте установим Билдер, чтобы сделать небольшой плагин. https://octobercms.com/plugin/rainlab-builder
В нашей демо версии создадим мини каталог-магазин.
Не будем заморачиваться, добавим простые поля товара. Нам этого хватит.
Отлично. Уж извините 🙂 ничего быстрее не придумал, но буду продавать картошку и помидоры и еще что-нибудь. НО! интернационально на всех языках. Поэтому это круто.
Сделал пару товаров.
Добавлю компонентик с помощью которого выведу информацию на фронтенд.
Код:
<?php
namespace Alex\Store\Components;
use Cms\Classes\ComponentBase;
use Alex\Store\Models\Prod as ProdModel;
class Prod extends ComponentBase
{
public $items;
public function init()
{
}
public function onRun()
{
}
public function componentDetails()
{
return [
'name' => 'Products',
'description' => 'Some Products'
];
}
public function defineProperties()
{
return [
];
}
}
Регистрируем компонент и выводим.
Plugin.php
<?php namespace Alex\Store;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function registerComponents()
{
return [
'Alex\Store\Components\Prod' => 'prods'
];
}
public function registerSettings()
{
}
}
Шаблон:
title = "Store"
url = "/store"
layout = "default"
[prods]
==
<div class="jumbotron">
<div class="container">
{% component 'contenteditor' file="lang/home/store" class='' fixture='div'%}
</div>
</div>
<div class="container">
<div class="prods">
{% for prod in prods.items %}
<div class="prod">
<div class="name">{{prod.name}}</div>
<div class="descr">{{prod.descr}}</div>
<div class="price">{{prod.price}}</div>
</div>
{% endfor %}
</div>
</div>
И пока что как мы видим появилась страничка. Продукты еще не вывелись. Давайте их перекинем с бэка.
public function onRun()
{
$this->items = ProdModel::get();
}
Как то так.
Все хорошо. Только продукты я вывел на русском. Хотя мы договорились, что дефолтный язык будет английским. Это я поправлю. Теперь надо подумать как локализовать данные из компонента.
Точнее как локализовать модель. Изначально я делал не столь гибко, тк не до конца разобрался. Я пошел по пути дополнения полей в модель. Это раздуло таблицу и к тому же вышло не гибко. У меня был случай на 2 языка. А что если их будет 2-5 десять?
Поэтому у RainlabTranslate реализован более гибкий подход. Мы будем использовать трейт для имплементации функционала перевода.
class Prod extends Model
{
use \October\Rain\Database\Traits\Validation;
public $implement = ['RainLab.Translate.Behaviors.TranslatableModel'];
public $translatable = ['name','descr'];
Добавили трейт и указали поля для перевода. В итоге получили дефолтный функционал.
И при этом наша таблица осталась с теми же полями, но добавилась отдельная таблица Rainlab с атрибутами.
Отлично. Теперь под дефолтной локалью, кою я поменял на En выводятся товары на английском, под ru соответственно на русском.
Стоит добавить локализацию для валюты и цены. Тогда будет совсем ок.
Что ж таким образом можно переводить контент из моделей для любых кастомных плагинов.
Узкие места и нюансы, я возможно допишу позже.