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;