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