Rrule: toText์˜ i18n์— ๋Œ€ํ•œ ๋ฌธ์„œ

์— ๋งŒ๋“  2013๋…„ 04์›” 17์ผ  ยท  15์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: jakubroztocil/rrule

toText() ๋ฉ”์†Œ๋“œ์˜ i18n์— ๋Œ€ํ•œ ๋” ๋‚˜์€ ๋ฌธ์„œ๋ฅผ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.

  1. today ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์˜๋ฏธ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?
  2. gettext ์ „๋‹ฌ๋˜๋Š” ๊ฐ’์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?
  3. ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ๋ฒˆ์—ญํ•ฉ๋‹ˆ๊นŒ? dayNames ๋ฐ monthNames ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Š” ์ผ๋ถ€์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

enhancement

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ํ…์ŠคํŠธ๋ฅผ ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๋ฒˆ์—ญํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๋ชจ๋“  15 ๋Œ“๊ธ€

์˜ค๋Š˜ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์˜๋ฏธ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

ํ˜„์žฌ๋กœ์„œ๋Š” ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋˜์ง€ ์•Š์œผ๋ฉฐ null ์ „๋‹ฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์–ด๋–ค ๊ฐ’์ด gettext์— ์ „๋‹ฌ๋ฉ๋‹ˆ๊นŒ?
์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ๋ฒˆ์—ญํ•ฉ๋‹ˆ๊นŒ? ๋‚˜๋Š” dayNames ๋ฐ monthNames๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Š” ๊ทธ ์ผ๋ถ€์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

API๋Š” ๊ทธ๋‹ค์ง€ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚ ์งœ ๊ด€๋ จ ํ•ญ๋ชฉ์œผ๋กœ ์–ธ์–ด ์ •์˜๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ์˜์–ด๋Š” ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค . tokens ๋Š” RRule.fromText ์—๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

gettext ๋Š” ์˜์–ด ๋ฌธ์ž์—ด์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค( ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉ๋œ ๋ฌธ์ž์—ด์„ ๋ณผ ์ˆ˜ ์žˆ์Œ).

์กฐ์žกํ•œ ์˜ˆ(ํ˜„์žฌ ๋งˆ์Šคํ„ฐ๊ฐ€ ํ•„์š”ํ•˜๊ณ  ์ด์ „ ๋ฒ„์ „์€ toText ์˜ ์ถœ๋ ฅ์„ ์บ์‹œํ•จ):

// Date-related translations
var portuguese = {
    dayNames: [
        "Domingo",
        "Segunda-Feira",
        "Terรงa-feira",
        "Quarta-feira",
        "Quinta-feira",
        "Sexta-feira",
        "Sรกbado"
    ],
    monthNames: [
        "Janeiro",
        "Fevereiro",
        // โ€ฆ
    ]
    // `tokens` are only needed for `RRule.fromText`

};


// Strings
var portugueseStrings = {
    'every': 'cada',
    'until': 'atรฉ',
    'day': 'dia',
    'days': 'dias',
    'week': 'semana',
    'weeks': 'semanas',
    'on': 'em'
    // โ€ฆ
};

var gettext =  function(id) {
    // Return pt. string, default to english.
    return portugueseStrings[id] || id;
};


var rule = new RRule(RRule.WEEKLY, {
    interval: 5,
    byweekday: [RRule.MO, RRule.FR],
    dtstart: new Date(2012, 1, 1, 10, 30),
    until: new Date(2012, 12, 31)
});

console.log(rule.toText());
// => every 5 weeks on Monday, Friday until January 31, 2013

console.log(rule.toText(null, gettext, portuguese));
// => cada 5 semanas em Segunda-Feira, Sexta-feira atรฉ Janeiro 31, 2013

TODO: API๋ฅผ ๊ฐœ์„ ํ•˜๊ณ  ๋ฌธ์„œํ™”ํ•ฉ๋‹ˆ๋‹ค( Language ํด๋ž˜์Šค๊ฐ€ ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค).

API๋Š” ๊ทธ๋‹ค์ง€ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ , ๊ทธ๋ž˜. ๋น ์ง„ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์–ด๋งŒ ๋ฒˆ์—ญํ•  ์ˆ˜๋Š” ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์–ธ์–ด์— ๋”ฐ๋ผ ๋ฌธ๋ฒ•๋„ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์ˆœ์„œ๋„ ๋ฐ”๊ฟ”์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•์‹ ๋ฌธ์ž์—ด์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

singular: 'every week on {{dayNames}}',
plural: 'every {{numWeeks}} weeks on {{dayNames}}'

๊ทธ๊ฒƒ์€ ๋‹จ์ง€ ๊ฑฐ์นœ ์˜ˆ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋งŽ์€ ๊ทน๋‹จ์ ์ธ ๊ฒฝ์šฐ ๋“ฑ์ด ์žˆ๊ณ  ์•„๋งˆ๋„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐฉ๊ธˆ https://github.com/airbnb/polyglot.js ๋ฅผ ์ฐพ์•˜์ง€๋งŒ i18n์— ๋Œ€ํ•œ ๋‹ค๋ฅธ ๋งŽ์€ ์†”๋ฃจ์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋ฅผ ๋ฌผ๋ฆฐ ๊ฒƒ :

์˜์–ด๋กœ "๋งค์ฃผ"์™€ "๋งค์›”"์ž…๋‹ˆ๋‹ค. ๋…์ผ์–ด๋กœ "jede Woche"์™€ "jeden Monat"์ž…๋‹ˆ๋‹ค. "n"์— ์ฃผ๋ชฉํ•˜์‹ญ์‹œ์˜ค. "๋ชจ๋“ "์„ ๋ฒˆ์—ญํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

gettext์— "st" ๋˜๋Š” "rd"๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์•„๋ฌด ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์†Œ์‹์ด๋‚˜ ๊ณ„ํš์ด ์žˆ๋‚˜์š”? ์ด์ œ DTSTART ๋ฐ UNTIL ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์œผ๋ฏ€๋กœ ๋” ์ด์ƒ toText ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ ์ „์—๋Š” ํ˜„์žฌ ๊ตฌํ˜„์„ ํ•ดํ‚นํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋ชฉ๋ก์— ๋Œ€ํ•œ ํ•œ ๊ฐ€์ง€ ๋”: ๋‚ ์งœ ํ˜•์‹. ๋‚˜๋Š” DD.MM.YYYY ๊ฐ€ ์•„๋‹ˆ๋ผ MMMM DD, YYYY ์›ํ•ฉ๋‹ˆ๋‹ค.

์ดํ•ด๊ฐ€ ์•ˆ ๋ผ์š”. ํ•˜๋‚˜์˜ html ํŒŒ์ผ์—๋Š” ์ตœ์‹  ๋ฆด๋ฆฌ์Šค(2.0)๊ฐ€ ํฌํ•จ๋œ ์ด ์ฝ”๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

[์•”ํ˜ธ]

๋ฌด์—ญ ํ…Œ์ŠคํŠธ

[/์•”ํ˜ธ]
๋‹ค์Œ ์˜ค๋ฅ˜์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

TypeError: _์ด(๊ฐ€) ์ •์˜๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
var ๊ธฐ๋ณธ๊ฐ’ = _.clone(RRule.DEFAULT_OPTIONS);
463ํ–‰์˜ ๊ทœ์น™์—์„œ.

๋‚ด๊ฐ€ ์ž˜๋ชปํ•œ ๋ถ€๋ถ„์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

underscorejs๋ผ๋Š” ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ „ํ™”๋ฅผ ๋ฐ›๊ณ  ์žˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‚ด๊ฐ€ ๋‹น์‹ ์—๊ฒŒ ๋งํฌ๋ฅผ ์ฃผ์—ˆ์„ ๊ฒƒ์ด๋‹ค.

2013๋…„ 10์›” 30์ผ ์˜คํ›„ 11์‹œ 54๋ถ„์— elecoest [email protected]์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

์ดํ•ด๊ฐ€ ์•ˆ ๋ผ์š”. ํ•˜๋‚˜์˜ html ํŒŒ์ผ์—๋Š” ์ตœ์‹  ๋ฆด๋ฆฌ์Šค(2.0)๊ฐ€ ํฌํ•จ๋œ ์ด ์ฝ”๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌด์—ญ ํ…Œ์ŠคํŠธ
์˜ค๋ฅ˜์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

TypeError: _์ด(๊ฐ€) ์ •์˜๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

var ๊ธฐ๋ณธ๊ฐ’ = .clone(RRule.DEFAULTOPTIONS);
463ํ–‰์˜ ๊ทœ์น™์—์„œ.

๋‚ด๊ฐ€ ์ž˜๋ชปํ•œ ๋ถ€๋ถ„์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

โ€”
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ฑฐ๋‚˜ GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.

์ข‹์•„, ์„ธ ๋ฒˆ์งธ ์œ„์น˜์— undesrcore.js๋ฅผ ๋ฐฐ์น˜ํ–ˆ์Šต๋‹ˆ๋‹ค...
๋‚˜๋Š” underscore.js๋ฅผ ์ฒซ ๋ฒˆ์งธ ์œ„์น˜์— ๋ฐฐ์น˜ํ–ˆ์Šต๋‹ˆ๋‹ค.
์ด์ œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.
TypeError: 2๋Š” ๊ฐ์ฒด๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.
return result.call(this, func.apply(_, args));
underscore.js์—์„œ

์ฃ„์†กํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•์ด ๋ชจ๋“  ์‹ ์ฒด์— ์ ํ•ฉํ•ฉ๋‹ˆ๊นŒ?

์•„๋ฌด๋„ ์ „์—์ด ์˜ค๋ฅ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

๋„์™€ ์ฃผ์…”์„œ ์ •๋ง๋กœ ๊ณ ๋ง™์Šต๋‹ˆ๋‹ค.

์˜ค๋Š˜ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์˜๋ฏธ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

ํ˜„์žฌ๋กœ์„œ๋Š” ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋˜์ง€ ์•Š์œผ๋ฉฐ null ์ „๋‹ฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์–ด๋–ค ๊ฐ’์ด gettext์— ์ „๋‹ฌ๋ฉ๋‹ˆ๊นŒ?
์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ๋ฒˆ์—ญํ•ฉ๋‹ˆ๊นŒ? ๋‚˜๋Š” dayNames ๋ฐ monthNames๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Š” ๊ทธ ์ผ๋ถ€์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

API๋Š” ๊ทธ๋‹ค์ง€ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚ ์งœ ๊ด€๋ จ ํ•ญ๋ชฉ์œผ๋กœ ์–ธ์–ด ์ •์˜๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ์˜์–ด๋Š” ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค . tokens ๋Š” RRule.fromText ์—๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

gettext ๋Š” ์˜์–ด ๋ฌธ์ž์—ด์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค( ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉ๋œ ๋ฌธ์ž์—ด์„ ๋ณผ ์ˆ˜ ์žˆ์Œ).

์กฐ์žกํ•œ ์˜ˆ(ํ˜„์žฌ ๋งˆ์Šคํ„ฐ๊ฐ€ ํ•„์š”ํ•˜๊ณ  ์ด์ „ ๋ฒ„์ „์€ toText ์˜ ์ถœ๋ ฅ์„ ์บ์‹œํ•จ):

// Date-related translations
var portuguese = {
    dayNames: [
        "Domingo",
        "Segunda-Feira",
        "Terรงa-feira",
        "Quarta-feira",
        "Quinta-feira",
        "Sexta-feira",
        "Sรกbado"
    ],
    monthNames: [
        "Janeiro",
        "Fevereiro",
        // โ€ฆ
    ]
    // `tokens` are only needed for `RRule.fromText`

};


// Strings
var portugueseStrings = {
    'every': 'cada',
    'until': 'atรฉ',
    'day': 'dia',
    'days': 'dias',
    'week': 'semana',
    'weeks': 'semanas',
    'on': 'em'
    // โ€ฆ
};

var gettext =  function(id) {
    // Return pt. string, default to english.
    return portugueseStrings[id] || id;
};


var rule = new RRule(RRule.WEEKLY, {
    interval: 5,
    byweekday: [RRule.MO, RRule.FR],
    dtstart: new Date(2012, 1, 1, 10, 30),
    until: new Date(2012, 12, 31)
});

console.log(rule.toText());
// => every 5 weeks on Monday, Friday until January 31, 2013

console.log(rule.toText(null, gettext, portuguese));
// => cada 5 semanas em Segunda-Feira, Sexta-feira atรฉ Janeiro 31, 2013

TODO: API๋ฅผ ๊ฐœ์„ ํ•˜๊ณ  ๋ฌธ์„œํ™”ํ•ฉ๋‹ˆ๋‹ค( Language ํด๋ž˜์Šค๊ฐ€ ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค).

์•ˆ๋…•ํ•˜์„ธ์š”, ๋…์ผ์–ด์šฉ i18n์„ ๊ตฌํ•˜๋ ค๊ณ  ํ•˜๋Š”๋ฐ ๋งํฌ๊ฐ€ ๋Š์–ด์ ธ "gettext"์— ์‚ฌ์šฉ๋œ ๋ฌธ์ž์—ด์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ถœ์ฒ˜๋ฅผ ์ฐพ์•„๋ณด๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ๋ญ๋“ ์ง€ ์ฐพ์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ฐ์‚ฌ ํ•ด์š”!

์˜ค๋Š˜ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์˜๋ฏธ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

ํ˜„์žฌ๋กœ์„œ๋Š” ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋˜์ง€ ์•Š์œผ๋ฉฐ null ์ „๋‹ฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์–ด๋–ค ๊ฐ’์ด gettext์— ์ „๋‹ฌ๋ฉ๋‹ˆ๊นŒ?
์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ๋ฒˆ์—ญํ•ฉ๋‹ˆ๊นŒ? ๋‚˜๋Š” dayNames ๋ฐ monthNames๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Š” ๊ทธ ์ผ๋ถ€์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

API๋Š” ๊ทธ๋‹ค์ง€ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋‚ ์งœ ๊ด€๋ จ ํ•ญ๋ชฉ์œผ๋กœ ์–ธ์–ด ์ •์˜๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ์˜์–ด๋Š” ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค . tokens ๋Š” RRule.fromText ์—๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
gettext ๋Š” ์˜์–ด ๋ฌธ์ž์—ด์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค( ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉ๋œ ๋ฌธ์ž์—ด์„ ๋ณผ ์ˆ˜ ์žˆ์Œ).
์กฐ์žกํ•œ ์˜ˆ(ํ˜„์žฌ ๋งˆ์Šคํ„ฐ๊ฐ€ ํ•„์š”ํ•˜๊ณ  ์ด์ „ ๋ฒ„์ „์€ toText ์˜ ์ถœ๋ ฅ์„ ์บ์‹œํ•จ):

// Date-related translations
var portuguese = {
    dayNames: [
        "Domingo",
        "Segunda-Feira",
        "Terรงa-feira",
        "Quarta-feira",
        "Quinta-feira",
        "Sexta-feira",
        "Sรกbado"
    ],
    monthNames: [
        "Janeiro",
        "Fevereiro",
        // โ€ฆ
    ]
    // `tokens` are only needed for `RRule.fromText`

};


// Strings
var portugueseStrings = {
    'every': 'cada',
    'until': 'atรฉ',
    'day': 'dia',
    'days': 'dias',
    'week': 'semana',
    'weeks': 'semanas',
    'on': 'em'
    // โ€ฆ
};

var gettext =  function(id) {
    // Return pt. string, default to english.
    return portugueseStrings[id] || id;
};


var rule = new RRule(RRule.WEEKLY, {
    interval: 5,
    byweekday: [RRule.MO, RRule.FR],
    dtstart: new Date(2012, 1, 1, 10, 30),
    until: new Date(2012, 12, 31)
});

console.log(rule.toText());
// => every 5 weeks on Monday, Friday until January 31, 2013

console.log(rule.toText(null, gettext, portuguese));
// => cada 5 semanas em Segunda-Feira, Sexta-feira atรฉ Janeiro 31, 2013

TODO: API๋ฅผ ๊ฐœ์„ ํ•˜๊ณ  ๋ฌธ์„œํ™”ํ•ฉ๋‹ˆ๋‹ค( Language ํด๋ž˜์Šค๊ฐ€ ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค).

์•ˆ๋…•ํ•˜์„ธ์š”, ๋…์ผ์–ด์šฉ i18n์„ ๊ตฌํ•˜๋ ค๊ณ  ํ•˜๋Š”๋ฐ ๋งํฌ๊ฐ€ ๋Š์–ด์ ธ "gettext"์— ์‚ฌ์šฉ๋œ ๋ฌธ์ž์—ด์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ถœ์ฒ˜๋ฅผ ์ฐพ์•„๋ณด๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ๋ญ๋“ ์ง€ ์ฐพ์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ฐ์‚ฌ ํ•ด์š”!

https://github.com/jakubroztocil/rrule/tree/master/src/nlp

์‚ฌ์šฉ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ฌธ์„œ๊ฐ€ ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋…์ผ์–ด๋กœ ๋ฒˆ์—ญํ–ˆ์ง€๋งŒ ์ž˜๋ชป๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

const germanStrings = {
    every: 'jedes',
    until: 'bis',
    day: 'Tag',
    days: 'Tage',
    week: 'Woche',
    weeks: 'Wochen',
    on: 'ein',
    in: 'in',
    'on the': 'auf dem',
    for: 'fรผr',
    and: 'und',
    or: 'oder',
    at: 'bei',
    last: 'zuletzt',
    '(~ approximate)': '(~ approximativ)',
    times: 'Zeiten',
    time: 'Zeit',
    minutes: 'Minuten',
    hours: 'Stunden',
    weekdays: 'Wochentage',
    weekday: 'Wochentag',
    months: 'Monate',
    month: 'Monat',
    years: 'Jahre',
    year: 'Jahr'
  };
const RRULE_GERMAN = {
  dayNames: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
  monthNames: [
    'Januar',
    'Februar',
    'Mรคrz',
    'April',
    'Mai',
    'Juni',
    'Juli',
    'August',
    'September',
    'Oktober',
    'November',
    'Dezember'
  ]
};
const gettext = id => {
    return germanStrings[id] || id;
};

const rruleText = rule.toText(id => {
    gettext(id);
}, RRULE_GERMAN);

์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ํ…์ŠคํŠธ๋ฅผ ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๋ฒˆ์—ญํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ i18n์€ ํ˜„์žฌ๋กœ์„œ๋Š” ๊ทผ๋ณธ์ ์œผ๋กœ ๊ฒฐํ•จ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ๊ฒƒ๋“ค

nth_monthday' => array(
        '1' => 'the 1st',
        '2' => 'the 2nd',
        '3' => 'the 3rd',
        '21' => 'the 21st',
        '22' => 'the 22nd',
        '23' => 'the 23rd',
        '31' => 'the 31st',
        'else' => 'the %{n}th'
    ),

๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๋œ ์ผ๋ถ€ ์ตœ์ข… ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ์‚ฌ์šฉ์— ์ ˆ๋Œ€์ ์œผ๋กœ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋Œ€์•ˆ์—์„œ ๋…ผ๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค( ์ด ๊ฒŒ์‹œ๋ฌผ์—์„œ @wakirin ์ด ์–ธ๊ธ‰ํ•จ). ํ˜„์žฌ ์ด ๋กœ์ง์€ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ i18n ๋กœ์ง์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์ˆ˜๋™์œผ๋กœ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‚ฌ์šฉ์„ ์‹ค์ œ๋กœ ์ฆ๊ฐ€์‹œํ‚ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ: ์ฝ”๋“œ๋ฅผ ํฌ๋กค๋งํ•œ ํ›„ ์›ํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. ๋‚ด ์–ธ์–ด๋กœ "ํ•ด๊ฒฐ"๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜์ค‘์— ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋„๋ก ์ „๋‹ฌํ•˜๋Š” getText ๋ฉ”์„œ๋“œ์—์„œ ๋ฒˆ์—ญํ•ด์•ผ ํ•˜๋Š” ๋ชจ๋“  ํ‚ค ๋ชฉ๋ก์„ ์—ฌ๊ธฐ์— ๋‚จ๊ฒจ ๋‘ก๋‹ˆ๋‹ค.

 '(~ approximate)'
 'and'
 'at'
 'day'
 'days'
 'every'
 'for'
 'hour'
 'hours'
 'in'
 'last'
 'minutes'
 'month'
 'months'
 'nd'
 'on the'
 'on'
 'or'
 'rd'
 'st'
 'th'
 'the'
 'time'
 'times'
 'until'
 'week'
 'weekday'
 'weekdays'
 'weeks'
 'weeks'
 'year'
 'years'
 'RRule error: Unable to fully convert this rrule to text'

@gongAll ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
๊ท€ํ•˜์˜ ์˜ˆ๋ฅผ ํ†ตํ•ด ์•„๋ž˜์™€ ๊ฐ™์ด moment.js ๋ฐ i18n ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

export const RRuleToText = ({ strRRule }) => {
  const language = {
    dayNames: moment.weekdays(),
    monthNames: moment.months()
  };

  const getText = id => {
    return i18n.t(`vendor.rrule.${id}`, id);
  };

  const dateFormat = (year, month, day) =>
    moment()
      .date(day)
      .year(year)
      .month(month)
      .format("LL");

  return strRRule
    ? capitalize(
        RRule.fromString(strRRule).toText(getText, language, dateFormat)
      )
    : "";
};

์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์ผ๋ณธ์–ด๋กœ ๋ฒˆ์—ญํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์–ด ์ˆœ์„œ๊ฐ€ ํ™•์—ฐํžˆ ๋‹ฌ๋ผ์„œ ์–ด๋–ป๊ฒŒ ์ง„ํ–‰ํ•ด์•ผํ• ์ง€ ๋ชจ๋ฅด๊ฒ ๋„ค์š”...

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰