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 |
