Comments 18
Немного риторики — как дела с доменами, контекстами, множественными числами? (Хотя из кода вижу, что никак) Ну и конвертить PO онлайн — должно быть очень удобно для билда проектов.
+3
Я же и прокомментировал в конце статьи, что жду от вас всех пожеланий и нужд. По поводу конвертации, я всё равно перед тем как залить на сервер запускаю POEdit, и он создает .mo файл. Но видел решения автоматической генерации перевода на сервере. Думаю, туда несложно добавить автоматическое создание JSON-файла. Просто относится ли это к этой библиотеке или нет? Если вы считаете, что да, то как вы видите это процесс? Спасибо.
0
Вы можете просто сделать эту фичу отдельный модулем. Кому будет нужно — тот подключит.
0
Всё верно, я так уже и планирую. Просто в каком виде? Это будет bash скрипт или php скрипт (второе больше по душе).
0
PHP, наверное, будет лучше тем, что более кроссплатформенно получится, чем баш.
-3
т.е. господа минусующие хотят сказать, что баш скрипт проще будет запустить под Windows, чем PHP?
-3
Скорее всего да. Bash поставить на Windows — раз плюнуть (и если вы более-менее серьезный разработчик, то он у вас уже есть), а разбираться с подключением PHP — это отдельный гемор если у вас серверная часть на другом языке.
0
Joshua I. Miller в свое время написал отличнейший порт GNU gettext-a, тут есть его копия — phpxref.pagelines.com/nav.html?dms/editor/js/Gettext.js.source.html. Там можете найти много интересного. У себя на проекте используем именно этот модуль.
С файлами локализации у нас работают документаторы, через POEdit. На выходе получаем .po файлы, которые вышеупомянутой библиотекой конвертируем в .json, во время билда. В клиент подтягиваем уже скомпиленый .json, который внедряется в код урезанной версией Gettext-а.
При этом сохранены все доступные методы GNU.
С файлами локализации у нас работают документаторы, через POEdit. На выходе получаем .po файлы, которые вышеупомянутой библиотекой конвертируем в .json, во время билда. В клиент подтягиваем уже скомпиленый .json, который внедряется в код урезанной версией Gettext-а.
При этом сохранены все доступные методы GNU.
0
>Первым делом я искал, как же в JS прочитать PO-файлы. Можно парсить, но это лишняя нагрузка, поэтому я решил не насиловать JavaScript и отдавать ему уже готовый JSON.
Я бы всё-таки подумал о том, чтобы добавить парсер po->json в библиотеку. Во многих случаях вполне допустимо потратить сотню миллисекунд на парсинг po-файла, особенно если он происходит уже после DOM Ready.
Имхо, это тот случай, когда можно разгрузить сервер и отдать работу клиенту.
Обычно po-файлы меняются не так часто, но не у всех настроены всякие билд-скрипты, которые автоматически смогут перевести po во json при изменении перевода, и возможность прямой загрузки po может помочь некоторым будущим пользователям вашей библиотеки.
Я бы всё-таки подумал о том, чтобы добавить парсер po->json в библиотеку. Во многих случаях вполне допустимо потратить сотню миллисекунд на парсинг po-файла, особенно если он происходит уже после DOM Ready.
Имхо, это тот случай, когда можно разгрузить сервер и отдать работу клиенту.
Обычно po-файлы меняются не так часто, но не у всех настроены всякие билд-скрипты, которые автоматически смогут перевести po во json при изменении перевода, и возможность прямой загрузки po может помочь некоторым будущим пользователям вашей библиотеки.
0
Для более менее серьезных проектов файл .po может быть немаленьким. И конвертация на клиенте может занять неприятное время. Но я согласен с вами, парсинг нужно добавить, но он должен происходить или во время билда, или на сервере при загрузке страницы. Дело в том, что хотелось бы какое-то универсальное решение. Я могу написать парсер на PHP, но что, если проект на Python или Ruby?
0
поэтому я и говорю — парсер на js на клиенте. Укажите в документации, что гораздо лучше иметь заранее созданный json на сервере, но дайте и возможность автоматического подключения po-файла. Не все из тех, что хочет переводы, имеют инфраструктуру на сервере, и им придётся вручную запускать создание json-а.
Но смотрите сами. Вы просили улучшения, я считаю, что количество пользователей эта функция увеличит. Но решать вам. Если вы считаете архитектурно неправильным парсить на клиенте, то так и быть. Вон, твиттер пытался сделать шаблонизацию на клиенте, а потом отказался и стал с сервера выдавать готовый html.
Но смотрите сами. Вы просили улучшения, я считаю, что количество пользователей эта функция увеличит. Но решать вам. Если вы считаете архитектурно неправильным парсить на клиенте, то так и быть. Вон, твиттер пытался сделать шаблонизацию на клиенте, а потом отказался и стал с сервера выдавать готовый html.
0
Без поддержки числительных и контекста это несерьезно, в любом сколько-либо крупном проекте это требуется. Ну и интерфейс не-gettext совместимый уже сейчас.
Солидарен с комментатором выше по поводу кода: зачем дикой частоты интервал, там где всего один раз должен сработать коллбек после загрузки файла? Да и односимвольные переменные (как и underscore-префикс для всего подряд) не добавляют читаемости, оставьте эту работу минимизатору.
(Промахнулся веткой комментариев, хотел на первом уровне написать)
Солидарен с комментатором выше по поводу кода: зачем дикой частоты интервал, там где всего один раз должен сработать коллбек после загрузки файла? Да и односимвольные переменные (как и underscore-префикс для всего подряд) не добавляют читаемости, оставьте эту работу минимизатору.
(Промахнулся веткой комментариев, хотел на первом уровне написать)
0
Гдето с месяц назад тоже искал (js based) i18n тулзу для своего проекта. В общем в финальном раунде сравнения победил i18next. Среди участников также были
0
Отличный метод…
Да еще и несоблюдение JS стандартов.
ready: function(cb) {
var _t = this, i = setInterval(function() {
if (_t._r) {
cb();
clearInterval(i);
}
}, 10);
},
Да еще и несоблюдение JS стандартов.
+1
Я понимаю, что вы гуру и вам достаточно написать саркастическое словосочетание. Но знаете что, отвергая, предлагай. Не все мы пишем идеальный код. На вашем месте я бы лучше поделился опытом и объяснил, что в этой функции не так.
+1
Писал с iPad, ночью, по-этому так «сухо». Сейчас попробую все разжевать.
Во-первых, не i18n (internationalization), а всего лишь i10n (localization). Не путайте.
Во-вторых, на GitHub у вас написанно:
В-третьих, у инструментов, перечисленных вверху поста, нет зависимостей. Библиотека/фреймворк, под которую написан плагин/дополнение не может быть зависимостью, а только ноборот.
P.S. Создал pull request на GitHub.
Во-первых, не i18n (internationalization), а всего лишь i10n (localization). Не путайте.
Во-вторых, на GitHub у вас написанно:
Super-simple gettext translation in pure JSи, хочу я сказать, что Gettext тут не при чем.
В-третьих, у инструментов, перечисленных вверху поста, нет зависимостей. Библиотека/фреймворк, под которую написан плагин/дополнение не может быть зависимостью, а только ноборот.
Код вашей библиотеки с моими комментариями
// Неправильное определение переменной: нет ключевого
// слова "var" - несоблюдение строгих стандартов JS.
pojs = {
// Непонятное имя свойства
_l: null,
// Непонятное имя свойства
_r: false,
// Непонятное имя свойства
_p: {},
// Непонятное имя параметра
init: function(l) {
this._l = l;
this._load();
},
_: function(key, args) {
// Избыточное выражение.
// Проще:
// this._p[key] || key
//
// Неправильное форматирование кода. Не только здесь, повсеместно.
// Рекомендую к прочтению JS Style Guide: https://github.com/BR0kEN-/javascript
//
// В данном случае лучше так:
// var t = this._p[key] || key,
// a;
var t = this._p.hasOwnProperty(key) ? this._p[key] : key, a;
// Неправильная проверка. "args" может быть строкой и удовлетворять условие.
// Пример:
// var args = 'string';
//
// if (args) {
// for (var arg in args) {
// // args[arg] = s
// // args[arg] = t
// // args[arg] = r
// // args[arg] = i
// // args[arg] = n
// // args[arg] = g
// }
// }
if (args) {
for (a in args) {
t = t.replace(/%s/, args[a]);
}
}
return t;
},
// Неправильный подход. Необходимо использовать
// событие "load" для XMLHttp объекта.
//
// Отсутствие проверки на тип.
// Пример:
// pojs.ready('fucking code');
// Uncaught TypeError: string is not a function
ready: function(cb) {
var _t = this, i = setInterval(function() {
if (_t._r) {
cb();
clearInterval(i);
}
}, 10);
},
_load: function() {
// "'localStorage' in window" и "window['localStorage'] !== null" - одно и то же.
var _t = this, x, lsa = 'localStorage' in window && window['localStorage'] !== null, cache = null;
if (_t._l) {
if (lsa) {
cache = localStorage.getItem('pojs_' + _t._l);
if (cache) {
_t._p = JSON.parse(cache);
_t._r = true;
return;
}
}
x = new XMLHttpRequest();
x.onreadystatechange = function() {
// Избыточная вложенность и неправильное обращение к объекту.
//
// Выражение записывается так:
// if (this.readyState === 4 && this.status === 200) {
// // actions
// }
//
// Или же еще проще:
// if (this.response) {
// // actions
// }
//
// Помимо этого, в IE8, данный код обрастет ошибками:
// - отсутствие объекта XMLHttpRequest;
// - отсутствие объекта console.
if (x.readyState === 4) {
if (x.status === 200) {
// Выше, почему-то, есть проверка на существование
// localStorage, а тут подразумевается что объект
// будет во что бы то ни стало?
localStorage.setItem('pojs_' + _t._l, x.responseText);
_t._p = JSON.parse(x.responseText);
} else {
console.error('Can not load JSON from ' + _t._l);
}
_t._r = true;
}
};
x.open('GET', this._l, true);
x.send();
} else {
_t._r = true;
}
}
};
P.S. Создал pull request на GitHub.
+2
Как это обычно бывает, все уже написано, оттестировано, проверено на продакшене. github.com/socialabs/puttext
0
Sign up to leave a comment.
po.js — супер простая утилита для i18n