SlideShare a Scribd company logo
JavaScript
Укладка изображений в галереях
и интернационализация приложений
Денис Ольшин
http://vk.com/denull
О чем пойдет речь
Задача: делаем Single page application.
Или расширение для Хрома.
Или приложение на PhoneGap.
Или приложение для социальной сети.
Или свою социальную сеть.
Или вообще любой современный сайт.
О чем пойдет речь
Общие задачи решают фреймворки.
Рассмотрим две частные (на самом деле не
связанные, зато интересные) задачи:
1. Как вывести много картинок.
2. Как выводить много текста.
Часть 1. Укладка изображений
(layout то есть, но раз уж вторая часть про
локализацию…)
В этой части будет много картинок.
Цель?
● Выводим картинки или текст, HTML?
● Много (лента), мало (альбом) или очень
мало (запись с аттачами)?
● Можно сжимать и обрезать?
● Можно менять местами?
● Можно таскать, редактировать,
анимировать?
Тривиальный случай: квадратики!
Фиксируем соотношение
сторон — соответственно,
можем легко посчитать число
строк и столбцов.
Используется: повсеместно.
Квадратики+
Если на некоторых фото
хочется сделать акцент —
делаем их в 4 раза больше.
Требуется чтобы число столбцов было
четным (бонус: укладка на одном CSS).
Используется: Facebook
А если не квадрат?
Вариант А: сжимать
+ всё на месте
– дырки
– всё мелкое
Вариант Б: обрезать
+ аккуратные поля
– потери
– иногда потери
критические
(портреты?)
Сделаем поинтереснее
Пусть можно сжимать, но очень не хочется
обрезать И оставлять пустые «дырки».
Bin Packing Problem:
NP-полнота, нужен
перебор всех комбинаций.
(Почти) идеальное решение
Фиксированная высота строки, ничего не
обрезано, везде равные поля.
Используется: поиск
Google, Яндекс,
iOS-приложение ВК
(в альбомах).
Как эта магия работает?
Сколько бы картинок ни было в строке, их
можно сделать равной высоты, а суммарную
ширину — равной ширине строки.
«Набиваем» их, пока высота > minRowHeight
...и когда эта магия не работает?
● В небольших альбомах висячая
последняя строка портит вид.
● У широооких фоток (ландшафты,
панорамы) преимущество перед
высокими (портреты).
● Строки немного плавают по высоте.
Когда фоток совсем мало
Перебираем, сколько положим на каждую
строчку и из всех вариантов выбираем
оптимальный по
пропорциям/размеру.
Используется: ВК
(в постах)
А если столбики, а не строки?
Если порядок не особо
важен, можно просто
заполнять столбики.
Чит: ещё можно выбирать ширину столбиков
как-нибудь по-хитрому.
Используется: tumblr, Pinterest, Lightbox
Дополнительный чит
Подгоняем под сетку, когда соседние
столбики выровнялись — вставляем
широкую картинку, становится не так скучно.
Столбики+
Фиксируем число
столбцов (немного)
и перебираем разные
варианты. Можно делать акценты.
Используется: 500px
Экзотика: золотое сечение
Пользуемся тем, что из двух ландшафтов
четко формируется один портрет (и наоборот).
– У портретов или
у ландшафтов перевес.
– Квадратам места нет.
– Висячий хвост в конце.
Как всё это применить?
Например, Masonry:
Или Packery.
Или Isotope.
Все упаковывают,
никто не масштабирует: не для картинок.
http://masonry.desandro.com/
http://packery.metafizzy.co/
Как всё это применить?
Или вот Freewall:
плагин jQuery.
Поддерживает
4 укладки, перетаскивание и анимации.
http://vnjs.net/www/project/freewall/
(Почти) идеальное решение+
Внутрь строк прячем стопки! Наполняем
почти как строки — пока можем.
Теперь широкие фотки
складываются в стопки,
а не забивают всю строку.
+ Можно гибко настраивать размеры строк и
стопок.
+ Альтернативный режим: подгонять все
фото под искомую площадь. Бонус: можно
делать акценты (задать искомую площадь
побольше).
– Те же проблемы с последней строкой.
– Строки по-прежнему могут плавать.
Где используется?
А нигде.
Но есть в виде библиотеки!
Paver.JS
https://github.com/deNULL/Paver.js
Использование
Paver(dataSource, width, opts).render(el);
dataSource – массив, у элементов поля
width, height.
width – ширина контейнера.
opts – настройки.
el – контейнер, куда всё отрисовать.
Для рендеринга в opts передаем функцию:
renderTile: function(tile, path) {
…
return html;
},
path содержит тройку индексов row, stack и
tile – номер строчки, стопки и картинки в
стопке.
Использование
И о настройках
Демка
Тут можно подергать за рычажки:
http://denull.github.io/Paver.JS/
Конец первой части.
Есть вопросы?
Следующая часть начнется
после перерыва.
Часть 2. Об интернационализации
(и локализации тоже)
● язык = ru, en
● локаль = ru_RU, en_US, en_GB
● перевод = отображение ключей на строки
● интернационализация = i18n = подготовка
● локализация = l10n = процесс перевода
А нужны ли эти заморочки?
Нужны.
● Задел на будущее.
● Избавление от «Найдено 21 фотографий».
● Возможность править тексты без правки
шаблонов.
Начнем с простого
Все строки кладем в виде полей куда-нибудь
в lang { … }, а потом достаем по lang[‘key’].
Сразу же хочется научиться делать
подстановки (интерполировать) — пишем
функцию:
function T(key, substitute) { … }
А что там с числами?
Всё страшно.
В каждом языке свои
категории. До шести
штук. ШЕСТИ, КАРЛ.
http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
Половой вопрос
Тут чуть проще: только два случая (если не
придираться).
Придется спрашивать ещё одно поле при
регистрации, зато никаких уродливых
«Загрузил(а)».
Число, род… и падеж, конечно
Тут всё совсем плохо. Даже для одного
языка фамилии склоняются по
неоднозначно определенным правилам:
Чаплин → Чаплином или Чаплиным?
Повезло тем, у кого в языке падежей нет.
Решение: Petrovich.js
Работа с датами
Тут всё чуть иначе: формат зависит от
локали, а не от языка.
Но от языка зависят фразы типа «3 часа
назад», которые хорошо бы тоже уметь
выводить с умом.
Решение: moment.js, разумеется.
Работа с числами
Всё аналогично датам, только заморочек с
выводом относительного времени нет.
Решение: Numeral.js или сами фреймворки
А как же .toLocaleString()?
В ванильном JS есть:
Date.prototype.toLocaleString()
Number.prototype.toLocaleString()
Есть давно, но настроить можно только с
Chrome 24, FF 29, IE 11, Opera 15, а в Safari
до сих пор нельзя.
А неплохо бы ещё...
...вспомнить о типографских правилах.
● кроме «-» есть, как минимум, «—» и «–»
● кавычки бывают “тоже” «разные»
● автозамены: (c) , (r) , (tm) , ...
● и вообще много всего
Решения: Типограф, mdash.ru, грамотность.
Итого:
Для i18n + l10n:
● l10n.js
● LocalePlanet
● L20n от Mozilla
● Moment.js – даты
● Numeral.js – числа
● Petrovich.js – имена
● Типограф – правила
Ближе всего к тому, что надо: FormatJS.io и
i18next.com (но все равно не идеально)
+
У всех свои форматы :(
i18next:
{ en: { translation: {
girlsAndBoys:
'$t(girls, {"count": __girls__})
and __count__ boy',
girlsAndBoys_plural:
'$t(girls, {"count": __girls__})
and __count__ boys' },
girls: '__count__ girl',
girls_plural: '__count__ girls'
} } };
FormatJS:
‘You have {itemCount, plural,
=0 {no items}
one {1 item}
other {{itemCount} items}
}.’
Это хотя бы стандарт
Message ICU
Но он совсем адовый
Хочется всего и сразу
Но без излишеств (встроенного во
фреймворки не хватает, тащить кучу
библиотек ради базовых вещей грустно). К
тому же, вещи реально тесно связанные.
Склонять имена вообще все боятся.
Мое решение?
Да, ещё один велосипед. С блекджеком и
своим форматом шаблонов.
T.js
https://github.com/deNULL/T.js
Это почти как шаблонизатор, но нет
photos: 'фотографий',
liked: 'оценил',
user_liked: '{user} {>liked} {photos} {>photos}',
Делаем: T(‘user_liked’, {user: ’Олег’, photos: 5})
и получаем: ‘Олег оценил 5 фотографий’.
Подставили входные данные + другие ключи.
Структура языковых данных
T.define({ ru: {
key1: ‘str1’,
key2: ‘str2’,
key3: { subkey: { subsubkey: ‘wow’ } },
}})
Можно вызывать сколько угодно раз.
Вложенность любая. Достаем через точку:
T(‘key3.subkey.subsubkey’)
А что с числами?
Чтобы не было ‘Олег оценил 1 фотографий’:
photos: { $plural: {
one: ‘фотографию’, few: ‘фотографии’,
other: ‘фотографий’
}}
Категории зависят от языка, есть поддержка
ru/en. Можно добавить свою функцию
определения категории.
А если не Олег, а Анна?
liked: { $gender: {
m: ‘оценил’, f: ‘оценила’
}}
Аналогично, но надо передавать пол как
параметр в подставляемый шаблон:
user_liked: ‘… {>user.name user.gender} …’
T(‘user_liked’,
{ user: { name: ‘Анна’, gender: ‘f’});
А добавить «... Ильи» в конце?
user_liked: ‘… {$name.gen whom.name}’
= вызов функции $name с первым
параметром whom.name, вторым — ‘gen’
(родительный падеж).
Есть внутренние функции $name, $surname,
$patronym для русского, их можно
доопределить или переопределить.
Что за «вызов функции»?
Функция = шаблон. Подставить шаблон =
вызвать функцию. Если имя функции или
шаблона начинается с $, то при подстановке
> не нужен ({>$some} = {$some}).
То, что после точек (func.p1.p2)
интерпретируется как дополнительные
параметры.
Бонус: трансформации
Пишем:
user: ‘пользователь’
Получаем:
T(‘user’) => ‘пользователь’
T(‘User’) => ‘Пользователь’
T(‘USER’) => ‘ПОЛЬЗОВАТЕЛЬ’
Непривычно, но может быть удобно.
И внезапно — инлайн-перевод
T.inlineTranslation(true);
TA-DA! Все строки кликабельны и открывают
окошко с текстом перевода.
Сохранение изменений (и проверка прав) на
сервере — лежит на вас.
T.showAllKeys();
Показать вообще все ключики списком.
Такая вот красота
Это всё без дополнительных зависимостей.
Можно и вырезать, если юзер не переводчик.
К слову
T(‘user!’) — Локально отключить инлайн.
Инлайн-перевод генерит HTML — в
шаблонизаторы надо подставлять результат
в сыром виде (Angular: $sce + ng-bind-html).
Во входных данных эскейпятся < и > – а в
самих переводах нет, будьте внимательны.
Чего пока нет
● форматирование дат ({$date …})
● форматирование чисел ({$num …})
Под некоторым сомнением: применение
типографских правил.
Конец второй части.
Есть вопросы?
Денис Ольшин
http://vk.com/denull

More Related Content

Similar to Kl10 tch – paver.js + t.js

CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы
CodeFest 2014. Гайдаренко О. — Промисы и jQuery ПромисыCodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы
CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы
CodeFest
 
Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013
ScalaNsk
 
Android: Как написать приложение, которое не тормозит
Android: Как  написать приложение, которое не тормозитAndroid: Как  написать приложение, которое не тормозит
Android: Как написать приложение, которое не тормозит
Elena Kotina
 
Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)
Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)
Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)
Ontico
 

Similar to Kl10 tch – paver.js + t.js (20)

Статический анализ и регулярные выражения
Статический анализ и регулярные выраженияСтатический анализ и регулярные выражения
Статический анализ и регулярные выражения
 
CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы
CodeFest 2014. Гайдаренко О. — Промисы и jQuery ПромисыCodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы
CodeFest 2014. Гайдаренко О. — Промисы и jQuery Промисы
 
"Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
"Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24"Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
"Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
 
Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013
 
Как и зачем можно создать DSL на Python
Как и зачем можно создать DSL на PythonКак и зачем можно создать DSL на Python
Как и зачем можно создать DSL на Python
 
Android: Как написать приложение, которое не тормозит
Android: Как  написать приложение, которое не тормозитAndroid: Как  написать приложение, которое не тормозит
Android: Как написать приложение, которое не тормозит
 
Invisible
InvisibleInvisible
Invisible
 
Viacheslav Eremin about DOT NET (rus lang)
Viacheslav Eremin about DOT NET (rus lang)Viacheslav Eremin about DOT NET (rus lang)
Viacheslav Eremin about DOT NET (rus lang)
 
Пора учить WebGL
Пора учить WebGLПора учить WebGL
Пора учить WebGL
 
Уроки Scratch
Уроки Scratch Уроки Scratch
Уроки Scratch
 
Ruby строки
Ruby строкиRuby строки
Ruby строки
 
Aaa
AaaAaa
Aaa
 
Большой брат помогает тебе
Большой брат помогает тебеБольшой брат помогает тебе
Большой брат помогает тебе
 
робот
роботробот
робот
 
Jquery_tutorial_for-beginners
Jquery_tutorial_for-beginnersJquery_tutorial_for-beginners
Jquery_tutorial_for-beginners
 
Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?
 
Собеседование на позицию Java Developer
Собеседование на позицию Java DeveloperСобеседование на позицию Java Developer
Собеседование на позицию Java Developer
 
модель акторов и C++ что, зачем и как ?
модель акторов и C++ что, зачем и как ?модель акторов и C++ что, зачем и как ?
модель акторов и C++ что, зачем и как ?
 
Систематизация экспрешнов в IE
Систематизация экспрешнов в IEСистематизация экспрешнов в IE
Систематизация экспрешнов в IE
 
Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)
Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)
Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)
 

Kl10 tch – paver.js + t.js

  • 1. JavaScript Укладка изображений в галереях и интернационализация приложений Денис Ольшин http://vk.com/denull
  • 2. О чем пойдет речь Задача: делаем Single page application. Или расширение для Хрома. Или приложение на PhoneGap. Или приложение для социальной сети. Или свою социальную сеть. Или вообще любой современный сайт.
  • 3. О чем пойдет речь Общие задачи решают фреймворки. Рассмотрим две частные (на самом деле не связанные, зато интересные) задачи: 1. Как вывести много картинок. 2. Как выводить много текста.
  • 4. Часть 1. Укладка изображений (layout то есть, но раз уж вторая часть про локализацию…) В этой части будет много картинок.
  • 5. Цель? ● Выводим картинки или текст, HTML? ● Много (лента), мало (альбом) или очень мало (запись с аттачами)? ● Можно сжимать и обрезать? ● Можно менять местами? ● Можно таскать, редактировать, анимировать?
  • 6. Тривиальный случай: квадратики! Фиксируем соотношение сторон — соответственно, можем легко посчитать число строк и столбцов. Используется: повсеместно.
  • 7. Квадратики+ Если на некоторых фото хочется сделать акцент — делаем их в 4 раза больше. Требуется чтобы число столбцов было четным (бонус: укладка на одном CSS). Используется: Facebook
  • 8. А если не квадрат? Вариант А: сжимать + всё на месте – дырки – всё мелкое Вариант Б: обрезать + аккуратные поля – потери – иногда потери критические (портреты?)
  • 9. Сделаем поинтереснее Пусть можно сжимать, но очень не хочется обрезать И оставлять пустые «дырки». Bin Packing Problem: NP-полнота, нужен перебор всех комбинаций.
  • 10. (Почти) идеальное решение Фиксированная высота строки, ничего не обрезано, везде равные поля. Используется: поиск Google, Яндекс, iOS-приложение ВК (в альбомах).
  • 11. Как эта магия работает? Сколько бы картинок ни было в строке, их можно сделать равной высоты, а суммарную ширину — равной ширине строки. «Набиваем» их, пока высота > minRowHeight
  • 12. ...и когда эта магия не работает? ● В небольших альбомах висячая последняя строка портит вид. ● У широооких фоток (ландшафты, панорамы) преимущество перед высокими (портреты). ● Строки немного плавают по высоте.
  • 13. Когда фоток совсем мало Перебираем, сколько положим на каждую строчку и из всех вариантов выбираем оптимальный по пропорциям/размеру. Используется: ВК (в постах)
  • 14. А если столбики, а не строки? Если порядок не особо важен, можно просто заполнять столбики. Чит: ещё можно выбирать ширину столбиков как-нибудь по-хитрому. Используется: tumblr, Pinterest, Lightbox
  • 15. Дополнительный чит Подгоняем под сетку, когда соседние столбики выровнялись — вставляем широкую картинку, становится не так скучно.
  • 16. Столбики+ Фиксируем число столбцов (немного) и перебираем разные варианты. Можно делать акценты. Используется: 500px
  • 17. Экзотика: золотое сечение Пользуемся тем, что из двух ландшафтов четко формируется один портрет (и наоборот). – У портретов или у ландшафтов перевес. – Квадратам места нет. – Висячий хвост в конце.
  • 18. Как всё это применить? Например, Masonry: Или Packery. Или Isotope. Все упаковывают, никто не масштабирует: не для картинок. http://masonry.desandro.com/ http://packery.metafizzy.co/
  • 19. Как всё это применить? Или вот Freewall: плагин jQuery. Поддерживает 4 укладки, перетаскивание и анимации. http://vnjs.net/www/project/freewall/
  • 20. (Почти) идеальное решение+ Внутрь строк прячем стопки! Наполняем почти как строки — пока можем. Теперь широкие фотки складываются в стопки, а не забивают всю строку.
  • 21. + Можно гибко настраивать размеры строк и стопок. + Альтернативный режим: подгонять все фото под искомую площадь. Бонус: можно делать акценты (задать искомую площадь побольше). – Те же проблемы с последней строкой. – Строки по-прежнему могут плавать.
  • 22. Где используется? А нигде. Но есть в виде библиотеки! Paver.JS https://github.com/deNULL/Paver.js
  • 23. Использование Paver(dataSource, width, opts).render(el); dataSource – массив, у элементов поля width, height. width – ширина контейнера. opts – настройки. el – контейнер, куда всё отрисовать.
  • 24. Для рендеринга в opts передаем функцию: renderTile: function(tile, path) { … return html; }, path содержит тройку индексов row, stack и tile – номер строчки, стопки и картинки в стопке. Использование
  • 26. Демка Тут можно подергать за рычажки: http://denull.github.io/Paver.JS/
  • 27. Конец первой части. Есть вопросы? Следующая часть начнется после перерыва.
  • 28. Часть 2. Об интернационализации (и локализации тоже) ● язык = ru, en ● локаль = ru_RU, en_US, en_GB ● перевод = отображение ключей на строки ● интернационализация = i18n = подготовка ● локализация = l10n = процесс перевода
  • 29. А нужны ли эти заморочки? Нужны. ● Задел на будущее. ● Избавление от «Найдено 21 фотографий». ● Возможность править тексты без правки шаблонов.
  • 30. Начнем с простого Все строки кладем в виде полей куда-нибудь в lang { … }, а потом достаем по lang[‘key’]. Сразу же хочется научиться делать подстановки (интерполировать) — пишем функцию: function T(key, substitute) { … }
  • 31. А что там с числами? Всё страшно. В каждом языке свои категории. До шести штук. ШЕСТИ, КАРЛ. http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
  • 32. Половой вопрос Тут чуть проще: только два случая (если не придираться). Придется спрашивать ещё одно поле при регистрации, зато никаких уродливых «Загрузил(а)».
  • 33. Число, род… и падеж, конечно Тут всё совсем плохо. Даже для одного языка фамилии склоняются по неоднозначно определенным правилам: Чаплин → Чаплином или Чаплиным? Повезло тем, у кого в языке падежей нет. Решение: Petrovich.js
  • 34. Работа с датами Тут всё чуть иначе: формат зависит от локали, а не от языка. Но от языка зависят фразы типа «3 часа назад», которые хорошо бы тоже уметь выводить с умом. Решение: moment.js, разумеется.
  • 35. Работа с числами Всё аналогично датам, только заморочек с выводом относительного времени нет. Решение: Numeral.js или сами фреймворки
  • 36. А как же .toLocaleString()? В ванильном JS есть: Date.prototype.toLocaleString() Number.prototype.toLocaleString() Есть давно, но настроить можно только с Chrome 24, FF 29, IE 11, Opera 15, а в Safari до сих пор нельзя.
  • 37. А неплохо бы ещё... ...вспомнить о типографских правилах. ● кроме «-» есть, как минимум, «—» и «–» ● кавычки бывают “тоже” «разные» ● автозамены: (c) , (r) , (tm) , ... ● и вообще много всего Решения: Типограф, mdash.ru, грамотность.
  • 38. Итого: Для i18n + l10n: ● l10n.js ● LocalePlanet ● L20n от Mozilla ● Moment.js – даты ● Numeral.js – числа ● Petrovich.js – имена ● Типограф – правила Ближе всего к тому, что надо: FormatJS.io и i18next.com (но все равно не идеально) +
  • 39. У всех свои форматы :( i18next: { en: { translation: { girlsAndBoys: '$t(girls, {"count": __girls__}) and __count__ boy', girlsAndBoys_plural: '$t(girls, {"count": __girls__}) and __count__ boys' }, girls: '__count__ girl', girls_plural: '__count__ girls' } } }; FormatJS: ‘You have {itemCount, plural, =0 {no items} one {1 item} other {{itemCount} items} }.’ Это хотя бы стандарт Message ICU Но он совсем адовый
  • 40. Хочется всего и сразу Но без излишеств (встроенного во фреймворки не хватает, тащить кучу библиотек ради базовых вещей грустно). К тому же, вещи реально тесно связанные. Склонять имена вообще все боятся.
  • 41. Мое решение? Да, ещё один велосипед. С блекджеком и своим форматом шаблонов. T.js https://github.com/deNULL/T.js
  • 42. Это почти как шаблонизатор, но нет photos: 'фотографий', liked: 'оценил', user_liked: '{user} {>liked} {photos} {>photos}', Делаем: T(‘user_liked’, {user: ’Олег’, photos: 5}) и получаем: ‘Олег оценил 5 фотографий’. Подставили входные данные + другие ключи.
  • 43. Структура языковых данных T.define({ ru: { key1: ‘str1’, key2: ‘str2’, key3: { subkey: { subsubkey: ‘wow’ } }, }}) Можно вызывать сколько угодно раз. Вложенность любая. Достаем через точку: T(‘key3.subkey.subsubkey’)
  • 44. А что с числами? Чтобы не было ‘Олег оценил 1 фотографий’: photos: { $plural: { one: ‘фотографию’, few: ‘фотографии’, other: ‘фотографий’ }} Категории зависят от языка, есть поддержка ru/en. Можно добавить свою функцию определения категории.
  • 45. А если не Олег, а Анна? liked: { $gender: { m: ‘оценил’, f: ‘оценила’ }} Аналогично, но надо передавать пол как параметр в подставляемый шаблон: user_liked: ‘… {>user.name user.gender} …’ T(‘user_liked’, { user: { name: ‘Анна’, gender: ‘f’});
  • 46. А добавить «... Ильи» в конце? user_liked: ‘… {$name.gen whom.name}’ = вызов функции $name с первым параметром whom.name, вторым — ‘gen’ (родительный падеж). Есть внутренние функции $name, $surname, $patronym для русского, их можно доопределить или переопределить.
  • 47. Что за «вызов функции»? Функция = шаблон. Подставить шаблон = вызвать функцию. Если имя функции или шаблона начинается с $, то при подстановке > не нужен ({>$some} = {$some}). То, что после точек (func.p1.p2) интерпретируется как дополнительные параметры.
  • 48. Бонус: трансформации Пишем: user: ‘пользователь’ Получаем: T(‘user’) => ‘пользователь’ T(‘User’) => ‘Пользователь’ T(‘USER’) => ‘ПОЛЬЗОВАТЕЛЬ’ Непривычно, но может быть удобно.
  • 49. И внезапно — инлайн-перевод T.inlineTranslation(true); TA-DA! Все строки кликабельны и открывают окошко с текстом перевода. Сохранение изменений (и проверка прав) на сервере — лежит на вас. T.showAllKeys(); Показать вообще все ключики списком.
  • 50. Такая вот красота Это всё без дополнительных зависимостей. Можно и вырезать, если юзер не переводчик.
  • 51. К слову T(‘user!’) — Локально отключить инлайн. Инлайн-перевод генерит HTML — в шаблонизаторы надо подставлять результат в сыром виде (Angular: $sce + ng-bind-html). Во входных данных эскейпятся < и > – а в самих переводах нет, будьте внимательны.
  • 52. Чего пока нет ● форматирование дат ({$date …}) ● форматирование чисел ({$num …}) Под некоторым сомнением: применение типографских правил.
  • 53. Конец второй части. Есть вопросы? Денис Ольшин http://vk.com/denull