mack-localization 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,110 @@
1
+ Mack-Localization
2
+ -----------------------------------------------------------------------------
3
+
4
+ == Summary
5
+ Mack-Localization gem provides localization support for the Mack Framework.
6
+ Multi-byte support is provided by unicodechars gem.
7
+
8
+ == Installation #TODO: gem must be uploaded to rubyforge
9
+ sudo gem install mack-localization
10
+
11
+ == Using The Gem
12
+
13
+ {Configuration File}
14
+
15
+ Several of the localization framework settings can be overwritten by the application
16
+ if the application has the localization.yml file.
17
+
18
+ If you want to configure the localization settings, you will need to add
19
+ the localization.yml file to your mack framework in [APP_ROOT]/config/localization.
20
+
21
+ The following settings are configurable:
22
+ 'base_directory'
23
+ This will tell the framework where to start looking for the content file.
24
+ The root of the content files is configurable, but the file structure in that
25
+ folder is assumed. The framework will assume the following file structure in the
26
+ content folder:
27
+ [CONTENT_ROOT]/views/...
28
+
29
+ 'base_language'
30
+ This will tell the framework what is the default supported language
31
+
32
+ 'supported_languages'
33
+ This provides the list languages that the application support. For each
34
+ language specified in this list, please make sure that there is a corresponding
35
+ content file provided.
36
+
37
+ 'char_encoding'
38
+ This tells the framework what is the default character encoding it should be using.
39
+ NOTE: this feature is not yet implemented.
40
+
41
+ 'dynamic_translation'
42
+ If this feature is set, then when a request for translated string cannot be found in
43
+ the language file, the system will perform a dynamic lookup to translation service,
44
+ and cache the content for future uses. This feature is yet to be implemented
45
+
46
+ 'content_expiry'
47
+ This will tell the framework how long it should wait before expiring the cached content.
48
+
49
+ The following is an example of the localization.yml file:
50
+ base_language: 'fr'
51
+
52
+ supported_languages:
53
+ - bp
54
+ - en
55
+ - fr
56
+ - it
57
+ - es
58
+ - de
59
+
60
+ char_encoding: 'utf-8'
61
+
62
+ dynamic_translation: true
63
+
64
+ content_expiry: 10
65
+
66
+ {Convenience Routines provided by the framework}
67
+
68
+ The following is the list of globally accessible convenient methods provided to all application using this framework:
69
+ 'l10n_config'
70
+ Let the application access to the configuration of the localization framework.
71
+ Accessing this will give you the set values of read from localization.yml file
72
+
73
+ 'l10n_translator'
74
+ Let the application access to the translator instance.
75
+
76
+ '10n_formatter'
77
+ Let the application access the formatter instance.
78
+
79
+ The following is the list of convenient methods provided to all application as view helpers:
80
+ 'l10n_gets(key, view_sym, lang)'
81
+ Get the string for a specific key in a view with the specified language
82
+
83
+ 'l10n_getimg(key, view_sym, lang)'
84
+ Get the image path mapped to the specified key in the specified language and view
85
+
86
+ 'l10n_date(time, type, lang)'
87
+ Format the date using the specified type (:short, :medium, :long)
88
+
89
+ 'l10n_currency(amt, lang)'
90
+ Apply currency format to the given amount in the specified language.
91
+
92
+ The third utility is programming the view code in a view/language context:
93
+
94
+ l10n_context(view_sym, lang) do |ctx|
95
+ ...HTML...
96
+ <%= ctx.gets(key) %>
97
+ ..........
98
+ end
99
+
100
+ == Contact
101
+ Please mail bugs, suggestions, and patches to darsono.sutedja@gmail.com
102
+
103
+ == Copyright Notices
104
+ Copyright (c) 2008 Darsono Sutedja
105
+
106
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
107
+
108
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
109
+
110
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,40 @@
1
+
2
+ #
3
+ # Mack Localization's main configuration.
4
+ # When loaded it will try to load localization.yml file from
5
+ # {config_dir}/localization/ inside the application directory.
6
+ # If the file doesn't exist then it will just load default configuration.
7
+ #
8
+ module Mack
9
+ module Localization # :nodoc:
10
+ module Configuration
11
+
12
+ unless self.const_defined?("L10N_DEFAULTS")
13
+ L10N_DEFAULTS = {
14
+ "base_language" => "en",
15
+ "supported_languages" => %w{bp en fr it de es},
16
+ "char_encoding" => 'us-ascii',
17
+ "dynamic_translation" => false,
18
+ "base_directory" => File.join(Mack.root, "app", "lang"),
19
+ "content_expiry" => 3600
20
+ }
21
+ end
22
+
23
+ app_config.load_hash(L10N_DEFAULTS, "l10n_defaults")
24
+ path = File.join(Mack.root, "config" , "localization", "localization.yml")
25
+ if File.exists?(path)
26
+ app_config.load_file(path)
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ class Object
33
+
34
+ #
35
+ # Give access to the mack l10n config object from anywhere inside the application
36
+ #
37
+ def l10n_config
38
+ app_config
39
+ end
40
+ end
@@ -0,0 +1,12 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ class ContentCache < Cachetastic::Caches::Base
4
+ end
5
+ end
6
+ end
7
+
8
+ class Object
9
+ def l10n_cache
10
+ Mack::Localization::ContentCache
11
+ end
12
+ end
@@ -0,0 +1,80 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module Errors # :nodoc:
4
+
5
+ #
6
+ # Raise this error when caller specified unsupported language.
7
+ # Supported language is defined in configuration as an array of language codes.
8
+ #
9
+ class UnsupportedLanguage < StandardError
10
+ def initialize(lang)
11
+ super("Locale: #{lang} is not currently supported.")
12
+ end
13
+ end
14
+
15
+ #
16
+ # Raise this error when caller specified an unsupported char encoding.
17
+ # This feature is not currently supported yet.
18
+ #
19
+ class UnsupportedEncoding < StandardError
20
+ def initialize(encoding)
21
+ super("Encoding: #{encoding} is not currently supported")
22
+ end
23
+ end
24
+
25
+ #
26
+ # Raise this error if the method called is not yet implemented
27
+ #
28
+ class UnsupportedFeature < StandardError
29
+ def initialize(feature)
30
+ super("Feature: #{feature} is currently unsupported")
31
+ end
32
+ end
33
+
34
+ #
35
+ # Raise this error when the user is trying to get a string using an invalid key
36
+ #
37
+ class UnknownStringKey < StandardError
38
+ def initialize(key)
39
+ super("Key: #{key} cannot be found in the language files")
40
+ end
41
+ end
42
+
43
+ #
44
+ # Raise this error when the formatter cannot find the engine for the given language
45
+ #
46
+ class FormatEngineNotFound < StandardError
47
+ def initialize(lang)
48
+ super("Format engine not found for '#{lang}'")
49
+ end
50
+ end
51
+
52
+ #
53
+ # Raise this error when the user is calling method that doesn't exist (similar to NoMethodError)
54
+ #
55
+ class InvalidMethodName < StandardError
56
+ def initialize(method_name)
57
+ super("Unknown method: #{method_name}")
58
+ end
59
+ end
60
+
61
+ class InvalidArgument < StandardError
62
+ def initialize(param_name)
63
+ super("Invalid argument passed into method: param_name")
64
+ end
65
+ end
66
+
67
+ #
68
+ # Raise this error when the configuration file is not properly setup
69
+ #
70
+ class InvalidConfiguration < StandardError
71
+ end
72
+
73
+ #
74
+ # Raise this error if a language file is missing
75
+ #
76
+ class LanguageFileNotFound < StandardError
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,41 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module DateFormatEngine # :nodoc:
4
+ class Base
5
+
6
+ def format(time = Time.now, type = :long)
7
+ day = time.day
8
+ day_of_week = time.wday
9
+ day_of_month = time.mday
10
+ month = time.month
11
+ year = time.year
12
+
13
+ raise Mack::Localization::Errors::InvalidArgument.new(type) if date_format_template(type).nil?
14
+
15
+ template = date_format_template(type).dup
16
+ template.gsub!("mm", "%02d" % month.to_s)
17
+ template.gsub!("MM", months(type)[month-1])
18
+ template.gsub!("dd", "%02d" % day.to_s)
19
+ template.gsub!("yyyy", year.to_s)
20
+ template.gsub!("DD", days_of_week(type)[day_of_week-1])
21
+
22
+ return template
23
+ end
24
+
25
+ protected
26
+ def date_format_template(type)
27
+ raise "Unimplemented: date_format(type)"
28
+ end
29
+
30
+ def days_of_week(type)
31
+ raise "Unimplemented: days_of_week(type)"
32
+ end
33
+
34
+ def months(type)
35
+ raise "Unimplemented: month(type)"
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,42 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module DateFormatEngine # :nodoc:
4
+ class BP < Base
5
+
6
+ def date_format_template(type)
7
+ hash = ivar_cache("df_hash") do
8
+ df_hash = {
9
+ :df_short => "dd/mm/yyyy",
10
+ :df_medium => "DD, dd MM, yyyy",
11
+ :df_long => "DD, dd MM, yyyy"
12
+ }
13
+ end
14
+ return hash["df_#{type}".to_sym]
15
+ end
16
+
17
+ def days_of_week(type)
18
+ hash = ivar_cache("dow_hash") do
19
+ dow_hash = {
20
+ :dow_short => %w{S T Q Q S S D},
21
+ :dow_medium => %w{Seg Ter Qua Qui Sex Sáb Dom},
22
+ :dow_long => %w{Segunda Terça Quarta Quinta Sexta Sábado Domingo}
23
+ }
24
+ end
25
+ return hash["dow_#{type}".to_sym]
26
+ end
27
+
28
+ def months(type)
29
+ hash = ivar_cache("m_hash") do
30
+ m_hash = {
31
+ :month_short => %w{Jan Fev Mar Abr Mai Jun Jul Ago Set Out Nov Dez},
32
+ :month_medium => %w{Jan Fev Mar Abr Mai Jun Jul Ago Set Out Nov Dez},
33
+ :month_long => %w{Janeiro Fevereiro Março Abril Maio Junho Julho Agosto Setembro Outubro Novembro Dezembro}
34
+ }
35
+ end
36
+ return hash["month_#{type}".to_sym]
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,42 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module DateFormatEngine # :nodoc:
4
+ class DE < Base
5
+
6
+ def date_format_template(type)
7
+ hash = ivar_cache("df_hash") do
8
+ df_hash = {
9
+ :df_short => "dd/mm/yyyy",
10
+ :df_medium => "DD, dd MM, yyyy",
11
+ :df_long => "DD, dd MM, yyyy"
12
+ }
13
+ end
14
+ return hash["df_#{type}".to_sym]
15
+ end
16
+
17
+ def days_of_week(type)
18
+ hash = ivar_cache("dow_hash") do
19
+ dow_hash = {
20
+ :dow_short => %w{M D M D F S S},
21
+ :dow_medium => %w{Mon Die Mit Don Fre Sam Son},
22
+ :dow_long => %w{Montag Dienstag Mittwoch Donnerstag Freitag Samstag Sonntag},
23
+ }
24
+ end
25
+ return hash["dow_#{type}".to_sym]
26
+ end
27
+
28
+ def months(type)
29
+ hash = ivar_cache("m_hash") do
30
+ m_hash = {
31
+ :month_short => %w{Jan Feb Mär Apr Mai Jun Jul Aug Sep Okt Nov Dez},
32
+ :month_medium => %w{Jan Feb Mär Apr Mai Jun Jul Aug Sep Okt Nov Dez},
33
+ :month_long => %w{Januar Februar März April Mai Juni Juli August September Oktober November Dezember}
34
+ }
35
+ end
36
+ return hash["month_#{type}".to_sym]
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,43 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module DateFormatEngine # :nodoc:
4
+ class EN < Base
5
+
6
+ def date_format_template(type)
7
+ hash = ivar_cache("df_hash") do
8
+ df_hash = {
9
+ :df_short => "mm/dd/yyyy",
10
+ :df_medium => "DD, MM dd, yyyy",
11
+ :df_long => "DD, MM dd, yyyy"
12
+ }
13
+ end
14
+
15
+ return hash["df_#{type}".to_sym]
16
+ end
17
+
18
+ def days_of_week(type)
19
+ hash = ivar_cache("dow_hash") do
20
+ dow_hash = {
21
+ :dow_short => %w{M T W T F S S},
22
+ :dow_medium => %w{Mon Tue wed Thu Fri Sat Sun},
23
+ :dow_long => %w{Monday Tuesday Wednesday Thursday Friday Saturday Sunday}
24
+ }
25
+ end
26
+ return hash["dow_#{type}".to_sym]
27
+ end
28
+
29
+ def months(type)
30
+ hash = ivar_cache("m_hash") do
31
+ m_hash = {
32
+ :month_short => %w{Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec},
33
+ :month_medium => %w{Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec},
34
+ :month_long => %w{January February March April May June July August September October November December}
35
+ }
36
+ end
37
+ return hash["month_#{type}".to_sym]
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,42 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module DateFormatEngine # :nodoc:
4
+ class ES < Base
5
+
6
+ def date_format_template(type)
7
+ hash = ivar_cache("df_hash") do
8
+ df_hash = {
9
+ :df_short => "dd/mm/yyyy",
10
+ :df_medium => "DD, dd MM, yyyy",
11
+ :df_long => "DD, dd MM, yyyy"
12
+ }
13
+ end
14
+ return hash["df_#{type}".to_sym]
15
+ end
16
+
17
+ def days_of_week(type)
18
+ hash = ivar_cache("dow_hash") do
19
+ dow_hash = {
20
+ :dow_short => %w{L M M J V S D},
21
+ :dow_medium => %w{Lun Mar Mié Jue Vie Sáb Dom},
22
+ :dow_long => %w{Lunes Martes Mi\303\251rcoles Jueves Viernes S\303\241bado Domingo}
23
+ }
24
+ end
25
+ return hash["dow_#{type}".to_sym]
26
+ end
27
+
28
+ def months(type)
29
+ hash = ivar_cache("m_hash") do
30
+ m_hash = {
31
+ :month_short => %w{Ene Feb Mar Abr May Jun Jul Ago Sep Oct Nov Dic},
32
+ :month_medium => %w{Ene Feb Mar Abr May Jun Jul Ago Sep Oct Nov Dic},
33
+ :month_long => %w{Enero Febrero Marzo Abril Mayo Junio Julio Agosto Septiembre Octubre Noviembre Diciembre}
34
+ }
35
+ end
36
+ return hash["month_#{type}".to_sym]
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,42 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module DateFormatEngine # :nodoc:
4
+ class FR < Base
5
+
6
+ def date_format_template(type)
7
+ hash = ivar_cache("df_hash") do
8
+ df_hash = {
9
+ :df_short => "dd/mm/yyyy",
10
+ :df_medium => "DD, dd MM, yyyy",
11
+ :df_long => "DD, dd MM, yyyy"
12
+ }
13
+ end
14
+ return hash["df_#{type}".to_sym]
15
+ end
16
+
17
+ def days_of_week(type)
18
+ hash = ivar_cache("dow_hash") do
19
+ dow_hash = {
20
+ :dow_short => %w{L M M J V S D},
21
+ :dow_medium => %w{Lun Mar Mer Jeu Ven Sam Dim},
22
+ :dow_long => %w{Lundi Mardi Mercredi Jeudi vendredi samedi dimanche},
23
+ }
24
+ end
25
+ return hash["dow_#{type}".to_sym]
26
+ end
27
+
28
+ def months(type)
29
+ hash = ivar_cache("m_hash") do
30
+ m_hash = {
31
+ :month_short => %w{Jan Fév Mar Avr Mai Jun Jui Aoû Sep Oct Nov Dec},
32
+ :month_medium => %w{Jan Fév Mar Avr Mai Jun Jui Aoû Sep Oct Nov Dec},
33
+ :month_long => %w{Janvier Février Mars Avril Mai Juin Juillet Août Septembre Octobre Novembre Décembre},
34
+ }
35
+ end
36
+ return hash["month_#{type}".to_sym]
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,42 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module DateFormatEngine # :nodoc:
4
+ class IT < Base
5
+
6
+ def date_format_template(type)
7
+ hash = ivar_cache("df_hash") do
8
+ df_hash = {
9
+ :df_short => "dd/mm/yyyy",
10
+ :df_medium => "DD, dd MM, yyyy",
11
+ :df_long => "DD, dd MM, yyyy"
12
+ }
13
+ end
14
+ return hash["df_#{type}".to_sym]
15
+ end
16
+
17
+ def days_of_week(type)
18
+ hash = ivar_cache("dow_hash") do
19
+ dow_hash = {
20
+ :dow_short => %w{L M M G V S D},
21
+ :dow_medium => %w{Lun Mar Mer Gio Ven Sab Dom},
22
+ :dow_long => %w{Lunedi Martedì Mercoledì Giovedi Venerdì Sabato Domenica}
23
+ }
24
+ end
25
+ return hash["dow_#{type}".to_sym]
26
+ end
27
+
28
+ def months(type)
29
+ hash = ivar_cache("m_hash") do
30
+ m_hash = {
31
+ :month_short => %w{Gen Feb Mar Apr Mag Giu Lug Ago Set Ott Nov Dic},
32
+ :month_medium => %w{Gen Feb Mar Apr Mag Giu Lug Ago Set Ott Nov Dic},
33
+ :month_long => %w{Gennaio Febbraio Marzo Aprile Maggio Giugno Luglio Agosto Settembre Ottobre Novembre Dicembre}
34
+ }
35
+ end
36
+ return hash["month_#{type}".to_sym]
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,52 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ class FormatEngineRegistry
4
+ include Singleton
5
+
6
+ def initialize
7
+ # {
8
+ # :en => {:date => {...}, :num_currency => {...}},
9
+ # :fr => ...
10
+ # }
11
+ @reg = {}
12
+ end
13
+
14
+ #
15
+ # Register a format engine
16
+ #
17
+ # params:
18
+ # lang - the language of the engine
19
+ # type - either l10n_formatter.date_format_registry_key or l10n_formatter.currency_format_registry_key
20
+ # overwrite - whether or not to overwrite the formatter if it's already registered. default == false
21
+ #
22
+ def register(lang, type, obj, overwrite = false)
23
+ lang = lang.to_sym
24
+ type = type.to_sym
25
+ if @reg[lang].nil?
26
+ @reg[lang] = {type => obj}
27
+ else
28
+ type_reg = @reg[lang]
29
+ type_reg[type] = obj if type_reg[type].nil? or (overwrite and !type_reg[type].nil?)
30
+ end
31
+ end
32
+
33
+ #
34
+ # Retrieve a registered engine
35
+ #
36
+ # params:
37
+ # lang - the language
38
+ # type - either l10n_formatter.date_format_registry_key or l10n_formatter.currency_format_registry_key
39
+ #
40
+ # returns the registered engine, or nil if no engine is registered for that type/lang
41
+ #
42
+ def get_engine(lang, type)
43
+ lang = lang.to_sym
44
+ type = type.to_sym
45
+ type_reg = @reg[lang]
46
+ return nil if type_reg.nil?
47
+ return type_reg[type]
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,35 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module NumberAndCurrencyFormatEngine # :nodoc:
4
+ class Base
5
+
6
+ def format_currency(num, lang)
7
+ currency = "#{unit}#{format_number(num, lang)}"
8
+ return currency
9
+ end
10
+
11
+ def format_number(num, lang)
12
+ num_str = "%01.2f" % num
13
+ parts = num_str.split(".")
14
+ parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
15
+ parts.join separator
16
+ end
17
+
18
+ protected
19
+
20
+ def delimiter
21
+ raise "Unimplemented: delimiter"
22
+ end
23
+
24
+ def unit
25
+ raise "Unimplemented: unit"
26
+ end
27
+
28
+ def separator
29
+ raise "Unimplemented: separator"
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module NumberAndCurrencyFormatEngine # :nodoc:
4
+ class BP < Base
5
+ def delimiter
6
+ return ","
7
+ end
8
+
9
+ def unit
10
+ return "R$"
11
+ end
12
+
13
+ def separator
14
+ return "."
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module NumberAndCurrencyFormatEngine # :nodoc:
4
+ class DE < Base
5
+ def delimiter
6
+ return "."
7
+ end
8
+
9
+ def unit
10
+ return "€"
11
+ end
12
+
13
+ def separator
14
+ return ","
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module NumberAndCurrencyFormatEngine # :nodoc:
4
+ class EN < Base
5
+ def delimiter
6
+ return ","
7
+ end
8
+
9
+ def unit
10
+ return "$"
11
+ end
12
+
13
+ def separator
14
+ return "."
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module NumberAndCurrencyFormatEngine # :nodoc:
4
+ class ES < Base
5
+ def delimiter
6
+ return "."
7
+ end
8
+
9
+ def unit
10
+ return "€"
11
+ end
12
+
13
+ def separator
14
+ return ","
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module NumberAndCurrencyFormatEngine # :nodoc:
4
+ class FR < Base
5
+ def delimiter
6
+ return " "
7
+ end
8
+
9
+ def unit
10
+ return "€"
11
+ end
12
+
13
+ def separator
14
+ return ","
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ module NumberAndCurrencyFormatEngine # :nodoc:
4
+ class IT < Base
5
+ def delimiter
6
+ return "."
7
+ end
8
+
9
+ def unit
10
+ return "€"
11
+ end
12
+
13
+ def separator
14
+ return ","
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,118 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ class Formatter
4
+
5
+ include Singleton
6
+
7
+ #
8
+ # Initialize the formatter object. Out of the box
9
+ # it will register 5 language supports for both
10
+ # the date and currency format
11
+ #
12
+ def initialize
13
+ @reg = Mack::Localization::FormatEngineRegistry.instance
14
+
15
+ [:en, :bp, :fr, :it, :de, :es].each do |lang|
16
+ klass = "Mack::Localization::DateFormatEngine::#{lang.to_s.upcase}"
17
+ @reg.register(lang, date_format_registry_key, klass.constantize.new)
18
+ end
19
+
20
+ [:en, :bp, :fr, :it, :de, :es].each do |lang|
21
+ klass = "Mack::Localization::NumberAndCurrencyFormatEngine::#{lang.to_s.upcase}"
22
+ @reg.register(lang, currency_format_registry_key, klass.constantize.new)
23
+ end
24
+ end
25
+
26
+ #
27
+ # Given a time, format according to the specified type (:short, :medium, :long)
28
+ # and language.
29
+ #
30
+ # params:
31
+ # time - the instance of time to be formatted
32
+ # type - what's the format? short, medium, or long
33
+ # lang - the language
34
+ #
35
+ # returns:
36
+ # the multibyte version of the formatted string
37
+ #
38
+ # see also:
39
+ # l10n_date in view_helpers
40
+ #
41
+ # examples:
42
+ # time = Time.local(2008, "dec", 1)
43
+ # date_format(time, :short, :en) will produce "12/01/2008"
44
+ # date_format(time, :medium, :en) will produce "Tue, Dec 01, 2008"
45
+ # date_format(time, :long, :en) will produce "Tuesday, December 01, 2008"
46
+ #
47
+ def date_format(time, type, lang)
48
+ engine = @reg.get_engine(lang, date_format_registry_key)
49
+ raise Mack::Localization::Errors::FormatEngineNotFound.new(lang.to_s) if engine.nil?
50
+ return u(engine.format(time, type))
51
+ end
52
+
53
+ #
54
+ # Given a number, format it according to the specified language
55
+ #
56
+ # params:
57
+ # num - the number to be formatted
58
+ # lang - the language
59
+ #
60
+ # returns:
61
+ # the multibyte version of the formatted string
62
+ #
63
+ # see also:
64
+ # l10n_number in view_helpers
65
+ #
66
+ # examples:
67
+ # number_format(10000.00, :en) will produce "10,000.00"
68
+ #
69
+ def number_format(num, lang)
70
+ engine = @reg.get_engine(lang, currency_format_registry_key)
71
+ raise Mack::Localization::Errors::FormatEngineNotFound.new(lang.to_s) if engine.nil?
72
+ return u(engine.format_number(num, lang))
73
+ end
74
+
75
+ #
76
+ # Given a currency, format it according to the specified language
77
+ #
78
+ # params:
79
+ # num - the amount of money to be formatted
80
+ # lang - the language
81
+ #
82
+ # returns:
83
+ # the multibyte version of the formatted string
84
+ #
85
+ # see also:
86
+ # l10n_currency in view_helpers
87
+ #
88
+ # examples:
89
+ # currency_format(10000.00, :en) will produce "$10,000.00"
90
+ #
91
+ def currency_format(num, lang)
92
+ engine = @reg.get_engine(lang, currency_format_registry_key)
93
+ raise Mack::Localization::Errors::FormatEngineNotFound.new(lang.to_s) if engine.nil?
94
+ return u(engine.format_currency(num, lang))
95
+ end
96
+
97
+ #
98
+ # Return the registry key for date formatter
99
+ #
100
+ def date_format_registry_key
101
+ return :date_format
102
+ end
103
+
104
+ #
105
+ # Return the registry key for currency formatter
106
+ #
107
+ def currency_format_registry_key
108
+ return :currency_format
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ class Object
115
+ def l10n_formatter
116
+ Mack::Localization::Formatter.instance
117
+ end
118
+ end
@@ -0,0 +1,141 @@
1
+ module Mack
2
+ module ViewHelpers # :nodoc:
3
+ module L10NHelpers
4
+
5
+ class Context
6
+ include Mack::ViewHelpers::L10NHelpers
7
+
8
+ def initialize(view_sym, lang)
9
+ @view_sym = view_sym
10
+ @lang = lang
11
+ end
12
+
13
+ def gets(key)
14
+ l10n_gets(key, @view_sym, @lang)
15
+ end
16
+
17
+ def getimg(key)
18
+ l10n_getimg(key, @view_sym, @lang)
19
+ end
20
+
21
+ def date(time, type)
22
+ l10n_date(time, type, @lang)
23
+ end
24
+
25
+ def number(num)
26
+ l10n_number(num, @lang)
27
+ end
28
+
29
+ def currency(amount)
30
+ l10n_currency(amount, @lang)
31
+ end
32
+ end
33
+
34
+ def l10n_context(view_sym, lang = session[:lang] || :en)
35
+ ctx = Context.new(view_sym, lang)
36
+ yield ctx
37
+ end
38
+
39
+ #
40
+ # View helper method to get the localized string in the given view_sym path and language
41
+ # using the specified key.
42
+ #
43
+ # params:
44
+ # key - lookup key
45
+ # view_sym - tell the system where to look for the content file
46
+ # lang - the language code
47
+ #
48
+ # See:
49
+ # Mack::Localization::Translator.getimg
50
+ #
51
+ # Returns:
52
+ # the multibyte version of the localized string
53
+ #
54
+ def l10n_gets(key, view_sym = controller.controller_name, lang = session[:lang] || :en)
55
+ return l10n_translator.gets(view_sym.to_sym, key, lang)
56
+ end
57
+
58
+ #
59
+ # View helper method to get the localized image path in the given view_sym path and language
60
+ # using the specified key.
61
+ #
62
+ # params:
63
+ # key - lookup key
64
+ # view_sym - tell the system where to look for the content file
65
+ # lang - the language code
66
+ #
67
+ # See:
68
+ # Mack::Localization::Translator.getimg
69
+ #
70
+ # Returns:
71
+ # the multibyte version of the path to the localized image
72
+ #
73
+ def l10n_getimg(key, view_sym = controller.controller_name, lang = session[:lang] || :en)
74
+ return l10n_translator.getimg(view_sym.to_sym, key, lang)
75
+ end
76
+
77
+ #
78
+ # View helper method to format the specified date based on the given language code
79
+ #
80
+ # params:
81
+ # time - the date to be formatted
82
+ # type - :short, :medium, :long
83
+ # lang - language code
84
+ #
85
+ # See:
86
+ # Mack::Localization::Formatter.date_format
87
+ #
88
+ # Example:
89
+ # aTime = Time.local(2008, "jan", 1)
90
+ # l10n_date(aTime, :short, :en) produces "Jan 01, 2008"
91
+ #
92
+ # Returns:
93
+ # the multibyte version of the formatted date
94
+ #
95
+ def l10n_date(time, type, lang = session[:lang] || :en)
96
+ return l10n_formatter.date_format(time, type, lang)
97
+ end
98
+
99
+ #
100
+ # View helper method to format the number based on the given language code
101
+ #
102
+ # params:
103
+ # num - the number to be formatted
104
+ # lang - language code
105
+ #
106
+ # See:
107
+ # Mack::Localization::Formatter.number_format
108
+ #
109
+ # Example:
110
+ # l10n_number(10000, :en) produces "10,000.00"
111
+ #
112
+ # Returns:
113
+ # the multibyte version of the formatted number
114
+ #
115
+ def l10n_number(num, lang = session[:lang] || :en)
116
+ return l10n_formatter.number_format(num, lang)
117
+ end
118
+
119
+ #
120
+ # View helper method to format the currency based on the given language code
121
+ #
122
+ # params:
123
+ # amount - the amount of money
124
+ # lang - language code
125
+ #
126
+ # See:
127
+ # Mack::Localization::Formatter.currency_format
128
+ #
129
+ # Example:
130
+ # l10n_currency(10000, :en) produces "$10,000.00"
131
+ #
132
+ # Returns:
133
+ # the multibyte version of the formatted currency
134
+ #
135
+ def l10n_currency(amount, lang = session[:lang] || :en)
136
+ return l10n_formatter.currency_format(amount, lang)
137
+ end
138
+
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,108 @@
1
+ module Mack
2
+ module Localization # :nodoc:
3
+ class Translator
4
+ include Singleton
5
+
6
+ #
7
+ # Get the localized string for the specified language using the given key in the view_sym namespace.
8
+ # The view symbol is how the system knows where to locate the content file.
9
+ # By default the localization of the file is in [app_directory]/lang/views/[view_sym]/content_[lang].yml
10
+ #
11
+ # params:
12
+ # view_sym -- which view is the key located in?
13
+ # key -- the lookup key
14
+ # lang -- the language
15
+ #
16
+ # returns:
17
+ # the multibyte version of the string
18
+ #
19
+ # raise:
20
+ # UnsupportedLanguage if the specified language is not defined in the 'supported_languages' array
21
+ # UnknownStringKey if the key specified is not defined in the content file
22
+ #
23
+ # see also:
24
+ # l10n_gets in view_helpers
25
+ #
26
+ def gets(view_sym, key, lang)
27
+ view_name = view_sym.to_s
28
+ base_lang = l10n_config.base_language
29
+ base_lang = lang.to_s if !lang.nil?
30
+
31
+ raise UnsupportedLanguage.new(base_lang) if !l10n_config.supported_languages.include?(base_lang)
32
+
33
+ cache_key = "#{view_sym}_#{base_lang}_content"
34
+ path = File.join(l10n_config.base_directory, "views", "#{view_name}", "content_#{base_lang}.yml")
35
+ content_hash = load_content_hash(cache_key, base_lang, path)
36
+
37
+ raise UnknownStringKey.new(key) if content_hash[key] == nil
38
+ return u(content_hash[key])
39
+ end
40
+
41
+ def getimg(view_sym, key, lang)
42
+ raise UnsupportedFeature.new("getimg")
43
+ end
44
+
45
+ # REVIEW: inflection... should localized inflection use the same inflection engine as the english counterpart?
46
+ def pluralize(key, lang, num)
47
+ return u(inflect(key, lang, num, :plural))
48
+ end
49
+
50
+ def irregular(key, lang, num)
51
+ return u(inflect(key, lang, num, :irregular))
52
+ end
53
+
54
+ private
55
+
56
+ def inflect(key, lang, num, type)
57
+ base_lang = l10n_config.base_language
58
+ base_lang = lang if !lang.nil?
59
+
60
+ raise UnsupportedLanguage.new(base_lang) if !l10n_config.supported_languages.include?(base_lang)
61
+
62
+ cache_key = "rules_content_#{base_lang}"
63
+ path = File.join(l10n_config.base_directory, "rules", "inflection_#{base_lang}.yml")
64
+ content_hash = load_content_hash(cache_key, base_lang, path)
65
+
66
+ hash = content_hash[type]
67
+ raise InvalidConfiguration.new if hash.nil?
68
+
69
+ arr = hash[key]
70
+ raise InvalidConfiguration.new if arr.nil?
71
+ raise InvalidConfiguration.new if arr.size != 2
72
+
73
+ if num <= 1
74
+ val = sprintf(arr[0], num)
75
+ else
76
+ val = sprintf(arr[1], num)
77
+ end
78
+
79
+ return val
80
+ end
81
+
82
+ private
83
+
84
+ def load_content_hash(cache_key, base_lang, path)
85
+ # content_hash = l10n_config.send("#{cache_key}")
86
+ content_hash = l10n_cache.get("#{cache_key}")
87
+
88
+ if content_hash.nil?
89
+ raise InvalidConfiguration.new if base_lang.nil?
90
+ raise LanguageFileNotFound.new if !File.exists?(path)
91
+
92
+ data = File.read(path)
93
+ content_hash = YAML.load(data)
94
+ l10n_cache.set("#{cache_key}", content_hash, l10n_config.content_expiry)
95
+ end
96
+
97
+ return content_hash
98
+ end
99
+
100
+ end
101
+ end
102
+ end
103
+
104
+ class Object
105
+ def l10n_translator
106
+ Mack::Localization::Translator.instance
107
+ end
108
+ end
@@ -0,0 +1,7 @@
1
+ require 'unicodechars'
2
+ require 'yaml'
3
+
4
+ dir_globs = Dir.glob(File.join(File.dirname(__FILE__), "localization", "**/*.rb"))
5
+ dir_globs.each do |d|
6
+ require d
7
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mack-localization
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.0
5
+ platform: ruby
6
+ authors:
7
+ - Darsono Sutedja
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-07-16 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: unicodechars
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - "="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.0.2
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: utf8proc
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - "="
30
+ - !ruby/object:Gem::Version
31
+ version: 1.0.3
32
+ version:
33
+ description: Localization support for Mack Framework
34
+ email: Darsono.Sutedja@gmail.com
35
+ executables: []
36
+
37
+ extensions: []
38
+
39
+ extra_rdoc_files:
40
+ - README
41
+ files:
42
+ - lib/localization/configuration.rb
43
+ - lib/localization/content_cache.rb
44
+ - lib/localization/errors.rb
45
+ - lib/localization/format_engine/df_engines/base.rb
46
+ - lib/localization/format_engine/df_engines/bp.rb
47
+ - lib/localization/format_engine/df_engines/de.rb
48
+ - lib/localization/format_engine/df_engines/en.rb
49
+ - lib/localization/format_engine/df_engines/es.rb
50
+ - lib/localization/format_engine/df_engines/fr.rb
51
+ - lib/localization/format_engine/df_engines/it.rb
52
+ - lib/localization/format_engine/engine_registry.rb
53
+ - lib/localization/format_engine/nc_engines/base.rb
54
+ - lib/localization/format_engine/nc_engines/bp.rb
55
+ - lib/localization/format_engine/nc_engines/de.rb
56
+ - lib/localization/format_engine/nc_engines/en.rb
57
+ - lib/localization/format_engine/nc_engines/es.rb
58
+ - lib/localization/format_engine/nc_engines/fr.rb
59
+ - lib/localization/format_engine/nc_engines/it.rb
60
+ - lib/localization/formatter.rb
61
+ - lib/localization/helpers/view_helpers/l10n_helpers.rb
62
+ - lib/localization/translator.rb
63
+ - lib/mack-localization.rb
64
+ - README
65
+ has_rdoc: true
66
+ homepage: http://www.mackframework.com
67
+ post_install_message:
68
+ rdoc_options: []
69
+
70
+ require_paths:
71
+ - lib
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: 1.8.6
78
+ version:
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ requirements: []
86
+
87
+ rubyforge_project: magrathea
88
+ rubygems_version: 1.1.1
89
+ signing_key:
90
+ specification_version: 2
91
+ summary: Localization support for Mack Framework
92
+ test_files: []
93
+