Mercurial > pub > Impl
comparison lib/IMPL/Resources/Strings.pm @ 407:c6e90e02dd17 ref20150831
renamed Lib->lib
author | cin |
---|---|
date | Fri, 04 Sep 2015 19:40:23 +0300 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
406:f23fcb19d3c1 | 407:c6e90e02dd17 |
---|---|
1 package IMPL::Resources::Strings; | |
2 use strict; | |
3 | |
4 use File::Spec; | |
5 use List::Util qw(first); | |
6 use IMPL::require { | |
7 StringMap => 'IMPL::Resources::StringLocaleMap' | |
8 }; | |
9 | |
10 our @Locations; | |
11 my %maps; | |
12 | |
13 sub import { | |
14 my ($self,$refStrings,%options) = @_; | |
15 | |
16 no strict 'refs'; | |
17 | |
18 my $class = caller; | |
19 my $methods = $options{methods}; | |
20 | |
21 if (ref $refStrings eq 'HASH') { | |
22 my $map = $self->_GetMapForClass($class,$refStrings); | |
23 | |
24 while(my ($str,$format) = each %$refStrings) { | |
25 *{"${class}::$str"} = sub { | |
26 shift if $methods; | |
27 my $args = @_ == 1 ? shift : { @_ }; | |
28 | |
29 return $map->GetString($str,$args); | |
30 } | |
31 } | |
32 } | |
33 } | |
34 | |
35 sub _GetResourceLocations { | |
36 my ($self,$class) = @_; | |
37 | |
38 my @classNamespace = split /::/,$class; | |
39 | |
40 my $classShortName = pop @classNamespace; | |
41 | |
42 my @paths = map File::Spec->catdir($_,@classNamespace), @Locations; | |
43 | |
44 # Foo::Bar -> 'Foo/Bar.pm' | |
45 my $classModuleName = File::Spec->catfile(@classNamespace,"${classShortName}.pm"); | |
46 | |
47 # 'Foo/Bar.pm' -> '/full/path/to/Foo/Bar.pm' | |
48 my $fullModulePath = first { -f } map( File::Spec->catfile($_,$classModuleName), @INC ); | |
49 | |
50 if ($fullModulePath) { | |
51 | |
52 # '/full/path/to/Foo/Bar.pm' -> '/full/path/to/Foo/locale/' | |
53 my ($vol,$dir,$file) = File::Spec->splitpath($fullModulePath); | |
54 push @paths, File::Spec->catpath($vol,File::Spec->catdir($dir,'locale'),''); | |
55 } | |
56 | |
57 return \@paths, $classShortName; | |
58 } | |
59 | |
60 sub _GetMapForClass { | |
61 my ($self,$class,$data) = @_; | |
62 | |
63 my $map; | |
64 | |
65 unless ($map) { | |
66 | |
67 my ($paths,$name) = $self->_GetResourceLocations($class); | |
68 | |
69 $map = StringMap->new($data); | |
70 $map->name($name); | |
71 $map->paths($paths); | |
72 | |
73 $maps{$class} = $map; | |
74 | |
75 } | |
76 | |
77 return $map; | |
78 } | |
79 | |
80 1; | |
81 | |
82 __END__ | |
83 | |
84 =pod | |
85 | |
86 =head1 NAME | |
87 | |
88 C<IMPL::Resources::Strings> - Строковые ресурсы | |
89 | |
90 =head1 SYNOPSIS | |
91 | |
92 =begin code | |
93 | |
94 package Foo; | |
95 | |
96 use IMPL::Resources::Strings { | |
97 msg_say_hello => "Hello, %name%!", | |
98 msg_module_name => "Simple Foo class" | |
99 }; | |
100 | |
101 sub InviteUser { | |
102 my ($this,$uname) = @_; | |
103 | |
104 print msg_say_hello(name => $uname); | |
105 | |
106 } | |
107 | |
108 =end code | |
109 | |
110 =head1 DESCRIPTION | |
111 | |
112 Импортирует в целевой модуль функции, которые возвращают локализованные | |
113 параметризованные сообщения. | |
114 | |
115 При импорте ищутся модули по следующему алгоритму: | |
116 | |
117 В каталогах из массива C<@Locations> ищется файл с относительным путем | |
118 C<$Locale/$ModName>, где C<$Locale> - глобальная переменная | |
119 модуля C<IMPL::Resourses::Strings>, а переменная C<$ModName> получена | |
120 путем замены 'C<::>' в имени целевого модуля на 'C</>'. | |
121 | |
122 Если файл не был найден, то производится поиск в каталоге, где | |
123 расположен сам модуль, файла с относительным путем C<locale/$Locale/$ShortModName>, | |
124 где C<$ShortModeName> - последняя часть после 'C<::>' из имени целевого модуля. | |
125 | |
126 Если файл не найден, то используются строки, указанные при объявлении | |
127 сообщений в целевом модуле. | |
128 | |
129 =head1 FORMAT | |
130 | |
131 =begin code text | |
132 | |
133 msg_name = any text with named %params% | |
134 msg_hello = hello, %name%!!! | |
135 msg_resolve = this is a value of the property: %user.age% | |
136 | |
137 msg_short_err = %error.Message% | |
138 msg_full_err = %error% | |
139 | |
140 =end code text | |
141 | |
142 =cut |