/** * This function parses the os-template and os-data script tags. * It's of vital importance to call this function *before* the rewriteContent function * since the html/dom parser of the later breaks, mangles and otherwise destroys the * os template/data script tags. So we need to expand the templates to pure html * before we can proceeed to dom parse the resulting document * * @param string $content html to parse * @return string */ public function parseTemplates($content) { $osTemplates = array(); $osDataRequests = array(); // First extract all the os-data tags, and execute those in a single combined request, saves latency // and is consistent with other server implementations preg_match_all('/(<script[^>]*type="text\\/(os-data)"[^>]*>)(.*)(<\\/script>)/imsxU', $content, $osDataRequests); $osDataRequestsCombined = ''; foreach ($osDataRequests[0] as $match) { $osDataRequestsCombined .= $match . "\n"; // Remove the reference from the html document $content = str_replace($match, '', $content); } if (!empty($osDataRequestsCombined)) { $this->performDataRequests($osDataRequestsCombined); } preg_match_all('/(<script[^>]*type="text\\/(os-template)"[^>]*>)(.*)(<\\/script>)/imxsU', $content, $osTemplates); $templateLibrary = false; if (count($osTemplates[0])) { // only load the template parser if there's any templates in the gadget content require_once 'src/gadgets/templates/TemplateParser.php'; require_once 'src/gadgets/templates/TemplateLibrary.php'; $templateLibrary = new TemplateLibrary($this->gadget->gadgetContext); if ($this->gadget->gadgetSpec->templatesRequireLibraries) { foreach ($this->gadget->gadgetSpec->templatesRequireLibraries as $library) { $templateLibrary->addTemplateLibrary($library); } } foreach ($osTemplates[0] as $match) { if (!$this->gadget->gadgetSpec->templatesDisableAutoProcessing && ($renderedTemplate = $this->renderTemplate($match, $templateLibrary)) !== false) { // Template was rendered, insert the rendered html into the document $content = str_replace($match, $renderedTemplate, $content); } else { /* * The template could not be rendered, this could happen because: * - @require is present, and at least one of the required pieces of data is unavailable * - @name is present * - @autoUpdate == true * - $this->gadget->gadgetSpec->templatesDisableAutoProcessing is set to true * So set a magic marker (<template_$index>) that after the dom document parsing will be replaced with the original script content */ $index = count($this->unparsedTemplates); $this->unparsedTemplates[$index] = $match; $content = str_replace($match, "<template_{$index}></template_{$index}>", $content); } } } return $content; }