changeset 376:a54a2faf2f7e

added localizable string maps
author cin
date Mon, 13 Jan 2014 17:52:04 +0400
parents 441e84031c7b
children a0d342ac9a36
files Lib/IMPL/Resources/StringMap.pm
diffstat 1 files changed, 128 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib/IMPL/Resources/StringMap.pm	Mon Jan 13 17:52:04 2014 +0400
@@ -0,0 +1,128 @@
+package IMPL::Web::Resources::StringMap;
+use strict;
+
+use IMPL::Const qw(:prop);
+use IMPL::declare {
+	require => {
+		Exception => 'IMPL::Exception',
+		IOException => '-IMPL::IOException',
+		ArgException => '-IMPL::InvalidArgumentException'
+	},
+	props => [
+		_data => PROP_RW,
+		_parent => PROP_RW
+	]
+};
+
+sub CTOR {
+	my ($this,$data,$parent) = @_;
+	
+	die ArgException->new( data => 'A hash reference is required' )
+		unless ref($data) eq 'HASH';
+		
+	die ArgException->new( data => 'A hash must contain either scalars or subs')
+		if grep not($_) || (ref($_) and ref($_) ne 'CODE'), values %$data;
+	
+	$this->_data($data);
+	$this->_parent($parent);
+}
+
+sub GetString {
+	my ($this,$id,$args) = @_;
+	
+	if(my $format = $this->_data->{$id}) {
+		return $this->FormatString($format,$args);
+	} else {
+		return $this->_parent? $this->_parent->GetString($id,$args) : "[$id]";
+	}
+	
+}
+
+sub FormatString {
+	my ($self,$text,$args) = @_;
+    
+    $args ||= {};
+    $resolver ||= \&_defaultResolver;
+    $text ||= '';
+    
+    $string =~ s/%(\w+(?:\.\w+)*)%/$self->GetValue($args,$1,"\[$1\]")/ge;
+    
+    return $string;
+	
+}
+
+sub GetValue {
+	my ($self,$obj,$path,$default) = @_;
+    
+    foreach my $chunk (split /\./,$path) {
+        return $default unless $obj;
+        if (ref $obj eq 'HASH') {
+            $obj = $obj->{$chunk};
+        } else {
+            $obj = $self->Resolve($obj,$chunk);
+        }
+    }
+    return $obj||'<undef>';
+}
+
+sub Resolve {
+	my ($self,$obj,$prop) = @_;
+    
+    return ( eval { $obj->can($prop) } ? $obj->$prop() : undef );
+}
+
+sub _LoadMap {
+	my ($self,$file,$parent) = @_;
+	
+	my $data = do $file;
+	my $e = $@;
+	die Exception->new("Failed to load file '$file'", $e) if $e;
+	die IOException->new("Failed to load file '$file'", $!) if not defined $data and $!;
+	die Exception->new("Failed to load file '$file'", "A hash data is expected") unless ref($data) eq 'HASH';
+	
+	return $self->new($data,$parent);
+}
+
+1;
+
+__END__
+
+=pod 
+
+=head1 NAME
+
+C<IMPL::Web::Resources::StringMap>
+
+=head1 SYNOPSIS
+
+My/App/locale/default/Search.labels
+
+My/App/locale/en/Search.map
+
+=begin code
+
+{
+	TitleLabel => 'Search results',
+	ViewLabel => 'View %name%', # same as sub { $_[0]->Format('View %name%',$_[1]) } 
+	ResultsCountLabel => sub {
+		my ($self,$args) = @_;
+		
+		$args ||= {};
+		
+		if (not $args->{count}) {
+			return "No items found";
+		} elsif($args->{count} == 1) {
+			return "Found one item";
+		} else {
+			return $self->Format("Found %count% items", $args);
+		}
+	}
+}
+
+=end code
+
+=head1 DESCRIPTION
+
+=head
+
+=cut
\ No newline at end of file