Disclaimer: Эта статья про веб компоненты и уже реализованное UI решение на них. Если вам нравится все новое и нестандартное, тогда, я уверен вам понравится и наша реализация.

Я всегда мечтал о функциональности, которую можно было бы использовать в любом web проекте. Еще я мечтал иметь максимально гибкое решение для абсолютной кастомизации под себя. Два года назад мы начали работать над воплощением этой смелой мечты в реальность. Первой такой функциональностью стала именно Uni Локализация.

К сожалению, нельзя было просто так взять и сделать. Большую часть времени из этих двух лет пришлось потратить на создание правильной инфраструктуры с нуля и ее документирование. Но теперь разработка самих виджетов у нас занимает считанные часы.

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

Как нам удалось этого добиться?

Во первых, абсолютной портативности можно было добиться только лишь с HTML, так как он работает абсолютно в любом web проекте. Даже в JavaScript фреймворках это решается несколькими строчками в конфигурации или вовсе ничего не нужно ничего делать. С JavaScript библиотекой у нас бы так не получилось!

Во вторых, абсолютной кастомизации можно было добиться только с открытыми HTML шаблонами. Изменение исходного кода в JavaScript - это практически всегда потеря обратной совместимости и последующих обновлений, а при изменении открытого HTML шаблона - нет. Поэтому мы сразу же сконцентрировались только лишь на Web стандарте: Custom Elements & Web Components.

В третьих, это - принцип матрешки. Как и сам виджет, так и его внутренние компоненты имеют сразу несколько уровней вложенности, которые можно легко вытащить на поверхность, в точности как в матрешке. Приведу пример: компонента uni-icon-mat содержится в uni-icon, а она, в свою очередь, содержится в uni-button-icon, а та - в uni-button, которая содержится в меню, карточках, … Эту цепочку мы можем продолжать еще множество раз и на каждом уровне у нас будет полный и легальный доступ ко внутреннему HTML шаблону.

А что же с локализацией?

Сама Uni Локализация состоит из двух основных частей:

  1. Uni Lang Menu - next gen виджет выбора языка;

  2. Uni Translate - автоматическая компонента-переводчик;

Next Gen виджет и компонента-переводчик имеют по 3 режима:

  1. Кастомный элемент (Custom Element) - это стандартный режим. Здесь отсутствует Shadow DOM, а значит его можно полностью стилизовать с помощью CSS. Характеристики: удобство и простота - максимальный уровень; гибкость и настраиваемость - средний и высокий уровень (со свойством “only”).

  2. Веб компонент (Web Component) - это так называемый "черный ящик". Имеет собственный HTML шаблон и стили, которые изолированы по максимуму (Shadow DOM). Характеристики: надежность и безопасность - максимальный уровень; гибкость и настраиваемость - почти нулевой уровень.

  3. Распакованный (Unpacked) - весь функционал (HTML шаблон) вывернут наружу. Является очень удобным для тонкой настройки и когда нужно иметь доступ к абсолютно всему внутреннему содержимому. Характеристики: удобство и простота - средний уровень; кастомизируемость - высочайший уровень.

А как же это выглядит?

В упакованном виде (custom element / web component), виджет может выглядеть как выпадающее меню или как линейный список:

Может быть и без названия языка:

Может быть с круглыми флагами:

Может быть и без флагов:

Может отображаться различными кнопками:

Может быть с параметром в URL адресе, а может сохраняться только в памяти:

Может иметь свой, кастомный URL параметр:

Может сохраняться в объект window или sessionStorage или localStorage. Установите параметр type=”local” для того, чтобы открывать в новой вкладке с выбранным языком.

Может передавать переводы в Shadow Dom и iFrame

Даже может работать параллельно еще с несколькими виджетами локализации на одной странице и не конфликтовать с ними. Для этого необходимо указать другие пути в свойствах …-path (см.  API).

Для корректной работы виджета, необходим список языков в таком JSON формате:

[
  {
    "lang": "en", 
    "flag": "gb",
    "name": "English",
    "translation": "https://uni.github.io/loc/english.json"
  }
]

Свойство lang необходимо для только роутинга. Если свойство flag не указано, тогда флаг не будет отображаться. Список доступных на данный момент флагов указан здесь.

В разобранном виде (Unpacked), JSON формат может быть любой, как и сама реализация виджета. Вы вольны кастомизировать его как душе угодно.

Как же осуществляется сам перевод?

Uni Translate получает объект с ключами и значениями для них и проверяет текст в дочерних HTML элементах на соответствие ключам. Замена ключа на значение происходит при соблюдении нескольких условий:

  1. Ключевой текст находится в своем, отдельном HTML теге;

  2. Ключевой текст находится между (( и )) (биндинг);

Сами знаки биндинга можно переопределить и изначально они были {{ и }}, но затем были изменены по умолчанию на (( и )) для более простой интеграции с большой тройкой JS фреймворков.

Ещё биндинги можно использовать прямо в файле локализации. Это удобно для переиспользования переводов и исключения дублирования.

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

Uni Локализация является Open Source проектом с MIT лицензией. A если, к примеру, вам необходимы дополнительные флаги стран, тогда вы можете добавить их самостоятельно в репозиторий @uiwebkit/flags.

Интеграции:

WordPress plugin - есть стандартные настройки, переключая которые можно сразу же увидеть результат. Также есть Next Gen кастомизамизация, которая позволяет менять все что угодно самому прямо в настройках. Я уверен, что такого нет ни в одном другом WP виджете.

Vue.js 2 - даже для CLI билда интеграция очень простая. В index.html подключите необходимые скрипты и в main.js добавьте строку:

Vue.config.ignoredElements = [/uni-\w*/];

Vue.js 3 - для CLI билда интеграция чуть сложнее чем для второй версии. В index.html подключите необходимые скрипты и во vue.config.js добавьте:

module.exports = {
    ...,
    chainWebpack: (config) => {
        config.module
            .rule("vue")
            .use("vue-loader")
            .tap((options) => ({
                ...options,
                compilerOptions: {
                    ...options.compilerOptions,
                    // treat any tag that starts with uni- as custom elements
                    isCustomElement: (tag) => tag.startsWith("uni-"),
                },
            }));
    },
    ...
};

React - для create-react-app интеграция максимально простая. В index.html подключите необходимые скрипты. Всё!

Angular - для CLI билда интеграция очень простая. В index.html подключите необходимые скрипты и в главный модуль добавьте:

@NgModule({
  ...,
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  ...
})

Во всех интеграциях “большой тройки” не совсем корректно работает нативный HTML <template> при Next Gen кастомизации и поэтому мы рекомендуем использовать <uni-render-template>.

Планы

На подходе ещё несколько виджетов. Следующим будет виджет вкладок (Uni Tabs), а затем пойдут более крупные виджеты. Планируем выпускать новый Next Gen виджет каждый месяц или даже чаще. Ну а если если вы хотите иметь свой собственный виджет, который работает в любом web проекте и с любой технологией, тогда вы можете создать его самостоятельно с помощью UiWebKit пакетов, либо заказать его у нас.

Буду рад конструктивным комментариям и вопросам, с удовольствием на них отвечу.

Всем спасибо! Ставьте звездочки на Github, мне будет очень приятно. Подписывайтесь на наш Twitter, Facebook и Instagram, чтобы быть в курсе всех новинок. Пользуйтесь в удовольствие, берегите себя, оставайтесь здоровым и продуктивным!

Предыдущая статья

Комментарии (0)