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 Локализация состоит из двух основных частей:
Uni Lang Menu - next gen виджет выбора языка;
Uni Translate - автоматическая компонента-переводчик;
Next Gen виджет и компонента-переводчик имеют по 3 режима:
Кастомный элемент (Custom Element) - это стандартный режим. Здесь отсутствует Shadow DOM, а значит его можно полностью стилизовать с помощью CSS. Характеристики: удобство и простота - максимальный уровень; гибкость и настраиваемость - средний и высокий уровень (со свойством “only”).
Веб компонент (Web Component) - это так называемый "черный ящик". Имеет собственный HTML шаблон и стили, которые изолированы по максимуму (Shadow DOM). Характеристики: надежность и безопасность - максимальный уровень; гибкость и настраиваемость - почти нулевой уровень.
Распакованный (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 элементах на соответствие ключам. Замена ключа на значение происходит при соблюдении нескольких условий:
Ключевой текст находится в своем, отдельном HTML теге;
Ключевой текст находится между (( и )) (биндинг);
Сами знаки биндинга можно переопределить и изначально они были {{ и }}, но затем были изменены по умолчанию на (( и )) для более простой интеграции с большой тройкой 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, чтобы быть в курсе всех новинок. Пользуйтесь в удовольствие, берегите себя, оставайтесь здоровым и продуктивным!