Пример #1
0
 public function testGetLayout4HtmlInclude()
 {
     $tpl = '<w-layout template="master.htpl">';
     $tpl .= '<w-block name="content">';
     $tpl .= '<w-include file="HTMLInclude.html"/>';
     $tpl .= 'Test content</w-block>';
     $tpl .= '</w-layout>';
     $layout = '<html><body><w-block name="content"></w-block></body>';
     $includedFile = 'This is <div>{var}</div> HTML. ';
     $provider = new ArrayProvider(['test.htpl' => $tpl, 'master.htpl' => $layout, 'HTMLInclude.html' => $includedFile]);
     $result = LayoutTree::getLayout($provider, 'test.htpl');
     $this->assertSame('<html><body>This is <div>{var}</div> HTML. Test content</body>', $result->getSource());
 }
Пример #2
0
 /**
  * Method that does the actual compiling.
  *
  * @param string $templateName Template name that should be compiled.
  *
  * @return Layout Compiled template in form of a string.
  * @throws HtplException
  */
 private function compileLayout($templateName)
 {
     // before we can do the template compile, we need to solve the template inheritance
     $layout = LayoutTree::getLayout($this->htpl->getTemplateProvider(), $templateName);
     $template = $layout->getSource();
     // validate that the raw template doesn't contain any PHP code
     if (strpos($template, '<?') !== false) {
         throw new HtplException(sprintf('Template "%s" contains PHP tags which are not allowed.', $templateName));
     }
     // strip out w-literal content before parsing any tags or variables
     $literals = TagLexer::parse($template)->select('w-literal');
     $literalReplacements = [];
     foreach ($literals as $l) {
         $id = '<!-- htpl: w-literal => ' . uniqid() . ' -->';
         $literalReplacements[$id] = $l['content'];
         $template = str_replace($l['outerHtml'], $id, $template);
     }
     // parse the variables
     $template = VarLexer::parse($template, $this->htpl);
     // get a list of possible functions (tags) that we support
     $functions = $this->htpl->getFunctions();
     $lexedTemplate = TagLexer::parse($template);
     foreach ($functions as $tag => $callback) {
         $tags = $lexedTemplate->select($tag);
         foreach ($tags as $t) {
             $lexedTemplate = TagLexer::parse($template);
             $currentMatch = $lexedTemplate->select($tag);
             if (count($currentMatch) < 1) {
                 continue;
             } else {
                 $currentMatch = $currentMatch[0];
             }
             $content = $currentMatch['content'];
             $attributes = isset($currentMatch['attributes']) ? $currentMatch['attributes'] : [];
             try {
                 // extract the opening and closing tag
                 $outerContent = str_replace($currentMatch['content'], '', $currentMatch['outerHtml']);
                 $closingTag = '</' . $tag . '>';
                 $openingTag = str_replace($closingTag, '', $outerContent);
                 $instance = new $callback();
                 $result = $instance->parseTag($content, $attributes, $this->htpl);
                 if (!$result) {
                     continue;
                 }
                 // check if we have context defined
                 $contextStart = '';
                 $contextEnd = '';
                 if (isset($result['contexts'])) {
                     foreach ($result['contexts'] as $c) {
                         $contextStart .= '<!-- htpl-context-start:' . $c . ' -->' . "\n";
                         $contextEnd = '<!-- htpl-context-end:' . $c . ' -->' . "\n" . $contextEnd;
                     }
                 }
                 // do the replacement
                 if (isset($result['content'])) {
                     $replacement = $contextStart . $result['openingTag'] . $result['content'] . $result['closingTag'] . $contextEnd;
                     // we replace with offset 1 cause, we always do the replacement on the current template instance
                     //$template = str_replace($currentMatch['outerHtml'], $replacement, $template);
                     $template = preg_replace('/(\\s+|)' . preg_quote($currentMatch['outerHtml'], '/') . '(\\s+|)/', $replacement, $template);
                 } else {
                     $replacement = $contextStart . $result['openingTag'] . $currentMatch['content'] . $result['closingTag'] . $contextEnd;
                     $template = preg_replace('/(\\s+|)' . preg_quote($currentMatch['outerHtml'], '/') . '(\\s+|)/', $replacement, $template);
                     /*
                     //$template = str_replace($openingTag, $result['openingTag'], $template);
                     $template = preg_replace('/(\s+|)' . preg_quote($openingTag, '/') . '(\s+|)/',
                         $result['openingTag'], $template);
                     if (isset($result['closingTag'])) {
                         //$template = str_replace($closingTag, $result['closingTag'], $template);
                         $template = preg_replace('/(\s+|)' . preg_quote($closingTag, '/') . '(\s+|)/',
                             $result['closingTag'], $template);
                     }
                     */
                 }
             } catch (HtplException $e) {
                 throw new HtplException('Htpl in unable to parse your template near: ' . $openingTag . "\n\n " . $e->getMessage());
             }
         }
     }
     // adjust contexts
     $template = $this->adjustContexts($template);
     // optimize template execution
     /*$template = preg_replace('/\?>(\s+|)\<\?php/', "\n", $template);*/
     // put back the literals
     foreach ($literalReplacements as $lrId => $lrVal) {
         $template = str_replace($lrId, $lrVal, $template);
     }
     // save the new source
     $layout->setSource($template);
     return $layout;
 }