Mercurial > pub > Impl
diff Lib/DOM/Page.pm @ 0:03e58a454b20
Создан репозитарий
author | Sergey |
---|---|
date | Tue, 14 Jul 2009 12:54:37 +0400 |
parents | |
children | 16ada169ca75 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/DOM/Page.pm Tue Jul 14 12:54:37 2009 +0400 @@ -0,0 +1,241 @@ +package DOM::Page; +use Common; +use Template::Context; +use strict; + +our @ISA = qw(Object); +our $AUTOLOAD; + +BEGIN { + DeclareProperty(Title => ACCESS_ALL); + DeclareProperty(NavChain => ACCESS_READ); + DeclareProperty(Menus => ACCESS_READ); + DeclareProperty(Properties => ACCESS_READ); + DeclareProperty(Template => ACCESS_READ); + DeclareProperty(TemplatesProvider => ACCESS_NONE); + DeclareProperty(Site => ACCESS_READ); +} + +sub CTOR { + my ($this,%args) = @_; + $this->{$Site} = $args{'Site'}; + $this->{$TemplatesProvider} = $args{'TemplatesProvider'}; + $this->{$Properties} = $args{'Properties'} || {}; + $this->{$Title} = $args{'Template'}->Title() || $args{'Properties'}->{'Title'}; + $this->{$Template} = $args{'Template'}; + $this->{$NavChain} = $args{'NavChain'}; + $this->{$Menus} = $args{'Menus'}; +} + +sub Render { + my ($this,$hOut) = @_; + + my $context = new Template::Context({ + VARIABLES => $this->{$Site}->Objects(), + LOAD_TEMPLATES => $this->{$TemplatesProvider} + }); + + print $hOut $this->{$Template}->process($context); +} + +sub Dispose { + my ($this) = @_; + + undef %$this; + + $this->SUPER::Dispose; +} + +sub Container { + my ($this) = @_; + my $nav = $this->{$NavChain}; + return $nav->[@{$nav}-1]; +} + +sub AUTOLOAD { + my $this = shift; + + my $name = $AUTOLOAD; + $name =~ s/.*://; + + return $this->{$Properties}->{$name}; +} + +=pod +Ìåíþ + [ + Ýëåìåíò ìåíþ + { + Key => Êëþ÷ ïóíêòà ìåíþ, äëÿ áûñòðîãî îáðàùåíèÿ ê ýëåìåíòó è ñëèÿíèè ìåíþ + Name => Èìÿ ïóíêòà ìåíþ, êîòîðîå áóäåò âèäåëü ïîëüçîâàòåëü + Expand => ôëàã òîãî, ÷òî ìåíþ âûáðàíî + Value => {[ ýëåìåíò ìåíþ ...] | ÷òî-òî åùå, îáû÷íî óðë} + } + ] +=cut + +package DOM::PageMenu; +use Common; + +our @ISA = qw(Object); + +BEGIN { + DeclareProperty('Items'); # ìàññèâ + DeclareProperty('Keys'); # êëþ÷è äëÿ ïóíêòîâ ìåíþ, åñëè òàêîâûå èìåþòñÿ +} + +sub CTOR { + my ($this,%args) = @_; + if (ref $args{'DATA'} eq 'ARRAY') { + foreach my $item (@{$args{'DATA'}}) { + if (ref $item eq 'HASH') { + $this->Append($item->{'Name'},_ProcessData($item->{'Value'}), Expand => $item->{'Expand'}, Key => $item->{'Key'}, Url => $item->{'Url'}); + } elsif (ref $item eq 'ARRAY') { + $this->Append($item->[0],_ProcessData($item->[1]), Expand => $item->[2], Key => $item->[3], Url => $item->[4]); + } + } + } +} + +sub Item { + my ($this,$index) = @_; + + return $this->{$Items}[$index]; +} + +sub ItemByKey { + my ($this,$key) = @_; + + return $this->{$Keys}->{$key}; +} + +sub InsertBefore { + my ($this,$index,$name,$data,%options) = @_; + + my $item = {Name => $name, Value => _ProcessData($data), %options}; + splice @{$this->{$Items}},$index,0,$item; + + if ($options{'Key'}) { + $this->{$Keys}->{$options{'Key'}} = $item; + } +} + +sub Append { + my ($this,$name,$data,%options) = @_; + + my $item = {Name => $name, Value => _ProcessData($data), %options}; + + push @{$this->{$Items}},$item; + + if ($options{'Key'}) { + $this->{$Keys}->{$options{'Key'}} = $item; + } +} + +sub SubMenu { + my ($this,$path) = @_; + my $item = $this; + foreach my $key ( split /\/+/,$path ) { + $item = $item->{$Keys}->{$key}; + if (not $item ) { + die new Exception('Item does\'t exist', $path, $key); + } + $item = $item->{Value}; + if (not UNIVERSAL::isa($item,'DOM::PageMenu')) { + $item = ($this->{$Keys}->{$key}->{Value} = new DOM::PageMenu()); + } + } + + return $item; +} + +sub Dump { + use Data::Dumper; + + return Dumper(shift); +} + +sub AppendItem { + my ($this,$item) = @_; + + push @{$this->{$Items}},$item; + + if ($item->{'Key'}) { + $this->{$Keys}->{$item->{'Key'}} = $item; + } +} + +sub RemoveAt { + my ($this,$index) = @_; + + my $item = splice @{$this->{$Items}},$index,1; + + if ($item->{'Key'}) { + delete $this->{$Keys}->{$item->{'Key'}}; + } + + return 1; +} + +sub ItemsCount { + my $this = shift; + return scalar(@{$this->{$Items}}); +} + +sub Sort { + my $this = shift; + + $this->{$Items} = \sort { $a->{'Name'} <=> $b->{'Name'} } @{$this->{$Items}}; + + return 1; +} + +sub as_list { + my $this = shift; + return $this->{$Items} || []; +} + +sub Merge { + my ($this,$that) = @_; + + foreach my $itemThat ($that->Items) { + my $itemThis = $itemThat->{'Key'} ? $this->{$Keys}->{$itemThat->{'Key'}} : undef; + if ($itemThis) { + $this->MergeItems($itemThis,$itemThat); + } else { + $this->AppendItem($itemThat); + } + } +} + +sub MergeItems { + my ($this,$itemLeft,$itemRight) = @_; + + while (my ($prop,$value) = each %{$itemRight}) { + if ($prop eq 'Value') { + if (UNIVERSAL::isa($itemLeft->{$prop},__PACKAGE__) && UNIVERSAL::isa($value,__PACKAGE__)) { + $itemLeft->{$prop}->Merge($value); + } else { + $itemLeft->{$prop} = $value if defined $value; + } + } else { + $itemLeft->{$prop} = $value if defined $value; + } + } + + return 1; +} + +sub _ProcessData { + my $refData = shift; + + if (ref $refData eq 'ARRAY') { + return new DOM::PageMenu(DATA => $refData); + } else { + return $refData; + } +} + + + +1;