October CMS перевод сайта. (Translate site). Часть 2

336
0
336

В первой части обсудили постановку задачи. Я привел источники, на которые можно опираться, обсудили что нам потребуется и так же сделали простой перевод статических частей сайта.
Теперь перейдем к более нетривиальной задаче.

Перевод кастомных компонентов и данных из моделей

Давайте установим Билдер, чтобы сделать небольшой плагин. 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 соответственно на русском.

Стоит добавить локализацию для валюты и цены. Тогда будет совсем ок.

Что ж таким образом можно переводить контент из моделей для любых кастомных плагинов.
Узкие места и нюансы, я возможно допишу позже.

0