Dotclear

source: inc/admin/class.dc.tab.php @ 1092:f550e0726d86

Revision 1092:f550e0726d86, 8.1 KB checked in by JcDenis, 13 years ago (diff)

Added page tabs extension (with very simple exemple in aboutConfig)

Line 
1<?php
2# -- BEGIN LICENSE BLOCK ---------------------------------------
3#
4# This file is part of Dotclear 2.
5#
6# Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear
7# Licensed under the GPL version 2.0 license.
8# See LICENSE file or
9# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10#
11# -- END LICENSE BLOCK -----------------------------------------
12if (!defined('DC_RC_PATH')) { return; }
13
14/**
15Template tab node
16*/
17class dcTabNode extends Twig_Node
18{
19     public function __construct($name,Twig_NodeInterface $params=null,Twig_NodeInterface $body,$lineno,$tag=null)
20     {
21          parent::__construct(array('body' => $body),array('name' => $name,'params' => $params),$lineno,$tag);
22     }
23     
24     public function compile(Twig_Compiler $compiler)
25     {
26          $n = $this->getAttribute('name');
27         
28          $compiler
29               ->addDebugInfo($this)
30               ->write("\$context['dc_tabs']->beginTab('".$n."'");
31         
32          /* if tab is created from template, compile args */
33          if ($this->getAttribute('params')) {
34                foreach ($this->getAttribute('params') as $value) {
35                    $compiler
36                         ->raw(", ")
37                         ->subcompile($value);
38                }
39          }
40         
41          $compiler
42               ->write(");\n")
43               
44               /* if tab is not defined, body is compiled but not display */
45               ->write("if (\$context['dc_tabs']->isTab('".$n."')) {\n")
46               ->subcompile($this->getNode('body'))
47               ->write("}\n")
48               
49               ->write("\$context['dc_tabs']->endTab('".$n."');\n")
50               ;
51     }
52}
53
54/**
55Template tab token parser
56*/
57class dcTabTokenParser extends Twig_TokenParser
58{
59     public function parse(Twig_Token $token)
60     {
61          $lineno = $token->getLine();
62          $stream = $this->parser->getStream();
63         
64          $values = null;
65          $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
66         
67          /* create tab from template */
68          if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
69            $stream->next();
70            $values = $this->parser->getExpressionParser()->parseMultitargetExpression();
71            $stream->next();
72          }
73         
74          $stream->expect(Twig_Token::BLOCK_END_TYPE);
75          $body = $this->parser->subparse(array($this,'decideBlockEnd'),true);
76          $stream->expect(Twig_Token::BLOCK_END_TYPE);
77
78          return new dcTabNode($name, $values, $body, $lineno, $this->getTag());
79     }
80     
81     public function decideBlockEnd(Twig_Token $token)
82     {
83          return $token->test('endtab');
84     }
85     
86     public function getTag()
87     {
88          return 'tab';
89     }
90}
91
92/**
93Template tab extension
94*/
95class dcTabExtension extends Twig_Extension
96{
97     public static $uri = 'tab';
98     
99     protected $tpl;
100     protected $core;
101     
102     protected $tabs = array();
103     protected $selected_tab = ''; // This is tab id, not tab name !
104     
105     public function __construct($core)
106     {
107          $this->core = $core;
108          $this->tpl = 'tab_layout.html.twig';
109          $this->selected_tab = empty($_REQUEST[self::$uri]) ? '' : $_REQUEST[self::$uri];
110     }
111     
112     public function initRuntime(Twig_Environment $environment)
113     {
114          $this->twig = $environment;
115          $this->template = $this->twig->loadTemplate($this->tpl);
116          $this->blocks = $this->template->getBlocks();
117     }
118     
119     public function getName()
120     {
121          return 'dc_tabs';
122     }
123     
124     public function getTokenParsers()
125     {
126          return array(new dcTabTokenParser());
127     }
128     
129     public function getGlobals()
130     {
131          return array('dc_tabs' => $this);
132     }
133     
134     public function getFunctions()
135     {
136          return array(
137               'init_tabs' => new Twig_Function_Method(
138                    $this,
139                    'initTabs',
140                    array('is_safe' => array('html'))
141               ),
142               'faketab' => new Twig_Function_Method(
143                    $this,
144                    'fakeTab',
145                    array('is_safe' => array('html'))
146               )
147          );
148     }
149     
150     /**
151     Display page head required by tabs
152     */
153     public function initTabs($default_tab=null)
154     {
155          if (null === $default_tab) {
156               $default_tab =  $this->selected_tab;
157          }
158         
159          echo $this->template->renderBlock(
160               'page_tab_head',
161               array(
162                    'default_tab' => $default_tab,
163                    'theme_url' => DC_ADMIN_URL.'index.php?tf='
164               ),
165               $this->blocks
166          );
167     }
168     
169     /**
170     Display begin of a tab block
171     
172     This can also create a new tab from template
173     */
174     public function beginTab()
175     {
176          $case = func_num_args();
177          $args = func_get_args();
178         
179          switch($case) {
180         
181          # No tab name ?!
182          case 0:
183               throw new Exception('Something went wrong while compile tab.');
184               break;
185          # Normal usage
186          case 1:
187               break;
188          # Create a new tab from template
189          case 3:
190               $this->setTab(new dcTab($args[0],$args[1],$args[2]));
191               break;
192          # Wrong argument count
193          default:
194               throw new Exception('Wrong parameters count for tab.');
195               break;
196         
197          };
198         
199          $tab = $this->isTab($args[0]) ? $this->tabs[$args[0]] : false;
200          $this->renderTab('page_tab_begin',$tab);
201     }
202     
203     /**
204     Display end of a tab block
205     */
206     public function endTab($name)
207     {
208          $tab = $this->isTab($name) ? $this->tabs[$name] : false;
209          $this->renderTab('page_tab_end',$tab);
210     }
211     
212     /**
213     Display a fake tab block
214     */
215     public function fakeTab()
216     {
217          $case = func_num_args();
218          $args = func_get_args();
219         
220          switch($case) {
221         
222          # No tab name ?!
223          case 0:
224               throw new Exception('Something went wrong while compile tab.');
225               break;
226          # Normal usage
227          case 1:
228               break;
229          # Create a new fake tab from template
230          case 4:
231               $this->setTab(new dcFakeTab($args[0],$args[1],$args[2],$args[3]));
232               break;
233          # Wrong argument count
234          default:
235               throw new Exception('Wrong parameters count for tab.');
236               break;
237         
238          };
239         
240          $tab = $this->isFake($args[0]) ? $this->tabs[$args[0]] : false;
241          $this->renderTab('page_tab_fake',$tab);
242     }
243     
244     /**
245     Display block
246     */
247     private function renderTab($block,$tab)
248     {
249          if ($tab) {
250               echo $this->template->renderBlock(
251                    $block,
252                    $tab->getAttributes(),
253                    $this->blocks
254               );
255          }
256     }
257     
258     /**
259     Check if a tab is previously set
260     
261     @param string $name A tab name
262     @return boolean
263     */
264     public function isTab($name)
265     {
266          return array_key_exists($name,$this->tabs);
267     }
268     
269     
270     /**
271     Check if a tab is previously set and it is a fake tab
272     
273     @param string $name A tab name
274     @return boolean
275     */
276     public function isFake($name)
277     {
278          return array_key_exists($name,$this->tabs) 
279               && $this->tabs[$name] instanceOf dcFakeTab;
280     }
281     
282     
283     /**
284     Mark a tab as selected
285     
286     @param string $name A tab name
287     */
288     public function selectTab($name)
289     {
290          if (!$name) {
291               $this->selected_tab = '';
292          }
293          elseif ($this->isTab($name) && !$this->isFake($name)) {
294               $this->selected_tab =  $this->getTab($name)->getId();
295          }
296     }
297     
298     /**
299     Get a page tab
300     
301     @param string $name A tab name
302     @return object dcTab instance
303     */
304     public function getTab($name)
305     {
306          return $this->isTab($name) ? $this->tabs[$name] : null;
307     }
308     
309     /**
310     Set (prepapre) a page tab
311     
312     @param object $tab dcTab instance
313     @return object self
314     */
315     public function setTab($tab)
316     {
317          if ($tab instanceOf dcTab || $tab instanceOf dcFakeTab) {
318               $this->tabs[$tab->getName()] = $tab;
319          }
320          return $this;
321     }
322     
323     /**
324     Check if a tab name is well formed
325     
326     Tab name must look like Twig_Token::NAME_TYPE
327     
328     @param string $name A string to check
329     @param boolean $verbose Throw exception or not
330     @return string The string or false
331     */
332     public static function checkTabName($name,$verbose=true)
333     {
334          if (!preg_match('/[a-zA-Z0-9_]{2,}/',$name)) {
335               if ($verbose) {
336                    throw new Exception(__('Wrong tab name'));
337               }
338               return false;
339          }
340          return $name;
341     }
342}
343
344/**
345Tab
346*/
347class dcTab
348{
349     protected $attributes = array();
350     
351     public function __construct($name,$id,$title)
352     {
353          $this->attributes = array(
354               'name' => dcTabExtension::checkTabName($name),
355               'id' => $id,
356               'title' => $title
357          );
358     }
359     
360     public function getAttributes()
361     {
362          return $this->attributes;
363     }
364     
365     public function getName()
366     {
367          return $this->attributes['name'];
368     }
369     
370     public function getId()
371     {
372          return $this->attributes['id'];
373     }
374     
375     public function getTitle()
376     {
377          return $this->attributes['title'];
378     }
379}
380
381/**
382Fake tab
383*/
384class dcFakeTab extends dcTab
385{
386     public function __construct($name,$id,$title,$url)
387     {
388          parent::__construct($name,$id,$title);
389          $this->attributes['url'] = $url;
390     }
391     
392     public function getURL()
393     {
394          return $this->attributes['url'];
395     }
396}
397?>
Note: See TracBrowser for help on using the repository browser.

Sites map