TYPO3 CMS  TYPO3_6-2
AbstractTemplateView.php
Go to the documentation of this file.
1 <?php
3 
4 /* *
5  * This script is backported from the TYPO3 Flow package "TYPO3.Fluid". *
6  * *
7  * It is free software; you can redistribute it and/or modify it under *
8  * the terms of the GNU Lesser General Public License, either version 3 *
9  * of the License, or (at your option) any later version. *
10  * *
11  * The TYPO3 project - inspiring people to share! *
12  * */
13 
20 
24  const RENDERING_TEMPLATE = 1;
25  const RENDERING_PARTIAL = 2;
26  const RENDERING_LAYOUT = 3;
27 
31  protected $controllerContext;
32 
37  protected $objectManager;
38 
43  protected $templateParser;
44 
48  protected $templateCompiler;
49 
58 
65  protected $renderingStack = array();
66 
74  protected $partialIdentifierCache = array();
75 
80  public function injectTemplateCompiler(\TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler) {
81  $this->templateCompiler = $templateCompiler;
82  $this->templateCompiler->setTemplateCache(\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Cache\\CacheManager')->getCache('fluid_template'));
83  }
84 
91  public function setRenderingContext(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
92  $this->baseRenderingContext = $renderingContext;
93  $this->baseRenderingContext->getViewHelperVariableContainer()->setView($this);
94  $this->controllerContext = $renderingContext->getControllerContext();
95  }
96 
104  public function setControllerContext(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext) {
105  $this->controllerContext = $controllerContext;
106  }
107 
108  public function initializeView() {
109  }
110  // Here, the backporter can insert the initializeView method, which is needed for Fluid v4.
111 
120  public function assign($key, $value) {
121  $templateVariableContainer = $this->baseRenderingContext->getTemplateVariableContainer();
122  if ($templateVariableContainer->exists($key)) {
123  $templateVariableContainer->remove($key);
124  }
125  $templateVariableContainer->add($key, $value);
126  return $this;
127  }
128 
137  public function assignMultiple(array $values) {
138  $templateVariableContainer = $this->baseRenderingContext->getTemplateVariableContainer();
139  foreach ($values as $key => $value) {
140  if ($templateVariableContainer->exists($key)) {
141  $templateVariableContainer->remove($key);
142  }
143  $templateVariableContainer->add($key, $value);
144  }
145  return $this;
146  }
147 
156  public function render($actionName = NULL) {
157  $this->baseRenderingContext->setControllerContext($this->controllerContext);
158  $this->templateParser->setConfiguration($this->buildParserConfiguration());
159 
160  $templateIdentifier = $this->getTemplateIdentifier($actionName);
161  if ($this->templateCompiler->has($templateIdentifier)) {
162  $parsedTemplate = $this->templateCompiler->get($templateIdentifier);
163  } else {
164  $parsedTemplate = $this->templateParser->parse($this->getTemplateSource($actionName));
165  if ($parsedTemplate->isCompilable()) {
166  $this->templateCompiler->store($templateIdentifier, $parsedTemplate);
167  }
168  }
169 
170  if ($parsedTemplate->hasLayout()) {
171  $layoutName = $parsedTemplate->getLayoutName($this->baseRenderingContext);
172  $layoutIdentifier = $this->getLayoutIdentifier($layoutName);
173  if ($this->templateCompiler->has($layoutIdentifier)) {
174  $parsedLayout = $this->templateCompiler->get($layoutIdentifier);
175  } else {
176  $parsedLayout = $this->templateParser->parse($this->getLayoutSource($layoutName));
177  if ($parsedLayout->isCompilable()) {
178  $this->templateCompiler->store($layoutIdentifier, $parsedLayout);
179  }
180  }
181  $this->startRendering(self::RENDERING_LAYOUT, $parsedTemplate, $this->baseRenderingContext);
182  $output = $parsedLayout->render($this->baseRenderingContext);
183  $this->stopRendering();
184  } else {
185  $this->startRendering(self::RENDERING_TEMPLATE, $parsedTemplate, $this->baseRenderingContext);
186  $output = $parsedTemplate->render($this->baseRenderingContext);
187  $this->stopRendering();
188  }
189 
190  return $output;
191  }
192 
202  public function renderSection($sectionName, array $variables, $ignoreUnknown = FALSE) {
203  $renderingContext = $this->getCurrentRenderingContext();
204  if ($this->getCurrentRenderingType() === self::RENDERING_LAYOUT) {
205  // in case we render a layout right now, we will render a section inside a TEMPLATE.
206  $renderingTypeOnNextLevel = self::RENDERING_TEMPLATE;
207  } else {
208  $variableContainer = $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\ViewHelper\\TemplateVariableContainer', $variables);
209  $renderingContext = clone $renderingContext;
210  $renderingContext->injectTemplateVariableContainer($variableContainer);
211  $renderingTypeOnNextLevel = $this->getCurrentRenderingType();
212  }
213 
214  $parsedTemplate = $this->getCurrentParsedTemplate();
215 
216  if ($parsedTemplate->isCompiled()) {
217  $methodNameOfSection = 'section_' . sha1($sectionName);
218  if ($ignoreUnknown && !method_exists($parsedTemplate, $methodNameOfSection)) {
219  return '';
220  }
221  $this->startRendering($renderingTypeOnNextLevel, $parsedTemplate, $renderingContext);
222  $output = $parsedTemplate->{$methodNameOfSection}($renderingContext);
223  $this->stopRendering();
224  } else {
225  $sections = $parsedTemplate->getVariableContainer()->get('sections');
226  if (!array_key_exists($sectionName, $sections)) {
227  $controllerObjectName = $this->controllerContext->getRequest()->getControllerObjectName();
228  if ($ignoreUnknown) {
229  return '';
230  } else {
231  throw new \TYPO3\CMS\Fluid\View\Exception\InvalidSectionException(sprintf('Could not render unknown section "%s" in %s used by %s.', $sectionName, get_class($this), $controllerObjectName), 1227108982);
232  }
233  }
234  $section = $sections[$sectionName];
235 
236  $renderingContext->getViewHelperVariableContainer()->add('TYPO3\\CMS\\Fluid\\ViewHelpers\\SectionViewHelper', 'isCurrentlyRenderingSection', 'TRUE');
237 
238  $this->startRendering($renderingTypeOnNextLevel, $parsedTemplate, $renderingContext);
239  $output = $section->evaluate($renderingContext);
240  $this->stopRendering();
241  }
242 
243  return $output;
244  }
245 
255  public function renderPartial($partialName, $sectionName, array $variables) {
256  $partialNameWithFormat = $partialName . '.' . $this->controllerContext->getRequest()->getFormat();
257  if (!isset($this->partialIdentifierCache[$partialNameWithFormat])) {
258  $this->partialIdentifierCache[$partialNameWithFormat] = $this->getPartialIdentifier($partialName);
259  }
260  $partialIdentifier = $this->partialIdentifierCache[$partialNameWithFormat];
261 
262  if ($this->templateCompiler->has($partialIdentifier)) {
263  $parsedPartial = $this->templateCompiler->get($partialIdentifier);
264  } else {
265  $parsedPartial = $this->templateParser->parse($this->getPartialSource($partialName));
266  if ($parsedPartial->isCompilable()) {
267  $this->templateCompiler->store($partialIdentifier, $parsedPartial);
268  }
269  }
270 
271  $variableContainer = $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\ViewHelper\\TemplateVariableContainer', $variables);
272  $renderingContext = clone $this->getCurrentRenderingContext();
273  $renderingContext->injectTemplateVariableContainer($variableContainer);
274 
275  $this->startRendering(self::RENDERING_PARTIAL, $parsedPartial, $renderingContext);
276  if ($sectionName !== NULL) {
277  $output = $this->renderSection($sectionName, $variables);
278  } else {
279  $output = $parsedPartial->render($renderingContext);
280  }
281  $this->stopRendering();
282 
283  return $output;
284  }
285 
293  abstract protected function getTemplateIdentifier($actionName = NULL);
294 
303  abstract protected function getTemplateSource($actionName = NULL);
304 
312  abstract protected function getLayoutIdentifier($layoutName = 'Default');
313 
326  abstract protected function getLayoutSource($layoutName = 'Default');
327 
335  abstract protected function getPartialIdentifier($partialName);
336 
344  abstract protected function getPartialSource($partialName);
345 
351  protected function buildParserConfiguration() {
352  $parserConfiguration = $this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Parser\\Configuration');
353  if ($this->controllerContext->getRequest()->getFormat() === 'html') {
354  $parserConfiguration->addInterceptor($this->objectManager->get('TYPO3\\CMS\\Fluid\\Core\\Parser\\Interceptor\\Escape'));
355  }
356  return $parserConfiguration;
357  }
358 
367  protected function startRendering($type, \TYPO3\CMS\Fluid\Core\Parser\ParsedTemplateInterface $parsedTemplate, \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext) {
368  array_push($this->renderingStack, array('type' => $type, 'parsedTemplate' => $parsedTemplate, 'renderingContext' => $renderingContext));
369  }
370 
377  protected function stopRendering() {
378  array_pop($this->renderingStack);
379  }
380 
386  protected function getCurrentRenderingType() {
387  $currentRendering = end($this->renderingStack);
388  return $currentRendering['type'];
389  }
390 
396  protected function getCurrentParsedTemplate() {
397  $currentRendering = end($this->renderingStack);
398  return $currentRendering['parsedTemplate'];
399  }
400 
406  protected function getCurrentRenderingContext() {
407  $currentRendering = end($this->renderingStack);
408  return $currentRendering['renderingContext'];
409  }
410 
421  public function canRender(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext) {
422  return TRUE;
423  }
424 }
canRender(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext)
getLayoutSource($layoutName='Default')
setRenderingContext(\TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext)
renderPartial($partialName, $sectionName, array $variables)
getLayoutIdentifier($layoutName='Default')
setControllerContext(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext)
injectTemplateCompiler(\TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler)
startRendering($type, \TYPO3\CMS\Fluid\Core\Parser\ParsedTemplateInterface $parsedTemplate, \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext)
renderSection($sectionName, array $variables, $ignoreUnknown=FALSE)