vorst.ru - Как сделать двуязычный сайт
Статьи из рубрики about-sites

Рефакторинг кода авторизации

Использование аккаунта социальной сети для авторизации

Авторизация с помощью социальной сети не должна зависеть от типа аккаунта. В предыдущем посте используется код, где в конструкторе классa common/components/SocialContact.php выполняется оператор switch. При добавлении обработчика для новой социальной сети, придется дописывать код, при этом меняя класс.

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


Как подключить авторизацию через аккаунт

OAuth2 авторизация с использованием аккаунта

Допустим, что вы уже зарегистрированы в известной социальной сети. То есть вы уже сообщили о себе, все, что считали нужным. Очевидно вам не хочется проходить процедуру еще раз на другом ресурсе.


Модерация и вывод комментариев

Ответ на комментарии и рекурсивный вывод

На сайте оставили комментарий, вы ответили. Оппонент что-то еще уточнил, вы опять ответили. Цепочка из нескольких вопросов/ответов, которую нужно представить в виде лестницы.

Отступы можно выводить в обычном цикле, но если отступы формируются с помощью блочных элементов и css, то проще использовать рекурсию.


Модуль для управления блогом

Блог включает управление комментариями, пользователями, rbac

Новости, сообщения, описания - это все статьи, а статьи - это блог. Блог является важной составляющей любого сайта.

Блог настолько важен, что самая популярная CMS на планете WordPress - это блог.

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


Как отправить email с сайта и не попасть в спам

Как указать реального отправителя отправляя сообщение с сайта

При создании сайта почти всегда предусматривают форму обратной связи.

Допустим у вас на сайте есть форма обратной связи и посетитель заполнил в ней поле Name и поле Email. Логично отправить сообщение с сайта от имени посетителя на адрес администратора сайта или, например, адрес отдела маркетинга.

Но так отправить сообщение не получится. При отправке сообщения с сайта, нужно чтобы отправитель имел тот-же домен, что и сайт.


Как определить правило для RBAC

Выполнять действие или нет

В предыдущей статье были определены две роли - Админ и Автор, как в обычном блоге. А обычно блог используется при создании любого сайта. Для ролей Админ и Автор были определены разрешения.

Если вы Админ, то у вас есть общее разрешение create. Оно дает право добавлять данные к любым моделям. Если вы Автор, то такое разрешение давать не стоит. Автор не может, например, добавить новую рубрику.


Определение разрешений на доступ и ролей для пользователей

Задание доступа только к определенным действиям

Разработка бекенда сайта часто подразумевает ограничение прав при редактировании контента.

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


Как подключить RBAC

Подключение ролевого доступа

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

Именно распределение прав для групп пользователей и будет рассмотрено в паре-тройке статей. В качестве примера будет использоваться всего две роли.


Как определить и вызвать событие

Пример события

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

В первом случае обработчик события один, во-втором их несколько. Но принцип один - наступило событие, надо действовать.


Пример работы с сессией

Если читатель хочет вспомнить, что просмотрено и прочитано

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


Как разместить контент на двух языках

Перевод контента сайта

Для перевода интерфейса в Yii применяется таблица из двух колонок. В первой колонке записываются слова или фразы на английском, во второй - перевод на русском. Строки отсортированы по первой колонке. В тексте программы вместо нужного слова или фразы вызывается функция t('Word or Phrase'). Если текущий язык сайта английский, функция возвращает параметр, иначе соответствующий перевод.

Для контента такой перевод невозможен и, обычно, создается отдельный, полностью переведенный сайт. Но когда автор статьи и переводчик одно лицо, этот подход сложен и не удобен. Проще переводить каждый абзац сразу.



Поиск



Как разместить контент на двух языках

Перевод контента сайта

Для перевода интерфейса в Yii применяется таблица из двух колонок. В первой колонке записываются слова или фразы на английском, во второй - перевод на русском. Строки отсортированы по первой колонке. В тексте программы вместо нужного слова или фразы вызывается функция t('Word or Phrase'). Если текущий язык сайта английский, функция возвращает параметр, иначе соответствующий перевод.

Для контента такой перевод невозможен и, обычно, создается отдельный, полностью переведенный сайт. Но когда автор статьи и переводчик одно лицо, этот подход сложен и не удобен. Проще переводить каждый абзац сразу.


    Поделиться

Пусть каждый тег с русским текстом имеет класс .ru, а такой же тег с английским текстом имеет класс .en.

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

Заголовки на разных языках будем разделять символом "/".

Behavior

В поведении LangSwitcher.php определены два метода, которые удаляют, не нужную на данный момент, часть контента. Первый тот, что удаляет не нужные теги.

private static $languages = ['ru' => 0, 'en' => 1];
private static $opposite = ['ru' => 'en', 'en' => 'ru'];
private static $translatedTags = '(h1|h2|h3|h4|p|ul|ol|blockquote)';
...
public function excludeByLanguage($attribute = 'excerpt')
{
    return preg_replace('/<' . 
        self::$translatedTags . ' class="'. self::$opposite[$this->language] .'">(.+)<\/' . 
        self::$translatedTags . '>/isU', '', $this->owner->$attribute);
}

Второй выбирает нужную часть заголовка.

public function splitByLanguage($attribute = 'title', $language = null)
{
    $language = $language ? $language : $this->language;
    $vals = explode('/', $this->owner->$attribute);
    return (count(self::$languages) == count($vals))
        ? trim($vals[self::$languages[$language]])
        : $this->owner->$attribute;
}

Теперь в представлении достаточно вызывать нужный метод. Например так:

<div class="post-excerpt">
    <?= $model->excludeByLanguage('excerpt'); ?>
</div>

RSS & feeds

Чтобы сервисы, предоставляющие информацию по требованию извне, получали нужную языковую версию нужно переопределить в модели метод fields (пример rss).

public function fields()
{
    return [
        'id', 'author_id', 'slug', 'previous', 
        'title' => function ($model) { return $model->splitByLanguage('title');},
        'subtitle' => function ($model) { return $model->splitByLanguage('subtitle');},
        'excerpt' => function ($model) { return $model->excludeByLanguage(); },
        'content' => function ($model) { return $model->excludeByLanguage('content'); },
        'resume' => function ($model) { return $model->excludeByLanguage('resume'); },
        'tags', 'rubric', 'status', 'created_at', 'updated_at', 
        'keywords' => function ($model) { return $model->splitByLanguage('keywords');},
        'description' => function ($model) { return $model->splitByLanguage('description');},
    ];
}

Как скрывается текст с одним языком и показывается другой теперь понятно. Но как узнать, какой язык сейчас текущий и как его переключить?

Первую часть работы выполняет widget. Он определяет и устанавливает текущий язык используя cookie. Cмену языка выполняет действие контроллера. Виджет и контроллер можно посмотреть в расширении - yii2-lang-switcher.

Static pages

С динамичным контентом все ясно, а что делать со статичными страницами? В них хотелось бы использовать тот-же подход. Для этого нужно пропустить вывод метода renderContent контроллера через фильтр аналогичный методу excludeByLanguage упомянутому выше.

Поэтому в расширении github.com/yii2-lang-switcher есть еще один контроллер. От него должен наследоваться например frontend\controllers\SiteController.php.

use sergmoro1\langswitcher\controllers\Controller;
class SiteController extends Controller
{

Заключение

Предложенный вариант интернационализации сайта прост в установке и поддержке. Но, скорее всего, подходит только для пары языков.

Оставить комментарий

Только авторизованные пользователи могут оставлять комментарии. Пожалуйста авторизуйтесь или пройдите регистрацию.