]> git.mxchange.org Git - core.git/blob - framework/main/classes/template/menu/class_MenuTemplateEngine.php
Continued:
[core.git] / framework / main / classes / template / menu / class_MenuTemplateEngine.php
1 <?php
2 // Own namespace
3 namespace Org\Mxchange\CoreFramework\Template\Engine;
4
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Bootstrap\FrameworkBootstrap;
7 use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
8 use Org\Mxchange\CoreFramework\Filesystem\InvalidDirectoryException;
9 use Org\Mxchange\CoreFramework\Menu\RenderableMenu;
10 use Org\Mxchange\CoreFramework\Parser\Xml\XmlParser;
11 use Org\Mxchange\CoreFramework\Registry\GenericRegistry;
12 use Org\Mxchange\CoreFramework\Template\CompileableTemplate;
13 use Org\Mxchange\CoreFramework\Template\Engine\BaseTemplateEngine;
14 use Org\Mxchange\CoreFramework\Utils\String\StringUtils;
15
16 // Import SPL stuff
17 use \SplFileInfo;
18 use \UnexpectedValueException;
19
20 /**
21  * A Menu template engine class
22  *
23  * @author              Roland Haeder <webmaster@shipsimu.org>
24  * @version             0.0.0
25  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2020 Core Developer Team
26  * @license             GNU GPL 3.0 or any newer version
27  * @link                http://www.shipsimu.org
28  *
29  * This program is free software: you can redistribute it and/or modify
30  * it under the terms of the GNU General Public License as published by
31  * the Free Software Foundation, either version 3 of the License, or
32  * (at your option) any later version.
33  *
34  * This program is distributed in the hope that it will be useful,
35  * but WITHOUT ANY WARRANTY; without even the implied warranty of
36  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37  * GNU General Public License for more details.
38  *
39  * You should have received a copy of the GNU General Public License
40  * along with this program. If not, see <http://www.gnu.org/licenses/>.
41  */
42 class MenuTemplateEngine extends BaseTemplateEngine implements CompileableTemplate {
43         /**
44          * Main nodes in the XML tree ('menu' is ignored)
45          */
46         private $mainNodes = array(
47                 'block-list',
48         );
49
50         /**
51          * Sub nodes in the XML tree
52          */
53         private $subNodes = array(
54                 'entry-list',
55                 'entry',
56                 'entry-id',
57                 'entries-content',
58                 'block-header',
59                 'block-footer',
60                 'footer-id',
61                 'footer-class',
62                 'footer-text',
63                 'block',
64                 'title',
65                 'title-id',
66                 'title-class',
67                 'title-text',
68                 'design',
69                 'text',
70                 'advert',
71                 'anchor',
72                 'anchor-id',
73                 'anchor-text',
74                 'anchor-title',
75                 'anchor-href',
76         );
77
78         /**
79          * Variables for a menu entry
80          */
81         private $menuEntryVariables = array(
82                 // List entry
83                 'entry_id',
84                 // Anchor
85                 'anchor-id',
86                 'anchor-text',
87                 'anchor-title',
88                 'anchor-href',
89         );
90
91         /**
92          * Variables for a menu block
93          */
94         private $menuBlockVariables = array(
95                 // Title
96                 'title_id',
97                 'title_class',
98                 'title_text',
99                 // Content is taken from menuEntries
100                 // Footer
101                 'footer_id',
102                 'footer_class',
103                 'footer_text',
104         );
105
106         /**
107          * Rendered menu entries
108          */
109         private $menuEntries = array();
110
111         /**
112          * Rendered menu blocks
113          */
114         private $menuBlocks = array();
115
116         /**
117          * Menu instance
118          */
119         private $menuInstance = NULL;
120
121         /**
122          * Current main node
123          */
124         private $curr = array();
125
126         /**
127          * Content from dependency
128          */
129         private $dependencyContent = array();
130
131         /**
132          * Protected constructor
133          *
134          * @return      void
135          */
136         protected function __construct () {
137                 // Call parent constructor
138                 parent::__construct(__CLASS__);
139         }
140
141         /**
142          * Creates an instance of the class TemplateEngine and prepares it for usage
143          *
144          * @param       $menuInstance                   A RenderableMenu instance
145          * @return      $templateInstance               An instance of TemplateEngine
146          * @throws      UnexpectedValueException                If the found $templateBasePath is empty or not a string
147          * @throws      InvalidDirectoryException       If $templateBasePath is no directory or not found
148          * @throws      BasePathReadProtectedException  If $templateBasePath is
149          *                                                                                      read-protected
150          */
151         public static final function createMenuTemplateEngine (RenderableMenu $menuInstance) {
152                 // Get a new instance
153                 $templateInstance = new MenuTemplateEngine();
154
155                 // Get the application instance from registry
156                 $applicationInstance = GenericRegistry::getRegistry()->getInstance('application');
157
158                 // Determine base path
159                 $templateBasePath = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('application_base_path') . $applicationInstance->getAppShortName(). '/';
160
161                 // Is the base path valid?
162                 if (empty($templateBasePath)) {
163                         // Base path is empty
164                         throw new UnexpectedValueException(sprintf('[%s:%d] Variable templateBasePath is empty.', $templateInstance->__toString(), __LINE__), self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
165                 } elseif (!is_string($templateBasePath)) {
166                         // Is not a string
167                         throw new UnexpectedValueException(sprintf('[%s:%d] %s is not a string with a base path.', $templateInstance->__toString(), __LINE__, $templateBasePath), self::EXCEPTION_INVALID_STRING);
168                 } elseif (!is_dir($templateBasePath)) {
169                         // Is not a path
170                         throw new InvalidDirectoryException(array($templateInstance, $templateBasePath), self::EXCEPTION_INVALID_PATH_NAME);
171                 } elseif (!is_readable($templateBasePath)) {
172                         // Is not readable
173                         throw new BasePathReadProtectedException(array($templateInstance, $templateBasePath), self::EXCEPTION_READ_PROTECED_PATH);
174                 }
175
176                 // Set the base path
177                 $templateInstance->setTemplateBasePath($templateBasePath);
178
179                 // Set template extensions
180                 $templateInstance->setRawTemplateExtension(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('raw_template_extension'));
181                 $templateInstance->setCodeTemplateExtension(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('menu_template_extension'));
182
183                 // Absolute output path for compiled templates
184                 $templateInstance->setCompileOutputPath(sprintf('%s%s/',
185                         $templateBasePath,
186                         FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('compile_output_path')
187                 ));
188
189                 // Set the menu instance
190                 $templateInstance->setMenuInstance($menuInstance);
191
192                 // Init a variable stacker
193                 $stackInstance = ObjectFactory::createObjectByConfiguredName('menu_stacker_class');
194
195                 // Set it
196                 $templateInstance->setStackInstance($stackInstance);
197
198                 // Return the prepared instance
199                 return $templateInstance;
200         }
201
202         /**
203          * Load a specified menu template into the engine
204          *
205          * @param       $template       The menu template we shall load which is
206          *                                              located in 'menu' by default
207          * @return      void
208          */
209         public function loadMenuTemplate ($template) {
210                 // Set template type
211                 $this->setTemplateType(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('menu_template_type'));
212
213                 // Load the special template
214                 $this->loadTemplate($template);
215         }
216
217         /**
218          * Getter for current main node
219          *
220          * @return      $currMainNode   Current main node
221          */
222         public final function getCurrMainNode () {
223                 return $this->curr['main_node'];
224         }
225
226         /**
227          * Setter for current main node
228          *
229          * @param       $element                Element name to set as current main node
230          * @return      $currMainNode   Current main node
231          */
232         private final function setCurrMainNode ($element) {
233                 $this->curr['main_node'] = (string) $element;
234         }
235
236         /**
237          * Getter for main node array
238          *
239          * @return      $mainNodes      Array with valid main node names
240          */
241         public final function getMainNodes () {
242                 return $this->mainNodes;
243         }
244
245         /**
246          * Getter for sub node array
247          *
248          * @return      $subNodes       Array with valid sub node names
249          */
250         public final function getSubNodes () {
251                 return $this->subNodes;
252         }
253
254         /**
255          * Handles the start element of an XML resource
256          *
257          * @param       $resource               XML parser resource (currently ignored)
258          * @param       $element                The element we shall handle
259          * @param       $attributes             All attributes
260          * @return      void
261          * @throws      InvalidXmlNodeException         If an unknown/invalid XML node name was found
262          */
263         public function startElement ($resource, $element, array $attributes) {
264                 // Initial method name which will never be called...
265                 $methodName = 'initMenu';
266
267                 // Make the element name lower-case
268                 $element = strtolower($element);
269
270                 // Is the element a main node?
271                 //* DEBUG: */ echo "START: &gt;".$element."&lt;<br />\n";
272                 if (in_array($element, $this->getMainNodes())) {
273                         // Okay, main node found!
274                         $methodName = 'start' . StringUtils::convertToClassName($element);
275
276                         // Set it
277                         $this->setCurrMainNode($element);
278                 } elseif (in_array($element, $this->getSubNodes())) {
279                         // Sub node found
280                         $methodName = 'start' . StringUtils::convertToClassName($element);
281                 } elseif ($element != 'menu') {
282                         // Invalid node name found
283                         throw new InvalidXmlNodeException(array($this, $element, $attributes), XmlParser::EXCEPTION_XML_NODE_UNKNOWN);
284                 }
285
286                 // Call method
287                 //* DEBUG: */ echo "call: ".$methodName."<br />\n";
288                 call_user_func_array(array($this, $methodName), $attributes);
289         }
290
291         /**
292          * Ends the main or sub node by sending out the gathered data
293          *
294          * @param       $resource       An XML resource pointer (currently ignored)
295          * @param       $nodeName       Name of the node we want to finish
296          * @return      void
297          * @throws      XmlNodeMismatchException        If current main node mismatches the closing one
298          */
299         public function finishElement ($resource, $nodeName) {
300                 // Make all lower-case
301                 $nodeName = strtolower($nodeName);
302
303                 // Does this match with current main node?
304                 //* DEBUG: */ echo "END: &gt;".$nodeName."&lt;<br />\n";
305                 if (($nodeName != $this->getCurrMainNode()) && (in_array($nodeName, $this->getMainNodes()))) {
306                         // Did not match!
307                         throw new XmlNodeMismatchException (array($this, $nodeName, $this->getCurrMainNode()), XmlParser::EXCEPTION_XML_NODE_MISMATCH);
308                 } // END - if
309
310                 // Construct method name
311                 $methodName = 'finish' . StringUtils::convertToClassName($nodeName);
312
313                 // Call the corresponding method
314                 //* DEBUG: */ echo "call: ".$methodName."<br />\n";
315                 call_user_func_array(array($this, $methodName), array());
316         }
317
318         /**
319          * Currently not used
320          *
321          * @param       $resource               XML parser resource (currently ignored)
322          * @param       $characters             Characters to handle
323          * @return      void
324          * @todo        Find something useful with this!
325          */
326         public function characterHandler ($resource, $characters) {
327                 // Trim all spaces away
328                 $characters = trim($characters);
329
330                 // Is this string empty?
331                 if (empty($characters)) {
332                         // Then skip it silently
333                         return;
334                 } // END - if
335
336                 // Assign the found characters to variable and use the last entry from
337                 // stack as the name
338                 parent::assignVariable($this->getStackInstance()->getNamed('current_node'), $characters);
339         }
340
341         /**
342          * Handles the template dependency for given node
343          *
344          * @param       $node                                   The node we should load a dependency template
345          * @param       $templateDependency             A template to load to satisfy dependencies
346          * @return      void
347          */
348         private function handleTemplateDependency ($node, $templateDependency) {
349                 // Is the template dependency set?
350                 if ((!empty($templateDependency)) && (!isset($this->dependencyContent[$node]))) {
351                         // Get a temporay menu template instance
352                         $templateInstance = ObjectFactory::createObjectByConfiguredName('menu_template_class', array($this->getMenuInstance()));
353
354                         // Then load it
355                         $templateInstance->loadMenuTemplate($templateDependency);
356
357                         // Parse the XML content
358                         $templateInstance->renderXmlContent();
359
360                         // Save the parsed raw content in our dependency array
361                         $this->dependencyContent[$node] = $templateInstance->getRawTemplateData();
362                 } // END - if
363         }
364
365         /**
366          * Intializes the menu
367          *
368          * @param       $templateDependency             A template to load to satisfy dependencies
369          * @return      void
370          * @todo        Add cache creation here
371          */
372         private function initMenu ($templateDependency = '') {
373                 // Get web template engine
374                 $this->setTemplateInstance(ObjectFactory::createObjectByConfiguredName('html_template_class', array(GenericRegistry::getRegistry()->getInstance('application'))));
375
376                 // Handle the dependency template
377                 $this->handleTemplateDependency('menu', $templateDependency);
378
379                 // Push the node name on the stacker
380                 $this->getStackInstance()->pushNamed('current_node', 'menu');
381         }
382
383         /**
384          * Starts the menu entries
385          *
386          * @param       $templateDependency             A template to load to satisfy dependencies
387          * @return      void
388          */
389         private function startEntryList () {
390                 // Push the node name on the stacker
391                 $this->getStackInstance()->pushNamed('current_node', 'entry-list');
392         }
393
394         /**
395          * Starts the menu block header
396          *
397          * @return      void
398          */
399         private function startBlockHeader () {
400                 // Push the node name on the stacker
401                 $this->getStackInstance()->pushNamed('current_node', 'block-header');
402         }
403
404         /**
405          * Starts the menu block footer
406          *
407          * @return      void
408          */
409         private function startBlockFooter () {
410                 // Push the node name on the stacker
411                 $this->getStackInstance()->pushNamed('current_node', 'block-footer');
412         }
413
414         /**
415          * Starts the menu property 'block-list'
416          *
417          * @return      void
418          */
419         private function startBlockList () {
420                 // Push the node name on the stacker
421                 $this->getStackInstance()->pushNamed('current_node', 'block-list');
422         }
423
424         /**
425          * Starts the menu property 'block'
426          *
427          * @return      void
428          */
429         private function startBlock () {
430                 // Push the node name on the stacker
431                 $this->getStackInstance()->pushNamed('current_node', 'block');
432         }
433
434         /**
435          * Starts the menu property 'title'
436          *
437          * @return      void
438          */
439         private function startTitle () {
440                 // Push the node name on the stacker
441                 $this->getStackInstance()->pushNamed('current_node', 'title');
442         }
443
444         /**
445          * Starts the menu property 'title-id'
446          *
447          * @return      void
448          */
449         private function startTitleId () {
450                 // Push the node name on the stacker
451                 $this->getStackInstance()->pushNamed('current_node', 'title-id');
452         }
453
454         /**
455          * Starts the menu property 'title-class'
456          *
457          * @return      void
458          */
459         private function startTitleClass () {
460                 // Push the node name on the stacker
461                 $this->getStackInstance()->pushNamed('current_node', 'title-class');
462         }
463
464         /**
465          * Starts the menu property 'title-text'
466          *
467          * @return      void
468          */
469         private function startTitleText () {
470                 // Push the node name on the stacker
471                 $this->getStackInstance()->pushNamed('current_node', 'title-text');
472         }
473
474         /**
475          * Starts the menu property 'entry'
476          *
477          * @return      void
478          */
479         private function startEntry () {
480                 // Push the node name on the stacker
481                 $this->getStackInstance()->pushNamed('current_node', 'entry');
482         }
483
484         /**
485          * Starts the menu property 'entry-id'
486          *
487          * @return      void
488          */
489         private function startEntryId () {
490                 // Push the node name on the stacker
491                 $this->getStackInstance()->pushNamed('current_node', 'entry-id');
492         }
493
494         /**
495          * Starts the menu property 'anchor'
496          *
497          * @return      void
498          */
499         private function startAnchor () {
500                 // Push the node name on the stacker
501                 $this->getStackInstance()->pushNamed('current_node', 'anchor');
502         }
503
504         /**
505          * Starts the menu property 'anchor-id'
506          *
507          * @return      void
508          */
509         private function startAnchorId () {
510                 // Push the node name on the stacker
511                 $this->getStackInstance()->pushNamed('current_node', 'anchor-id');
512         }
513
514         /**
515          * Starts the menu property 'anchor-text'
516          *
517          * @return      void
518          */
519         private function startAnchorText () {
520                 // Push the node name on the stacker
521                 $this->getStackInstance()->pushNamed('current_node', 'anchor-text');
522         }
523
524         /**
525          * Starts the menu property 'anchor-title'
526          *
527          * @return      void
528          */
529         private function startAnchorTitle () {
530                 // Push the node name on the stacker
531                 $this->getStackInstance()->pushNamed('current_node', 'anchor-title');
532         }
533
534         /**
535          * Starts the menu property 'anchor-href'
536          *
537          * @return      void
538          */
539         private function startAnchorHref () {
540                 // Push the node name on the stacker
541                 $this->getStackInstance()->pushNamed('current_node', 'anchor-href');
542         }
543
544         /**
545          * Starts the menu property 'footer-id'
546          *
547          * @return      void
548          */
549         private function startFooterId () {
550                 // Push the node name on the stacker
551                 $this->getStackInstance()->pushNamed('current_node', 'footer-id');
552         }
553
554         /**
555          * Starts the menu property 'footer-class'
556          *
557          * @return      void
558          */
559         private function startFooterClass () {
560                 // Push the node name on the stacker
561                 $this->getStackInstance()->pushNamed('current_node', 'footer-class');
562         }
563
564         /**
565          * Starts the menu property 'footer-text'
566          *
567          * @return      void
568          */
569         private function startFooterText () {
570                 // Push the node name on the stacker
571                 $this->getStackInstance()->pushNamed('current_node', 'footer-text');
572         }
573
574         /**
575          * Finishes the title node by added another template to the menu
576          *
577          * @return      void
578          */
579         private function finishTitle () {
580                 // Pop the last entry
581                 $this->getStackInstance()->popNamed('current_node');
582         }
583
584         /**
585          * Finishes the title-id node by
586          *
587          * @return      void
588          */
589         private function finishTitleId () {
590                 // Pop the last entry
591                 $this->getStackInstance()->popNamed('current_node');
592         }
593
594         /**
595          * Finishes the title-class node
596          *
597          * @return      void
598          */
599         private function finishTitleClass () {
600                 // Pop the last entry
601                 $this->getStackInstance()->popNamed('current_node');
602         }
603
604         /**
605          * Finishes the title-class node
606          *
607          * @return      void
608          */
609         private function finishTitleText () {
610                 // Pop the last entry
611                 $this->getStackInstance()->popNamed('current_node');
612         }
613
614         /**
615          * Finishes the footer-text node
616          *
617          * @return      void
618          */
619         private function finishFooterText () {
620                 // Pop the last entry
621                 $this->getStackInstance()->popNamed('current_node');
622         }
623
624         /**
625          * Finishes the footer-class node
626          *
627          * @return      void
628          */
629         private function finishFooterClass () {
630                 // Pop the last entry
631                 $this->getStackInstance()->popNamed('current_node');
632         }
633
634         /**
635          * Finishes the footer-id node
636          *
637          * @return      void
638          */
639         private function finishFooterId () {
640                 // Pop the last entry
641                 $this->getStackInstance()->popNamed('current_node');
642         }
643
644         /**
645          * Finishes the anchor-href node
646          *
647          * @return      void
648          */
649         private function finishAnchorHref () {
650                 // Pop the last entry
651                 $this->getStackInstance()->popNamed('current_node');
652         }
653
654         /**
655          * Finishes the anchor-title node
656          *
657          * @return      void
658          */
659         private function finishAnchorTitle () {
660                 // Pop the last entry
661                 $this->getStackInstance()->popNamed('current_node');
662         }
663
664         /**
665          * Finishes the anchor-text node
666          *
667          * @return      void
668          */
669         private function finishAnchorText () {
670                 // Pop the last entry
671                 $this->getStackInstance()->popNamed('current_node');
672         }
673
674         /**
675          * Finishes the anchor-id node
676          *
677          * @return      void
678          */
679         private function finishAnchorId () {
680                 // Pop the last entry
681                 $this->getStackInstance()->popNamed('current_node');
682         }
683
684         /**
685          * Finishes the anchor node
686          *
687          * @return      void
688          */
689         private function finishAnchor () {
690                 // Pop the last entry
691                 $this->getStackInstance()->popNamed('current_node');
692         }
693
694         /**
695          * Finishes the entry-id node
696          *
697          * @return      void
698          */
699         private function finishEntryId () {
700                 // Pop the last entry
701                 $this->getStackInstance()->popNamed('current_node');
702         }
703
704         /**
705          * Finishes the entry node
706          *
707          * @return      void
708          */
709         private function finishEntry () {
710                 // Pop the last entry
711                 $this->getStackInstance()->popNamed('current_node');
712
713                 // Render this menu entry
714                 $this->renderMenuEntry();
715         }
716
717         /**
718          * Finishes the block node
719          *
720          * @return      void
721          */
722         private function finishBlock () {
723                 // Pop the last entry
724                 $this->getStackInstance()->popNamed('current_node');
725
726                 // Render this menu block
727                 $this->renderMenuBlock();
728         }
729
730         /**
731          * Finishes the block-list node
732          *
733          * @return      void
734          */
735         private function finishBlockList () {
736                 // Pop the last entry
737                 $this->getStackInstance()->popNamed('current_node');
738         }
739
740         /**
741          * Finishes the menu entries
742          *
743          * @return      void
744          */
745         private function finishEntryList () {
746                 // Pop the last entry
747                 $this->getStackInstance()->popNamed('current_node');
748         }
749
750         /**
751          * Finishes the menu block header
752          *
753          * @return      void
754          */
755         private function finishBlockHeader () {
756                 // Pop the last entry
757                 $this->getStackInstance()->popNamed('current_node');
758         }
759
760         /**
761          * Finishes the menu block footer
762          *
763          * @return      void
764          */
765         private function finishBlockFooter () {
766                 // Pop the last entry
767                 $this->getStackInstance()->popNamed('current_node');
768         }
769
770         /**
771          * Finishes the menu
772          *
773          * @return      void
774          */
775         private function finishMenu () {
776                 // Pop the last entry
777                 $this->getStackInstance()->popNamed('current_node');
778         }
779
780         /**
781          * Renders this menu entry, as every block all variables got overwritten
782          * with data from next entry.
783          *
784          * @return      void
785          */
786         private function renderMenuEntry () {
787                 // Prepare template engine
788                 $templateInstance = $this->prepareTemplateInstance();
789
790                 // Load menu entry template
791                 $templateInstance->loadCodeTemplate('menu_entry');
792
793                 // Copy all variables over to it
794                 foreach ($this->menuEntryVariables as $variableName) {
795                         // Copy variable
796                         $variableValue = $this->readVariable($variableName);
797
798                         // Is the key 'anchor-href'?
799                         if ($variableName == 'anchor-href') {
800                                 // Expand variable with URL then
801                                 $variableValue = '{?base_url?}/' . $variableValue;
802                         } // END - if
803
804                         // ... into the instance
805                         $templateInstance->assignVariable($variableName, $variableValue);
806                 } // END - foreach
807
808                 // Compile template + variables
809                 $templateInstance->compileTemplate();
810                 $templateInstance->compileVariables();
811
812                 // Remember it here
813                 $this->menuEntries[$this->readVariable('entry_id')] = $templateInstance->getRawTemplateData();
814         }
815
816         /**
817          * Renders this menu block, as next block all data is overwritten with
818          * next block.
819          *
820          * @return      void
821          */
822         private function renderMenuBlock () {
823                 // Init block content
824                 $blockContent = implode('', $this->menuEntries);
825
826                 // Prepare template engine
827                 $templateInstance = $this->prepareTemplateInstance();
828
829                 // Load menu entry template
830                 $templateInstance->loadCodeTemplate('menu_block');
831
832                 // Copy all variables over to it
833                 foreach ($this->menuBlockVariables as $variableName) {
834                         // Copy variable
835                         $variableValue = $this->readVariable($variableName);
836
837                         // ... into the instance
838                         $templateInstance->assignVariable($variableName, $variableValue);
839                 } // END - foreach
840
841                 // Assign block content
842                 $templateInstance->assignVariable('block_content', $blockContent);
843
844                 // Compile template + variables
845                 $templateInstance->compileTemplate();
846                 $templateInstance->compileVariables();
847
848                 // Remember it here
849                 array_push($this->menuBlocks, $templateInstance->getRawTemplateData());
850
851                 // Reset rendered menu entries array
852                 $this->menuEntries = array();
853         }
854
855         /**
856          * "Getter" for menu content
857          *
858          * @return      $menuContent    Returned menu content
859          */
860         public function getMenuContent () {
861                 // Implode menuBlocks
862                 $menuContent = implode('', $this->menuBlocks);
863
864                 // Clean variable
865                 $this->menuBlocks = array();
866
867                 // And return it
868                 return $menuContent;
869         }
870
871         /**
872          * Getter for menu cache file instance
873          *
874          * @return      $fileInstance   Full-qualified file name of the menu cache
875          */
876         public function getMenuCacheFile () {
877                 // Get the application instance from registry
878                 $applicationInstance = GenericRegistry::getRegistry()->getInstance('application');
879
880                 // Get the file instance ready
881                 $fileInstance = new SplFileInfo(sprintf('%s%smenus/_cache/%s.%s',
882                         FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('application_base_path'),
883                         $applicationInstance->getAppShortName(),
884                         md5(
885                                 $this->getMenuInstance()->getMenuName() . ':' .
886                                 $this->__toString() . ':' .
887                                 $this->getMenuInstance()->__toString()
888                         ),
889                         $this->getMenuInstance()->getMenuType()
890                 ));
891
892                 // Return it
893                 return $fileInstance;
894         }
895
896 }