Mercurial > pub > Impl
annotate Lib/IMPL/Resources/StringMap.pm @ 384:4edd36025051
DOM schema refactoring
author | cin |
---|---|
date | Mon, 10 Feb 2014 17:41:34 +0400 |
parents | ced5937ff21a |
children |
rev | line source |
---|---|
378 | 1 package IMPL::Resources::StringMap; |
376 | 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 }, | |
378 | 11 base => [ |
12 'IMPL::Object' => '@_' | |
13 ], | |
376 | 14 props => [ |
15 _data => PROP_RW, | |
16 _parent => PROP_RW | |
17 ] | |
18 }; | |
19 | |
20 sub CTOR { | |
21 my ($this,$data,$parent) = @_; | |
22 | |
23 die ArgException->new( data => 'A hash reference is required' ) | |
24 unless ref($data) eq 'HASH'; | |
25 | |
26 die ArgException->new( data => 'A hash must contain either scalars or subs') | |
378 | 27 if grep ref($_) && ref($_) ne 'CODE', values %$data; |
376 | 28 |
29 $this->_data($data); | |
30 $this->_parent($parent); | |
31 } | |
32 | |
33 sub GetString { | |
34 my ($this,$id,$args) = @_; | |
35 | |
36 if(my $format = $this->_data->{$id}) { | |
378 | 37 return ref($format) eq 'CODE' ? &$format($this,$args || {}) : $this->FormatString($format,$args); |
376 | 38 } else { |
377 | 39 return $this->_parent? $this->_parent->GetString($id,$args) : "[ $id ]"; |
376 | 40 } |
41 | |
42 } | |
43 | |
377 | 44 sub AddFormat { |
45 my ($this,$id,$format) = @_; | |
46 | |
47 die ArgException->new( id => 'A format id is required' ) | |
48 unless $id; | |
49 | |
50 die ArgException->new( format => 'A format must be a scalar or a sub' ) | |
51 if ref($format) and ref($format) ne 'CODE'; | |
52 | |
53 $this->_data->{$id} = $format; | |
54 } | |
55 | |
376 | 56 sub FormatString { |
57 my ($self,$text,$args) = @_; | |
58 | |
59 $args ||= {}; | |
60 $text ||= ''; | |
61 | |
378 | 62 $text =~ s/%(\w+(?:\.\w+)*)%/$self->GetValue($args,$1,"\[$1\]")/ge; |
376 | 63 |
378 | 64 return $text; |
376 | 65 |
66 } | |
67 | |
68 sub GetValue { | |
69 my ($self,$obj,$path,$default) = @_; | |
70 | |
71 foreach my $chunk (split /\./,$path) { | |
72 return $default unless $obj; | |
73 if (ref $obj eq 'HASH') { | |
74 $obj = $obj->{$chunk}; | |
75 } else { | |
76 $obj = $self->Resolve($obj,$chunk); | |
77 } | |
78 } | |
79 return $obj||'<undef>'; | |
80 } | |
81 | |
82 sub Resolve { | |
83 my ($self,$obj,$prop) = @_; | |
84 | |
381
ced5937ff21a
Custom getters/setters support method names in theirs definitions
cin
parents:
378
diff
changeset
|
85 return eval { $obj->$prop() }; |
376 | 86 } |
87 | |
88 1; | |
89 | |
90 __END__ | |
91 | |
92 =pod | |
93 | |
94 =head1 NAME | |
95 | |
96 C<IMPL::Web::Resources::StringMap> | |
97 | |
98 =head1 SYNOPSIS | |
99 | |
100 =begin code | |
101 | |
377 | 102 use IMPL::require { |
103 StringMap => 'IMPL::Resources::StringMap' | |
104 }; | |
105 | |
106 my $data = { | |
376 | 107 TitleLabel => 'Search results', |
108 ViewLabel => 'View %name%', # same as sub { $_[0]->Format('View %name%',$_[1]) } | |
109 ResultsCountLabel => sub { | |
110 my ($self,$args) = @_; | |
111 | |
112 $args ||= {}; | |
113 | |
114 if (not $args->{count}) { | |
115 return "No items found"; | |
116 } elsif($args->{count} == 1) { | |
117 return "Found one item"; | |
118 } else { | |
377 | 119 return $self->Format('Found %count% items', $args); |
376 | 120 } |
121 } | |
122 } | |
123 | |
377 | 124 my $def = StringMap->new({ |
125 ResultsCountLabel => 'Found %count% items' | |
126 }); | |
127 | |
128 my $map = StringMap->new($data, $def); | |
129 | |
130 print $map->GetString('TitleLabel'); | |
131 print $map->GetString(ResultsCountLabel => { count => 0 }); # will print "No items found" | |
132 | |
133 | |
376 | 134 =end code |
135 | |
136 =head1 DESCRIPTION | |
137 | |
377 | 138 =head1 MEMBERS |
376 | 139 |
140 =cut |