Oleksii Vasyliev, Railsware
Brought to you by Alexey Vasiliev, Railsware
adapting computer software to different languages, regional peculiarities and technical requirements of a target locale
en:
errors:
format: "%{attribute} %{message}"
messages:
model_invalid: "Validation failed: %{errors}"
Let's translate "Press":
Russian example: "Мама мыла раму"
Latin
Spiritus quidem promptus est, caro autem infirma
Literal translation
Alcohol is good, but rotten meat (Russian: "Спирт хорош, а мясо протухло")
Correct translation
The spirit is vigorous, but the flesh is weak (Russian: "Дух бодр, плоть же немощна")
en:
about:
link_text: "Press here"
en:
about_page:
link_text_for_getting_info_about_privacy_policy_details:
"Press here"
#!/bin/bash
echo -n 'Extracting strings from Rails app...'
bundle exec rake gettext:find > /dev/null 2>&1
echo ' Done!'
echo -n 'Adding missing SPA locale entrypoint files...'
yarn gulp locale:spa > /dev/null 2>&1
echo ' Done!'
echo -n 'Extracting strings from SPA...'
yarn gulp build:pot > /dev/null 2>&1
make spa > /dev/null 2>&1
echo ' Done!'
namespace :gettext do
def files_to_translate
Dir.glob("{app,lib,config,locale}/**/*.{rb,erb,haml,rabl}")
end
end
gulp.task('build:pot', function() {
return gulp.src('webpack/**/*.js*')
.pipe(reactGettextParser({
output: 'spa.pot',
funcArgumentsMap: {
__: ['msgid'],
n__: ['msgid', 'msgid_plural'],
p__: ['msgctxt', 'msgid'],
np__: ['msgctxt', 'msgid', 'msgid_plural']
}
}))
.pipe(gulp.dest('locale'));
});
// webpack
externals: {
__i18n: 'i18n'
}
// gulp
const template = _template(`
import Jed from 'jed';
import messages from '../../locale/<%= lang %>/spa.po';
const i18n = new Jed(messages);
window.i18n = i18n;
`.trim().concat('\n')
);
// code
import i18n from '__i18n';
export const __ = function() {
return i18n.gettext.apply(i18n, arguments);
};
export const n__ = function() {
return i18n.ngettext.apply(i18n, arguments);
};
export const p__ = function() {
return i18n.pgettext.apply(i18n, arguments);
};
export const np__ = function() {
return i18n.npgettext.apply(i18n, arguments);
};
import locale from 'react-native-locale-detector';
import {en, fr, ru} from 'locale';
let messages;
if (/^ru/.test(locale)) {
messages = ru;
} else if (/^fr/.test(locale)) {
messages = fr;
} else {
messages = en;
}
_('N/A')
N_('Car', '%{n} Cars', 2) % { n: count } == '2 Autos'
slug = obj.new_record? ? _('Create %{resource}') : _('Update %{resource}')
slug % {resource: resource_name}
P_('Context', 'not-found') == 'not-found'
S_('Context|not-found') == 'not-found'
PN_('Fruit', 'Apple', 'Apples', 3) == 'Äpfel'
PN_('Fruit', 'Apple', 'Apples', 1) == 'Apfel'
%html{lang: FastGettext.locale}
day.localize(FastGettext.locale).to_additional_s('Ed')
def date_long_label(date)
date.to_date.localize(FastGettext.locale).to_additional_s('MMMMd')
end
def date_short_label(date)
date.to_date.localize(FastGettext.locale).to_additional_s('MMMd')
end
// react
<ActionButton
label={__('Deselect')}
onClick={onDeselectClick} />
{
isLoading &&
<Loader
text={__('Please wait data are loading…')}/>
}
i18n.translate("There is one translation.")
.onDomain("messages")
.withContext("male")
.ifPlural(num, "There are %d translations.")
.fetch(num);
moment.locale(this.getLocale());
moment(date).format(dateFormat.toString());
moment(currentDate).subtract(offset, 'days').format('YYYY-MM-DD')
Alcohol consumption is prohibited in Islam