/**
  <code>{{ block }}</code> variable handler.
  Hooked into @c parseVariableExpression:postCodeGen.
 */
 public function handleHBlockVariable(TemplateCompilerEx $compiler, TemplateNodeEx $node, &$variableCode, &$variableCheck)
 {
     if (isset($compiler->varInBlock) && $compiler->varInBlock && mb_strpos($variableCode, '[\'block\'][\'super\']') !== false) {
         $compiler->raiseIf(!isset($compiler->metadata['parentTemplate']), $node, 'Invalid use of "block.super" - no parent template', TemplateError::E_INVALID_SYNTAX);
         $variableCode = 'parent::_' . TemplateUtils::sanitize(end($compiler->varInBlock)) . '($e)';
         $variableCheck = '';
     }
     return false;
 }
 /**
  Compiles given template into output package.
  
  @param[in] $io Used I/O driver
  @param[in] $template %Template name
 */
 public function compile(ITemplateIODriver $io, $template)
 {
     $this->reset();
     if (($tpl = $io->loadTemplate($this->settings, $template)) === false) {
         throw new TemplateError('Could not load template "' . $in . '"', TemplateError::E_IO_LOAD_FAILURE);
     }
     $this->className = $io->className($this->settings, $template);
     $this->parserCurrentFile = $template;
     $this->metadata['usedIO'] = $io->driverID;
     $genAST = $this->createAST($tpl);
     $genCode = $this->generateCode($genAST);
     // determine template's parent class
     $classCode = '<?php class ' . $this->className . ' extends ';
     if (isset($this->metadata['parentTemplate'])) {
         list($parentIO, $parent) = TemplateUtils::parseIODSN($this->settings, $this->metadata['parentTemplate']);
         $classCode .= $parentIO->className($this->settings, $parent);
         // main content is ignored, when template extends another
         unset($genCode['main']);
     } else {
         $classCode .= 'Template';
     }
     $classCode .= '{';
     foreach ($genCode as $blockName => &$blockCode) {
         $classCode .= 'function _' . TemplateUtils::sanitize($blockName) . '($e){';
         // TODO: is constructor support really needed?
         if ($blockName == '_constructor') {
             $classCode .= 'parent::__constructor();';
         }
         $classCode .= $blockCode . '}';
     }
     $classCode .= '}';
     if ($io->saveMetadata($this->settings, $template, $this->metadata) === false) {
         throw new TemplateError('Could not save template metadata (compiled from "' . $template . '")', TemplateError::E_IO_SAVE_FAILURE);
     }
     if ($io->saveTemplate($this->settings, $template, $classCode) === false) {
         throw new TemplateError('Could not save template code (compiled from "' . $template . '").', TemplateError::E_IO_SAVE_FAILURE);
     }
 }
 /**
  Tests the behaviour of @ref TemplateUtils::sanitize.
 */
 public function testUtilsSanitize()
 {
     $this->assertEquals('f__123b_r', TemplateUtils::sanitize('fó#123b+r'));
 }