Mercurial > pub > Impl
view Lib/DOM/Page.pm @ 104:196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
Minor and major fixes almost for everything.
A 'Source' property of the ValidationErrors generated from a NodeSet or a NodeList is subject to change in the future.
author | wizard |
---|---|
date | Tue, 11 May 2010 02:42:59 +0400 |
parents | 16ada169ca75 |
children |
line wrap: on
line source
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;