Mercurial > pub > Impl
comparison Lib/IMPL/Resources/Strings.pm @ 245:7c517134c42f
Added Unsupported media type Web exception
corrected resourceLocation setting in the resource
Implemented localizable resources for text messages
fixed TT view scopings, INIT block in controls now sets globals correctly.
author | sergey |
---|---|
date | Mon, 29 Oct 2012 03:15:22 +0400 |
parents | 2b9b55cfb79b |
children | bbc0da7ef90e |
comparison
equal
deleted
inserted
replaced
244:a02b110da931 | 245:7c517134c42f |
---|---|
1 use strict; | 1 use strict; |
2 use warnings; | 2 use warnings; |
3 | 3 |
4 package IMPL::Resources::Strings::Storage; | |
5 package IMPL::Resources::Strings; | 4 package IMPL::Resources::Strings; |
5 | |
6 use File::Spec; | 6 use File::Spec; |
7 use List::Util qw(first); | |
8 use IMPL::Resources::Format qw(FormatMessage); | |
7 | 9 |
8 our $Locale ||= 'default'; | 10 our $Locale ||= 'default'; |
9 our $Base ||='locale'; | |
10 our $Encoding ||= 'utf-8'; | 11 our $Encoding ||= 'utf-8'; |
11 our @Locations; | 12 our @Locations; |
12 | |
13 @Locations = ('.') unless @Locations; | |
14 | 13 |
15 sub import { | 14 sub import { |
16 my ($self,$refStrings,%options) = @_; | 15 my ($self,$refStrings,%options) = @_; |
17 | 16 |
18 my ($class,$pathModule) = caller; | 17 no strict 'refs'; |
19 | 18 |
20 my ($vol,$dir,$file) = File::Spec->splitpath($pathModule); | 19 my $class = caller; |
21 my $baseDir = File::Spec->catpath($vol,$dir,''); | |
22 | 20 |
23 my @pathClass = split /::/,$class; | 21 if (ref $refStrings eq 'HASH') { |
24 my $fileClass = pop @pathClass; | 22 my %map; |
23 while(my ($name,$format) = each %$refStrings) { | |
24 $map{default}{$name} = $format; | |
25 | |
26 *{"${class}::$name"} = sub { | |
27 my $args = @_ == 1 ? shift : { @_ }; | |
28 | |
29 return _FormatMapMessage($class,$name,\%map,$Locale,$args); | |
30 } | |
31 } | |
32 } | |
33 } | |
34 | |
35 sub _FormatMapMessage { | |
36 my ($class,$msg,$map,$locale,$args) = @_; | |
37 | |
38 if (not exists $map->{$locale} ) { | |
39 $map->{$locale} = LoadStrings($class,$locale); | |
40 } | |
41 | |
42 return FormatMessage( ($map->{$locale} || $map->{default})->{$msg}, $args ); | |
43 } | |
44 | |
45 sub LoadStrings { | |
46 my ($class,$locale) = @_; | |
47 | |
48 # Foo::Bar -> ('Foo','Bar') | |
49 my @classNamespace = split /::/,$class; | |
50 | |
51 my $classShortName = pop @classNamespace; | |
52 | |
53 # Foo::Bar -> 'Foo/Bar.pm' | |
54 my $classModuleName = File::Spec->catfile(@classNamespace,"${classShortName}.pm"); | |
55 | |
56 # 'Foo/Bar.pm' -> '/full/path/to/Foo/Bar.pm' | |
57 my $fullModulePath = first { -f } map( File::Spec->catfile($_,$classModuleName), @INC ); | |
25 | 58 |
26 my @ways = map { | 59 my @ways = map { |
27 my @path = ($_); | 60 my @path = ($_); |
28 push @path,$Base; | |
29 push @path,$Locale; | 61 push @path,$Locale; |
30 | 62 |
31 File::Spec->catfile(@path,@pathClass,$fileClass); | 63 File::Spec->catfile($_,$Locale,@classNamespace,$classShortName); |
32 } @Locations; | 64 } @Locations; |
33 | 65 |
34 push @ways, File::Spec->catfile($baseDir,'locale',$Locale,$fileClass); | |
35 | 66 |
67 if ($fullModulePath) { | |
68 | |
69 # '/full/path/to/Foo/Bar.pm' -> '/full/path/to/Foo' | |
70 my ($vol,$dir,$file) = File::Spec->splitpath($fullModulePath); | |
71 my $baseDir = File::Spec->catpath($vol,$dir,''); | |
72 | |
73 # '/full/path/to/Foo' -> '/full/path/to/Foo/locale/En_US/Bar' | |
74 push @ways, File::Spec->catfile($baseDir,'locale',$Locale,$classShortName); | |
75 } | |
36 | 76 |
77 my $mapFile = first { -f } @ways; | |
37 | 78 |
38 my $stringsStorage = findResource($class,@ways); | 79 return unless $mapFile; |
39 | 80 |
81 return ParseStringsMap($mapFile); | |
40 } | 82 } |
41 | 83 |
42 sub findResource { | 84 sub ParseStringsMap { |
43 my ($class,$refWays) = @_; | |
44 | |
45 | |
46 } | |
47 | |
48 | |
49 | |
50 sub parseResource { | |
51 my ($fname) = @_; | 85 my ($fname) = @_; |
52 | 86 |
53 open my $hRes, "<:encoding($Encoding)", findFile($fname) or die "Failed to open file $fname: $!"; | 87 open my $hRes, "<:encoding($Encoding)", findFile($fname) or die "Failed to open file $fname: $!"; |
54 | 88 |
55 my %Map; | 89 my %Map; |
67 } | 101 } |
68 | 102 |
69 return \%Map; | 103 return \%Map; |
70 } | 104 } |
71 | 105 |
72 package IMPL::Resources::Strings::Storage; | |
73 use parent qw(IMPL::Object); | |
74 | |
75 sub get { | |
76 my ($this,$msg_name) = @_; | |
77 } | |
78 | |
79 1; | 106 1; |
80 | 107 |
81 __END__ | 108 __END__ |
82 | 109 |
83 =pod | 110 =pod |
91 =begin code | 118 =begin code |
92 | 119 |
93 package Foo; | 120 package Foo; |
94 | 121 |
95 use IMPL::Resources::Strings { | 122 use IMPL::Resources::Strings { |
96 msg_say_hello => "Hello, %name!", | 123 msg_say_hello => "Hello, %name%!", |
97 msg_module_name => "Simple Foo class" | 124 msg_module_name => "Simple Foo class" |
98 }, auto => 1, locale => 'en-US'; | 125 }, auto => 1, locale => 'en-US'; |
99 | 126 |
100 sub InviteUser { | 127 sub InviteUser { |
101 my ($this,$uname) = @_; | 128 my ($this,$uname) = @_; |
112 параметризованные сообщения. | 139 параметризованные сообщения. |
113 | 140 |
114 При импорте ищутся модули по следующему алгоритму: | 141 При импорте ищутся модули по следующему алгоритму: |
115 | 142 |
116 В каталогах из массива C<@Locations> ищется файл с относительным путем | 143 В каталогах из массива C<@Locations> ищется файл с относительным путем |
117 C<$Base/$Locale/$ModName>, где C<$Base>, C<$Locale> - глобальные переменные | 144 C<$Locale/$ModName>, где C<$Locale> - глобальная переменная |
118 модуля C<IMPL::Resourses::Strings>, а переменная C<$ModName> получена | 145 модуля C<IMPL::Resourses::Strings>, а переменная C<$ModName> получена |
119 путем замены 'C<::>' в имени целевого модуля на 'C</>'. | 146 путем замены 'C<::>' в имени целевого модуля на 'C</>'. |
120 | 147 |
121 Если файл не был найден, то производится поиск в каталоге, где | 148 Если файл не был найден, то производится поиск в каталоге, где |
122 расположен сам модуль, файла с относительным путем C<locale/$Locale/$ShortModName>, | 149 расположен сам модуль, файла с относительным путем C<locale/$Locale/$ShortModName>, |