comparison Lib/DOM/Page.pm @ 0:03e58a454b20

Создан репозитарий
author Sergey
date Tue, 14 Jul 2009 12:54:37 +0400
parents
children 16ada169ca75
comparison
equal deleted inserted replaced
-1:000000000000 0:03e58a454b20
1 package DOM::Page;
2 use Common;
3 use Template::Context;
4 use strict;
5
6 our @ISA = qw(Object);
7 our $AUTOLOAD;
8
9 BEGIN {
10 DeclareProperty(Title => ACCESS_ALL);
11 DeclareProperty(NavChain => ACCESS_READ);
12 DeclareProperty(Menus => ACCESS_READ);
13 DeclareProperty(Properties => ACCESS_READ);
14 DeclareProperty(Template => ACCESS_READ);
15 DeclareProperty(TemplatesProvider => ACCESS_NONE);
16 DeclareProperty(Site => ACCESS_READ);
17 }
18
19 sub CTOR {
20 my ($this,%args) = @_;
21 $this->{$Site} = $args{'Site'};
22 $this->{$TemplatesProvider} = $args{'TemplatesProvider'};
23 $this->{$Properties} = $args{'Properties'} || {};
24 $this->{$Title} = $args{'Template'}->Title() || $args{'Properties'}->{'Title'};
25 $this->{$Template} = $args{'Template'};
26 $this->{$NavChain} = $args{'NavChain'};
27 $this->{$Menus} = $args{'Menus'};
28 }
29
30 sub Render {
31 my ($this,$hOut) = @_;
32
33 my $context = new Template::Context({
34 VARIABLES => $this->{$Site}->Objects(),
35 LOAD_TEMPLATES => $this->{$TemplatesProvider}
36 });
37
38 print $hOut $this->{$Template}->process($context);
39 }
40
41 sub Dispose {
42 my ($this) = @_;
43
44 undef %$this;
45
46 $this->SUPER::Dispose;
47 }
48
49 sub Container {
50 my ($this) = @_;
51 my $nav = $this->{$NavChain};
52 return $nav->[@{$nav}-1];
53 }
54
55 sub AUTOLOAD {
56 my $this = shift;
57
58 my $name = $AUTOLOAD;
59 $name =~ s/.*://;
60
61 return $this->{$Properties}->{$name};
62 }
63
64 =pod
65 Ìåíþ
66 [
67 Ýëåìåíò ìåíþ
68 {
69 Key => Êëþ÷ ïóíêòà ìåíþ, äëÿ áûñòðîãî îáðàùåíèÿ ê ýëåìåíòó è ñëèÿíèè ìåíþ
70 Name => Èìÿ ïóíêòà ìåíþ, êîòîðîå áóäåò âèäåëü ïîëüçîâàòåëü
71 Expand => ôëàã òîãî, ÷òî ìåíþ âûáðàíî
72 Value => {[ ýëåìåíò ìåíþ ...] | ÷òî-òî åùå, îáû÷íî óðë}
73 }
74 ]
75 =cut
76
77 package DOM::PageMenu;
78 use Common;
79
80 our @ISA = qw(Object);
81
82 BEGIN {
83 DeclareProperty('Items'); # ìàññèâ
84 DeclareProperty('Keys'); # êëþ÷è äëÿ ïóíêòîâ ìåíþ, åñëè òàêîâûå èìåþòñÿ
85 }
86
87 sub CTOR {
88 my ($this,%args) = @_;
89 if (ref $args{'DATA'} eq 'ARRAY') {
90 foreach my $item (@{$args{'DATA'}}) {
91 if (ref $item eq 'HASH') {
92 $this->Append($item->{'Name'},_ProcessData($item->{'Value'}), Expand => $item->{'Expand'}, Key => $item->{'Key'}, Url => $item->{'Url'});
93 } elsif (ref $item eq 'ARRAY') {
94 $this->Append($item->[0],_ProcessData($item->[1]), Expand => $item->[2], Key => $item->[3], Url => $item->[4]);
95 }
96 }
97 }
98 }
99
100 sub Item {
101 my ($this,$index) = @_;
102
103 return $this->{$Items}[$index];
104 }
105
106 sub ItemByKey {
107 my ($this,$key) = @_;
108
109 return $this->{$Keys}->{$key};
110 }
111
112 sub InsertBefore {
113 my ($this,$index,$name,$data,%options) = @_;
114
115 my $item = {Name => $name, Value => _ProcessData($data), %options};
116 splice @{$this->{$Items}},$index,0,$item;
117
118 if ($options{'Key'}) {
119 $this->{$Keys}->{$options{'Key'}} = $item;
120 }
121 }
122
123 sub Append {
124 my ($this,$name,$data,%options) = @_;
125
126 my $item = {Name => $name, Value => _ProcessData($data), %options};
127
128 push @{$this->{$Items}},$item;
129
130 if ($options{'Key'}) {
131 $this->{$Keys}->{$options{'Key'}} = $item;
132 }
133 }
134
135 sub SubMenu {
136 my ($this,$path) = @_;
137 my $item = $this;
138 foreach my $key ( split /\/+/,$path ) {
139 $item = $item->{$Keys}->{$key};
140 if (not $item ) {
141 die new Exception('Item does\'t exist', $path, $key);
142 }
143 $item = $item->{Value};
144 if (not UNIVERSAL::isa($item,'DOM::PageMenu')) {
145 $item = ($this->{$Keys}->{$key}->{Value} = new DOM::PageMenu());
146 }
147 }
148
149 return $item;
150 }
151
152 sub Dump {
153 use Data::Dumper;
154
155 return Dumper(shift);
156 }
157
158 sub AppendItem {
159 my ($this,$item) = @_;
160
161 push @{$this->{$Items}},$item;
162
163 if ($item->{'Key'}) {
164 $this->{$Keys}->{$item->{'Key'}} = $item;
165 }
166 }
167
168 sub RemoveAt {
169 my ($this,$index) = @_;
170
171 my $item = splice @{$this->{$Items}},$index,1;
172
173 if ($item->{'Key'}) {
174 delete $this->{$Keys}->{$item->{'Key'}};
175 }
176
177 return 1;
178 }
179
180 sub ItemsCount {
181 my $this = shift;
182 return scalar(@{$this->{$Items}});
183 }
184
185 sub Sort {
186 my $this = shift;
187
188 $this->{$Items} = \sort { $a->{'Name'} <=> $b->{'Name'} } @{$this->{$Items}};
189
190 return 1;
191 }
192
193 sub as_list {
194 my $this = shift;
195 return $this->{$Items} || [];
196 }
197
198 sub Merge {
199 my ($this,$that) = @_;
200
201 foreach my $itemThat ($that->Items) {
202 my $itemThis = $itemThat->{'Key'} ? $this->{$Keys}->{$itemThat->{'Key'}} : undef;
203 if ($itemThis) {
204 $this->MergeItems($itemThis,$itemThat);
205 } else {
206 $this->AppendItem($itemThat);
207 }
208 }
209 }
210
211 sub MergeItems {
212 my ($this,$itemLeft,$itemRight) = @_;
213
214 while (my ($prop,$value) = each %{$itemRight}) {
215 if ($prop eq 'Value') {
216 if (UNIVERSAL::isa($itemLeft->{$prop},__PACKAGE__) && UNIVERSAL::isa($value,__PACKAGE__)) {
217 $itemLeft->{$prop}->Merge($value);
218 } else {
219 $itemLeft->{$prop} = $value if defined $value;
220 }
221 } else {
222 $itemLeft->{$prop} = $value if defined $value;
223 }
224 }
225
226 return 1;
227 }
228
229 sub _ProcessData {
230 my $refData = shift;
231
232 if (ref $refData eq 'ARRAY') {
233 return new DOM::PageMenu(DATA => $refData);
234 } else {
235 return $refData;
236 }
237 }
238
239
240
241 1;