Mercurial > pub > Impl
diff lib/IMPL/Resources/Strings.pm @ 407:c6e90e02dd17 ref20150831
renamed Lib->lib
author | cin |
---|---|
date | Fri, 04 Sep 2015 19:40:23 +0300 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/IMPL/Resources/Strings.pm Fri Sep 04 19:40:23 2015 +0300 @@ -0,0 +1,142 @@ +package IMPL::Resources::Strings; +use strict; + +use File::Spec; +use List::Util qw(first); +use IMPL::require { + StringMap => 'IMPL::Resources::StringLocaleMap' +}; + +our @Locations; +my %maps; + +sub import { + my ($self,$refStrings,%options) = @_; + + no strict 'refs'; + + my $class = caller; + my $methods = $options{methods}; + + if (ref $refStrings eq 'HASH') { + my $map = $self->_GetMapForClass($class,$refStrings); + + while(my ($str,$format) = each %$refStrings) { + *{"${class}::$str"} = sub { + shift if $methods; + my $args = @_ == 1 ? shift : { @_ }; + + return $map->GetString($str,$args); + } + } + } +} + +sub _GetResourceLocations { + my ($self,$class) = @_; + + my @classNamespace = split /::/,$class; + + my $classShortName = pop @classNamespace; + + my @paths = map File::Spec->catdir($_,@classNamespace), @Locations; + + # Foo::Bar -> 'Foo/Bar.pm' + my $classModuleName = File::Spec->catfile(@classNamespace,"${classShortName}.pm"); + + # 'Foo/Bar.pm' -> '/full/path/to/Foo/Bar.pm' + my $fullModulePath = first { -f } map( File::Spec->catfile($_,$classModuleName), @INC ); + + if ($fullModulePath) { + + # '/full/path/to/Foo/Bar.pm' -> '/full/path/to/Foo/locale/' + my ($vol,$dir,$file) = File::Spec->splitpath($fullModulePath); + push @paths, File::Spec->catpath($vol,File::Spec->catdir($dir,'locale'),''); + } + + return \@paths, $classShortName; +} + +sub _GetMapForClass { + my ($self,$class,$data) = @_; + + my $map; + + unless ($map) { + + my ($paths,$name) = $self->_GetResourceLocations($class); + + $map = StringMap->new($data); + $map->name($name); + $map->paths($paths); + + $maps{$class} = $map; + + } + + return $map; +} + +1; + +__END__ + +=pod + +=head1 NAME + +C<IMPL::Resources::Strings> - Строковые ресурсы + +=head1 SYNOPSIS + +=begin code + +package Foo; + +use IMPL::Resources::Strings { + msg_say_hello => "Hello, %name%!", + msg_module_name => "Simple Foo class" +}; + +sub InviteUser { + my ($this,$uname) = @_; + + print msg_say_hello(name => $uname); + +} + +=end code + +=head1 DESCRIPTION + +Импортирует в целевой модуль функции, которые возвращают локализованные +параметризованные сообщения. + +При импорте ищутся модули по следующему алгоритму: + +В каталогах из массива C<@Locations> ищется файл с относительным путем +C<$Locale/$ModName>, где C<$Locale> - глобальная переменная +модуля C<IMPL::Resourses::Strings>, а переменная C<$ModName> получена +путем замены 'C<::>' в имени целевого модуля на 'C</>'. + +Если файл не был найден, то производится поиск в каталоге, где +расположен сам модуль, файла с относительным путем C<locale/$Locale/$ShortModName>, +где C<$ShortModeName> - последняя часть после 'C<::>' из имени целевого модуля. + +Если файл не найден, то используются строки, указанные при объявлении +сообщений в целевом модуле. + +=head1 FORMAT + +=begin code text + +msg_name = any text with named %params% +msg_hello = hello, %name%!!! +msg_resolve = this is a value of the property: %user.age% + +msg_short_err = %error.Message% +msg_full_err = %error% + +=end code text + +=cut