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>,