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()); }
/** * 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; }