Mercurial > pub > Impl
comparison Lib/IMPL/Resources/StringMap.pm @ 376:a54a2faf2f7e
added localizable string maps
| author | cin |
|---|---|
| date | Mon, 13 Jan 2014 17:52:04 +0400 |
| parents | |
| children | a0d342ac9a36 |
comparison
equal
deleted
inserted
replaced
| 375:441e84031c7b | 376:a54a2faf2f7e |
|---|---|
| 1 package IMPL::Web::Resources::StringMap; | |
| 2 use strict; | |
| 3 | |
| 4 use IMPL::Const qw(:prop); | |
| 5 use IMPL::declare { | |
| 6 require => { | |
| 7 Exception => 'IMPL::Exception', | |
| 8 IOException => '-IMPL::IOException', | |
| 9 ArgException => '-IMPL::InvalidArgumentException' | |
| 10 }, | |
| 11 props => [ | |
| 12 _data => PROP_RW, | |
| 13 _parent => PROP_RW | |
| 14 ] | |
| 15 }; | |
| 16 | |
| 17 sub CTOR { | |
| 18 my ($this,$data,$parent) = @_; | |
| 19 | |
| 20 die ArgException->new( data => 'A hash reference is required' ) | |
| 21 unless ref($data) eq 'HASH'; | |
| 22 | |
| 23 die ArgException->new( data => 'A hash must contain either scalars or subs') | |
| 24 if grep not($_) || (ref($_) and ref($_) ne 'CODE'), values %$data; | |
| 25 | |
| 26 $this->_data($data); | |
| 27 $this->_parent($parent); | |
| 28 } | |
| 29 | |
| 30 sub GetString { | |
| 31 my ($this,$id,$args) = @_; | |
| 32 | |
| 33 if(my $format = $this->_data->{$id}) { | |
| 34 return $this->FormatString($format,$args); | |
| 35 } else { | |
| 36 return $this->_parent? $this->_parent->GetString($id,$args) : "[$id]"; | |
| 37 } | |
| 38 | |
| 39 } | |
| 40 | |
| 41 sub FormatString { | |
| 42 my ($self,$text,$args) = @_; | |
| 43 | |
| 44 $args ||= {}; | |
| 45 $resolver ||= \&_defaultResolver; | |
| 46 $text ||= ''; | |
| 47 | |
| 48 $string =~ s/%(\w+(?:\.\w+)*)%/$self->GetValue($args,$1,"\[$1\]")/ge; | |
| 49 | |
| 50 return $string; | |
| 51 | |
| 52 } | |
| 53 | |
| 54 sub GetValue { | |
| 55 my ($self,$obj,$path,$default) = @_; | |
| 56 | |
| 57 foreach my $chunk (split /\./,$path) { | |
| 58 return $default unless $obj; | |
| 59 if (ref $obj eq 'HASH') { | |
| 60 $obj = $obj->{$chunk}; | |
| 61 } else { | |
| 62 $obj = $self->Resolve($obj,$chunk); | |
| 63 } | |
| 64 } | |
| 65 return $obj||'<undef>'; | |
| 66 } | |
| 67 | |
| 68 sub Resolve { | |
| 69 my ($self,$obj,$prop) = @_; | |
| 70 | |
| 71 return ( eval { $obj->can($prop) } ? $obj->$prop() : undef ); | |
| 72 } | |
| 73 | |
| 74 sub _LoadMap { | |
| 75 my ($self,$file,$parent) = @_; | |
| 76 | |
| 77 my $data = do $file; | |
| 78 my $e = $@; | |
| 79 die Exception->new("Failed to load file '$file'", $e) if $e; | |
| 80 die IOException->new("Failed to load file '$file'", $!) if not defined $data and $!; | |
| 81 die Exception->new("Failed to load file '$file'", "A hash data is expected") unless ref($data) eq 'HASH'; | |
| 82 | |
| 83 return $self->new($data,$parent); | |
| 84 } | |
| 85 | |
| 86 1; | |
| 87 | |
| 88 __END__ | |
| 89 | |
| 90 =pod | |
| 91 | |
| 92 =head1 NAME | |
| 93 | |
| 94 C<IMPL::Web::Resources::StringMap> | |
| 95 | |
| 96 =head1 SYNOPSIS | |
| 97 | |
| 98 My/App/locale/default/Search.labels | |
| 99 | |
| 100 My/App/locale/en/Search.map | |
| 101 | |
| 102 =begin code | |
| 103 | |
| 104 { | |
| 105 TitleLabel => 'Search results', | |
| 106 ViewLabel => 'View %name%', # same as sub { $_[0]->Format('View %name%',$_[1]) } | |
| 107 ResultsCountLabel => sub { | |
| 108 my ($self,$args) = @_; | |
| 109 | |
| 110 $args ||= {}; | |
| 111 | |
| 112 if (not $args->{count}) { | |
| 113 return "No items found"; | |
| 114 } elsif($args->{count} == 1) { | |
| 115 return "Found one item"; | |
| 116 } else { | |
| 117 return $self->Format("Found %count% items", $args); | |
| 118 } | |
| 119 } | |
| 120 } | |
| 121 | |
| 122 =end code | |
| 123 | |
| 124 =head1 DESCRIPTION | |
| 125 | |
| 126 =head | |
| 127 | |
| 128 =cut |
