Mercurial > pub > Impl
annotate Lib/IMPL/Web/View/TTControl.pm @ 326:793cc7f0a7e7
IMPL::Web::AutoLocator added Sibling method for locating sibling resources
| author | sergey |
|---|---|
| date | Wed, 29 May 2013 17:58:45 +0400 |
| parents | 109f28643025 |
| children | 71221d79e6b4 |
| rev | line source |
|---|---|
| 181 | 1 package IMPL::Web::View::TTControl; |
| 2 use strict; | |
| 3 | |
| 234 | 4 use IMPL::Const qw(:prop); |
|
241
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
238
diff
changeset
|
5 use IMPL::lang qw(:hash); |
| 299 | 6 use Scalar::Util qw(blessed reftype); |
| 234 | 7 use IMPL::declare { |
| 8 require => { | |
| 296 | 9 TemplateDocument => 'Template::Document', |
| 234 | 10 TTContext => 'Template::Context', |
| 11 Exception => 'IMPL::Exception', | |
| 238 | 12 ArgumentException => '-IMPL::InvalidArgumentException', |
| 13 OperationException => '-IMPL::InvalidOperationException' | |
| 234 | 14 }, |
| 15 base => [ | |
|
241
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
238
diff
changeset
|
16 'IMPL::Object' => undef |
| 234 | 17 ], |
| 18 props => [ | |
| 19 id => PROP_RO, | |
| 238 | 20 attributes => PROP_RW, |
| 234 | 21 context => PROP_RO, |
| 22 template => PROP_RO | |
| 23 ] | |
| 24 }; | |
| 25 | |
| 181 | 26 |
| 187 | 27 { |
| 194 | 28 my $nextId = 1; |
| 29 sub _GetNextId { | |
| 299 | 30 return '_' . $nextId++; |
| 194 | 31 } |
| 187 | 32 } |
| 181 | 33 |
| 300 | 34 our $AUTOLOAD_REGEX = qr/^[a-z]/; |
| 238 | 35 |
| 181 | 36 sub CTOR { |
| 299 | 37 my ($this,$template,$context,$attrs) = @_; |
| 194 | 38 |
| 299 | 39 |
| 194 | 40 $this->template( $template ) or die new IMPL::ArgumentException("A template is required"); |
| 41 $this->context( $context ) or die new IMPL::ArgumentException("A context is required"); | |
| 42 | |
| 238 | 43 $this->attributes({}); |
| 194 | 44 |
| 301 | 45 if(ref($attrs) eq 'HASH') { |
| 299 | 46 while (my($key,$value) = each %$attrs) { |
| 47 $this->SetAttribute($key,$value); | |
| 48 } | |
| 307 | 49 } |
|
241
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
238
diff
changeset
|
50 |
| 299 | 51 $this->id(_GetNextId()) unless $this->id; |
| 191 | 52 } |
| 53 | |
| 238 | 54 sub GetAttribute { |
| 55 my ($this,$name) = (shift,shift); | |
| 56 | |
| 57 if (my $method = $this->can($name)) { | |
| 58 unshift @_,$this; | |
| 59 goto &$method; | |
| 60 } else { | |
| 61 return $this->attributes->{$name}; | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 sub SetAttribute { | |
| 66 my $this = shift; | |
| 67 my $name = shift; | |
| 68 | |
| 69 if (my $method = $this->can($name)) { | |
| 70 unshift @_, $this; | |
| 71 goto &$method; | |
| 72 } else { | |
| 73 return $this->attributes->{$name} = shift; | |
| 74 } | |
| 75 } | |
| 76 | |
| 187 | 77 sub Render { |
| 194 | 78 my ($this,$args) = @_; |
| 79 | |
| 80 $args = {} unless ref $args eq 'HASH'; | |
| 81 | |
| 299 | 82 return $this->context->include( |
| 301 | 83 $this->template->block, |
| 299 | 84 { |
| 85 %$args, | |
| 86 this => $this, | |
| 87 template => $this->template | |
| 88 } | |
| 89 ); | |
| 267 | 90 } |
| 91 | |
| 302 | 92 sub GetTemplate { |
| 93 my ($this,$name) = @_; | |
| 94 | |
| 95 return eval { $this->context->template($name) }; | |
| 96 } | |
| 97 | |
| 98 sub Include { | |
| 99 my ($this,$template, $args) = @_; | |
| 100 | |
| 101 my $tpl = $this->GetTemplate($template) | |
| 102 or die OperationException->new("The specified template isn't found", $template); | |
| 103 | |
| 104 return $this->context->include( | |
| 105 $tpl, | |
| 106 $args | |
| 107 ); | |
| 108 } | |
| 109 | |
| 314 | 110 sub HasBlock { |
| 111 my ($this,$block) = @_; | |
| 112 | |
| 113 $this->GetTemplate ? 1 : 0; | |
| 114 } | |
| 115 | |
| 185 | 116 sub AUTOLOAD { |
| 194 | 117 our $AUTOLOAD; |
| 118 | |
| 119 my $method = ($AUTOLOAD =~ m/(\w+)$/)[0]; | |
| 120 | |
| 121 return if $method eq 'DESTROY'; | |
| 122 | |
| 300 | 123 if ($method =~ /$AUTOLOAD_REGEX/) { |
| 238 | 124 my $this = shift; |
|
241
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
238
diff
changeset
|
125 |
|
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
238
diff
changeset
|
126 die OperationException->new("can't invoke method '$method' on an unblessed reference") unless blessed $this; |
| 238 | 127 |
| 128 return @_ ? $this->SetAttribute($method,@_) : $this->GetAttribute($method); | |
| 129 } else { | |
| 130 die OperationException->new("The specified method '$method' doesn't exists"); | |
| 131 } | |
| 181 | 132 } |
| 133 | |
| 134 1; | |
| 135 | |
| 136 __END__ | |
| 137 | |
| 138 =pod | |
| 139 | |
| 140 =head1 NAME | |
| 141 | |
| 142 C<IMPL::Web::View::TTControl> | |
| 143 | |
| 144 =head1 SYNPOSIS | |
| 145 | |
| 265 | 146 =begin text |
| 147 | |
| 148 [% | |
| 149 META version = 1; | |
| 150 BLOCK INIT; | |
| 151 # this is a document scope | |
| 299 | 152 dojo.modules.push( 'dijit/form/Input' ); |
| 265 | 153 END; |
| 299 | 154 |
| 155 # local to this block | |
| 156 TPreview = require('My/Org/TextPreview'); | |
| 265 | 157 |
| 299 | 158 # init control props |
| 159 visualClass = this.visualClass || 'classic'; | |
| 160 %] | |
| 161 <div id="$id" class="$visualClass" data-dojo-type="dijit/form/Input"> | |
| 162 [% FOREACH item IN model %] | |
| 163 <div class="itemContainer"> | |
| 164 [% Display(item) %] | |
| 165 </div> | |
| 265 | 166 [% END %] |
| 167 </div> | |
| 168 | |
| 169 =end text | |
| 170 | |
| 181 | 171 =head1 DESCRIPTION |
| 172 | |
| 299 | 173 Легкая обертка вокруг шаблона, позволяет изолировать пространство имен шаблона, |
| 174 а также реализовать собственные методы по представлению данных (в случае если | |
| 175 это проще сделать в виде методов класса). | |
| 265 | 176 |
| 181 | 177 =head2 BLOCKS |
| 178 | |
| 265 | 179 =head3 META |
| 180 | |
| 181 Атрибуты C<META> C<layout>, C<title> будут перенесены в свойства элемента | |
| 182 управления. | |
| 183 | |
| 181 | 184 =head3 INIT |
| 185 | |
| 265 | 186 Данный блок шаблона управления выполняется один раз при создании первого |
| 187 экземпляра элемента управления, в пространстве имен документа. Может | |
| 188 использоваться для формирования заголовочной части документа, скрипта | |
| 189 подключающего C<js> модули и т.п. | |
| 190 | |
| 191 Выполнение данного блока производится фабрикой элементов управления. | |
| 181 | 192 |
| 187 | 193 =head2 TEMPLATE VARS |
| 194 | |
| 265 | 195 Каждый шаблон имеет собственное пространство имен, вложенное в пространство имен |
| 196 фабрики элементов (которая разделяет пространство имен документа). В шаблоне | |
| 197 могут определяться новые переменные, однако они останутся локальными для блоков. | |
| 198 | |
| 199 Чтобы передать данные между блоками следует использовать ссылку на элемент | |
| 200 управления C<this>. | |
| 201 | |
| 202 =begin text | |
| 203 | |
| 204 [% | |
| 205 BLOCK CTOR; | |
| 206 this.extraCssClass = 'active'; | |
| 207 text = "this text will gone"; | |
| 208 END; | |
| 209 %] | |
| 210 | |
| 211 <div class="$this.extraCssClass">some text $text</div> | |
| 212 | |
| 213 =end text | |
| 214 | |
| 215 В примере выше переменная C<$text> установленная в конструкторе шаблона, при | |
| 216 отображении элемента управления будет неопределена. | |
| 187 | 217 |
| 218 =over | |
| 219 | |
| 265 | 220 =item * C<this> |
| 221 | |
| 222 ссылка на объект элемента управления | |
| 223 | |
| 224 =item * C<component> | |
| 187 | 225 |
| 265 | 226 ссылка на текущий шаблон, устанавливается автоматически в методе |
| 227 C<Template::Context::process>. | |
| 187 | 228 |
| 265 | 229 =item * C<template> |
| 230 | |
| 231 ссылка на шаблон элемента управления, для совместимости с C<TT> | |
| 187 | 232 |
| 233 =back | |
| 234 | |
| 235 =head1 MEMBERS | |
| 236 | |
| 300 | 237 =head2 C<[get]context> |
| 187 | 238 |
| 300 | 239 Контекст элемента управления, хранит пременные шаблона. Фабрика элементов |
| 240 управления создает новый контекст пространство имен которого вложено в | |
| 241 пространство имен документа. | |
| 187 | 242 |
| 300 | 243 Контекст следует использовать только при рендеринге документа. |
| 244 | |
| 245 =head2 C<[get,set]template> | |
| 187 | 246 |
| 247 C<Template::Document> Шаблон элемента управления. | |
| 248 | |
| 300 | 249 =head2 C<AUTOLOAD> |
| 187 | 250 |
| 265 | 251 Для удобства работы с шаблоном, элементы управления предоставляю доступ к своим |
| 252 свойствам через метод C<AUTOLOAD>. Имена свойств должны начинаться со строчной | |
| 253 буквы. | |
| 187 | 254 |
| 181 | 255 =cut |
