Example #1
0
 /**
  * Recursively handles the included templates (just the non dynamic ones).
  *
  * @param TemplateProviderInterface $provider
  * @param                           $source
  *
  * @return Layout
  * @throws HtplException
  */
 private function handleIncludes(TemplateProviderInterface $provider, $source)
 {
     $includes = TagLexer::parse($source)->select('w-include');
     $parsedTemplates = 0;
     foreach ($includes as $i) {
         $ext = substr($i['attributes']['file'], -5);
         if ($ext == '.htpl' || $ext == '.html') {
             // join the includes with the main template
             $includedTemplate = $provider->getSource($i['attributes']['file']);
             $source = preg_replace('/(\\s+|)' . preg_quote($i['outerHtml'], '/') . '(\\s+|)/', $includedTemplate, $source);
             // add the template to include list
             $this->includedFiles[$i['attributes']['file']] = $provider->createdOn($i['attributes']['file']);
             $parsedTemplates++;
         }
     }
     if (count($includes) < 1 || $parsedTemplates < 1) {
         return new Layout($source, $this->includedFiles);
     }
     return $this->handleIncludes($provider, $source);
 }
Example #2
0
 /**
  * @throws \Webiny\Htpl\HtplException
  * @expectedException \Webiny\Htpl\HtplException
  * @expectedExceptionMessage Unable to parse the template
  */
 public function testParseException()
 {
     $tpl = '<w-foo>
                 some content
             </w-bar>';
     $result = TagLexer::parse($tpl)->getLexedTags();
     $this->assertSame(0, count($result));
 }
Example #3
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;
 }