/** * Render the presentation and return the result. * * @param AgaviTemplateLayer The template layer to render. * @param array The template variables. * @param array The slots. * @param array Associative array of additional assigns. * * @return string A rendered result. * * @author David Zülke <*****@*****.**> * @since 1.0.6 */ public function render(AgaviTemplateLayer $layer, array &$attributes = array(), array &$slots = array(), array &$moreAssigns = array()) { $twig = $this->getEngine(); $path = $layer->getResourceStreamIdentifier(); if ($layer instanceof AgaviFileTemplateLayer) { $pathinfo = pathinfo($path); // set the directory the template is in as the first path to load from, and the directory set on the layer second // that way, including another template inside this template will look at e.g. a locale subdirectory first before falling back to the originally defined folder $paths = array($pathinfo['dirname'], $layer->getParameter('directory')); // also allow loading from the main template dir by default, and any other directories the user has set through configuration foreach ((array) $this->getParameter('template_dirs', array(AgaviConfig::get('core.template_dir'))) as $dir) { $paths[] = $dir; } $twig->setLoader(new Twig_Loader_Filesystem($paths)); $source = $pathinfo['basename']; } else { // a stream template or whatever; either way, it's something Twig can't load directly :S $twig->setLoader(new Twig_Loader_String()); $source = file_get_contents($path); } $template = $twig->loadTemplate($source); $data = array(); // template vars if ($this->extractVars) { foreach ($attributes as $name => $value) { $data[$name] = $value; } } else { $data[$this->varName] = $attributes; } // slots $data[$this->slotsVarName] = $slots; // dynamic assigns (global ones were set in getEngine()) $finalMoreAssigns = self::buildMoreAssigns($moreAssigns, $this->moreAssignNames); foreach ($finalMoreAssigns as $key => $value) { $data[$key] = $value; } return $template->render($data); }
/** * Render the presentation and return the result. * * @param AgaviTemplateLayer The template layer to render. * @param array The template variables. * @param array The slots. * @param array Associative array of additional assigns. * * @return string A rendered result. */ public function render(AgaviTemplateLayer $layer, array &$attributes = array(), array &$slots = array(), array &$moreAssigns = array()) { $engine = $this->getEngine(); $data = array(); if ($this->extractVars) { $data = $attributes; } else { $data[$this->varName] =& $attributes; } $data[$this->slotsVarName] =& $slots; foreach ($this->assigns as $key => $getter) { $data[$key] = $this->getContext()->{$getter}(); } foreach ($moreAssigns as $key => &$value) { if (isset($this->moreAssignNames[$key])) { $key = $this->moreAssignNames[$key]; } $data[$key] =& $value; } return $engine->get($layer->getResourceStreamIdentifier(), $data); }
/** * Render the presentation and return the result. * * @param AgaviTemplateLayer The template layer to render. * @param array The template variables. * @param array The slots. * @param array Associative array of additional assigns. * * @return string A rendered result. * * @author David Zülke <*****@*****.**> * @since 1.1.0 */ public function render(AgaviTemplateLayer $layer, array &$attributes = array(), array &$slots = array(), array &$moreAssigns = array()) { if ($this->getParameter('envelope', true)) { if (!$moreAssigns['inner'] instanceof DOMDocument) { // plain text, load it as a document try { $inner = $this->loadDomDocumentXml($moreAssigns['inner']); } catch (DOMException $e) { throw new AgaviRenderException(sprintf("Unable to load input document for layer '%s'.\n\n%s", $layer->getName(), $e->getMessage())); } } else { $inner = $moreAssigns['inner']; } // construct envelope $doc = new DOMDocument(); $doc->appendChild($doc->createElementNS(self::ENVELOPE_XMLNS, 'envelope')); // inner content container $doc->documentElement->appendChild($innerWrapper = $doc->createElementNS(self::ENVELOPE_XMLNS, 'inner')); $innerWrapper->appendChild($doc->importNode($inner->documentElement, true)); // slots container $slotsWrapper = $doc->createElementNS(self::ENVELOPE_XMLNS, 'slots'); $doc->documentElement->appendChild($slotsWrapper); // flatten slots, iterate and wrap them each $flattenedSlots = AgaviArrayPathDefinition::flatten($slots); foreach ($flattenedSlots as $slotName => $slotContent) { if (!$slotContent instanceof DOMDocument) { try { $slot = $this->loadDomDocumentXml($slotContent); } catch (Exception $e) { throw new AgaviRenderException(sprintf("Unable to load contents for slot '%s'.\n\n%s", $slotName, $e->getMessage())); } } else { $slot = $slotContent; } $slotWrapper = $doc->createElementNS(self::ENVELOPE_XMLNS, 'slot'); $slotWrapper->setAttribute('name', $slotName); $slotWrapper->appendChild($doc->importNode($slot->documentElement, true)); $slotsWrapper->appendChild($slotWrapper); } } else { if (!$moreAssigns['inner'] instanceof DOMDocument) { // plain text, load it as a document $doc = $this->loadDomDocumentXml($moreAssigns['inner']); } else { $doc = $moreAssigns['inner']; } // This will pretty much never work, so we're not doing it. Users must enable the envelope feature to use slots. // Warning: XSLTProcessor::transformToXml() [xsltprocessor.transformtoxml]: Cannot create XPath expression (string contains both quote and double-quotes) // $flattenedSlots = AgaviArrayPathDefinition::flatten($slots); // foreach($flattenedSlots as $slotName => $slotContent) { // if($slotContent instanceof DOMDocument) { // $slotContent = $slotContent->saveXML(); // } // $xsl->setParameter('', 'slot:' . $slotName, addslashes($slotContent)); // } } try { $xslt = $this->loadDomDocument($layer->getResourceStreamIdentifier()); } catch (DOMException $e) { throw new AgaviRenderException(sprintf("Unable to load template '%s'.\n\n%s", $layer->getResourceStreamIdentifier(), $e->getMessage())); } $xsl = new XSLTProcessor(); $xsl->importStylesheet($xslt); foreach ($attributes as $name => $attribute) { if (is_scalar($attribute) || is_object($attribute) && method_exists($attribute, '__toString')) { $xsl->setParameter('', $name, $attribute); } } return $xsl->transformToXML($doc); }
/** * Constructor. * * @param array Initial parameters. * * @author David Zülke <*****@*****.**> * @since 0.11.0 */ public function __construct(array $parameters = array()) { parent::__construct(array_merge(array('check' => false, 'scheme' => null, 'targets' => array('${template}')), $parameters)); }
/** * Render the presentation and return the result. * * @param AgaviTemplateLayer The template layer to render. * @param array The template variables. * @param array The slots. * @param array Associative array of additional assigns. * * @return string A rendered result. * * @author Felix Weis <*****@*****.**> * @since 0.11.0 */ public function render(AgaviTemplateLayer $layer, array &$attributes = array(), array &$slots = array(), array &$moreAssigns = array()) { $engine = $this->getEngine(); if ($this->extractVars) { foreach ($attributes as $name => &$value) { $engine->send->{$name} = $value; } } else { $engine->send->{$this->varName} = $attributes; } $key = $this->slotsVarName; $engine->send->{$key} = $slots; foreach ($this->assigns as $key => $getter) { $engine->send->{$key} = $this->context->{$getter}(); } $finalMoreAssigns =& self::buildMoreAssigns($moreAssigns, $this->moreAssignNames); foreach ($finalMoreAssigns as $key => &$value) { $engine->send->{$key} = $value; } return $engine->process($layer->getResourceStreamIdentifier()); }
/** * Render the presentation and return the result. * * @param AgaviTemplateLayer The template layer to render. * @param array The template variables. * @param array The slots. * @param array Associative array of additional assigns. * * @return string A rendered result. * * @author David Zülke <*****@*****.**> * @since 0.11.0 */ public function render(AgaviTemplateLayer $layer, array &$attributes = array(), array &$slots = array(), array &$moreAssigns = array()) { $engine = $this->getEngine(); if ($this->extractVars) { foreach ($attributes as $name => &$value) { $engine->assign_by_ref($name, $value); } } else { $engine->assign_by_ref($this->varName, $attributes); } $engine->assign_by_ref($this->slotsVarName, $slots); foreach ($this->assigns as $key => $getter) { $engine->assign($key, $this->context->{$getter}()); } $finalMoreAssigns =& self::buildMoreAssigns($moreAssigns, $this->moreAssignNames); foreach ($finalMoreAssigns as $key => &$value) { $engine->assign_by_ref($key, $value); } // hack because stupid smarty cannot handle php streams... my god $resource = str_replace('://', ':', $layer->getResourceStreamIdentifier()); return $engine->fetch($resource); }