|
TYPO3 API
SVNRelease
|
00001 <?php 00002 00003 /* * 00004 * This script belongs to the FLOW3 package "Fluid". * 00005 * * 00006 * It is free software; you can redistribute it and/or modify it under * 00007 * the terms of the GNU Lesser General Public License as published by the * 00008 * Free Software Foundation, either version 3 of the License, or (at your * 00009 * option) any later version. * 00010 * * 00011 * This script is distributed in the hope that it will be useful, but * 00012 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- * 00013 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * 00014 * General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU Lesser General Public * 00017 * License along with the script. * 00018 * If not, see http://www.gnu.org/licenses/lgpl.html * 00019 * * 00020 * The TYPO3 project - inspiring people to share! * 00021 * */ 00022 00023 /** 00024 * Abstract Fluid Template View. 00025 * 00026 * Contains the fundamental methods which any Fluid based template view needs. 00027 * 00028 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later 00029 */ 00030 abstract class Tx_Fluid_View_AbstractTemplateView implements Tx_Extbase_MVC_View_ViewInterface { 00031 00032 /** 00033 * Constants defining possible rendering types 00034 */ 00035 const RENDERING_TEMPLATE = 1; 00036 const RENDERING_PARTIAL = 2; 00037 const RENDERING_LAYOUT = 3; 00038 00039 /** 00040 * @var Tx_Extbase_MVC_Controller_ControllerContext 00041 */ 00042 protected $controllerContext; 00043 00044 /** 00045 * @var Tx_Extbase_Object_ObjectManagerInterface 00046 */ 00047 protected $objectManager; 00048 00049 /** 00050 * @var Tx_Fluid_Core_Parser_TemplateParser 00051 */ 00052 protected $templateParser; 00053 00054 /** 00055 * The initial rendering context for this template view. 00056 * Due to the rendering stack, another rendering context might be active 00057 * at certain points while rendering the template. 00058 * 00059 * @var Tx_Fluid_Core_Rendering_RenderingContextInterface 00060 */ 00061 protected $baseRenderingContext; 00062 00063 /** 00064 * Stack containing the current rendering type, the current rendering context, and the current parsed template 00065 * Do not manipulate directly, instead use the methods"getCurrent*()", "startRendering(...)" and "stopRendering()" 00066 * @var array 00067 */ 00068 protected $renderingStack = array(); 00069 00070 /** 00071 * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager 00072 * @return void 00073 * @author Robert Lemke <robert@typo3.org> 00074 */ 00075 public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) { 00076 $this->objectManager = $objectManager; 00077 } 00078 00079 /** 00080 * Inject the Template Parser 00081 * 00082 * @param Tx_Fluid_Core_Parser_TemplateParser $templateParser The template parser 00083 * @return void 00084 * @author Sebastian Kurfürst <sebastian@typo3.org> 00085 */ 00086 public function injectTemplateParser(Tx_Fluid_Core_Parser_TemplateParser $templateParser) { 00087 $this->templateParser = $templateParser; 00088 } 00089 00090 /** 00091 * Injects a fresh rendering context 00092 * 00093 * @param Tx_Fluid_Core_Rendering_RenderingContextInterface $renderingContext 00094 * @return void 00095 * @author Robert Lemke <robert@typo3.org> 00096 */ 00097 public function setRenderingContext(Tx_Fluid_Core_Rendering_RenderingContextInterface $renderingContext) { 00098 $this->baseRenderingContext = $renderingContext; 00099 $this->baseRenderingContext->getViewHelperVariableContainer()->setView($this); 00100 $this->controllerContext = $renderingContext->getControllerContext(); 00101 } 00102 00103 /** 00104 * Sets the current controller context 00105 * 00106 * @param Tx_Extbase_MVC_Controller_ControllerContext $controllerContext 00107 * @return void 00108 * @author Robert Lemke <robert@typo3.org> 00109 * @api 00110 */ 00111 public function setControllerContext(Tx_Extbase_MVC_Controller_ControllerContext $controllerContext) { 00112 $this->controllerContext = $controllerContext; 00113 } 00114 00115 public function initializeView() { 00116 } 00117 // Here, the backporter can insert the initializeView method, which is needed for Fluid v4. 00118 00119 /** 00120 * Assign a value to the variable container. 00121 * 00122 * @param string $key The key of a view variable to set 00123 * @param mixed $value The value of the view variable 00124 * @return Tx_Fluid_View_AbstractTemplateView the instance of this view to allow chaining 00125 * @author Robert Lemke <robert@typo3.org> 00126 * @api 00127 */ 00128 public function assign($key, $value) { 00129 $templateVariableContainer = $this->baseRenderingContext->getTemplateVariableContainer(); 00130 if ($templateVariableContainer->exists($key)) { 00131 $templateVariableContainer->remove($key); 00132 } 00133 $templateVariableContainer->add($key, $value); 00134 return $this; 00135 } 00136 00137 /** 00138 * Assigns multiple values to the JSON output. 00139 * However, only the key "value" is accepted. 00140 * 00141 * @param array $values Keys and values - only a value with key "value" is considered 00142 * @return Tx_Fluid_View_AbstractTemplateView the instance of this view to allow chaining 00143 * @author Robert Lemke <robert@typo3.org> 00144 * @api 00145 */ 00146 public function assignMultiple(array $values) { 00147 $templateVariableContainer = $this->baseRenderingContext->getTemplateVariableContainer(); 00148 foreach ($values as $key => $value) { 00149 if ($templateVariableContainer->exists($key)) { 00150 $templateVariableContainer->remove($key); 00151 } 00152 $templateVariableContainer->add($key, $value); 00153 } 00154 return $this; 00155 } 00156 00157 /** 00158 * Loads the template source and render the template. 00159 * If "layoutName" is set in a PostParseFacet callback, it will render the file with the given layout. 00160 * 00161 * @param string $actionName If set, the view of the specified action will be rendered instead. Default is the action specified in the Request object 00162 * @return string Rendered Template 00163 * @author Sebastian Kurfürst <sebastian@typo3.org> 00164 * @author Robert Lemke <robert@typo3.org> 00165 * @api 00166 */ 00167 public function render($actionName = NULL) { 00168 $this->baseRenderingContext->setControllerContext($this->controllerContext); 00169 $this->templateParser->setConfiguration($this->buildParserConfiguration()); 00170 $parsedTemplate = $this->templateParser->parse($this->getTemplateSource($actionName)); 00171 00172 if ($this->isLayoutDefinedInTemplate($parsedTemplate)) { 00173 $this->startRendering(self::RENDERING_LAYOUT, $parsedTemplate, $this->baseRenderingContext); 00174 $parsedLayout = $this->templateParser->parse($this->getLayoutSource($this->getLayoutNameInTemplate($parsedTemplate))); 00175 $output = $parsedLayout->render($this->baseRenderingContext); 00176 $this->stopRendering(); 00177 } else { 00178 $this->startRendering(self::RENDERING_TEMPLATE, $parsedTemplate, $this->baseRenderingContext); 00179 $output = $parsedTemplate->render($this->baseRenderingContext); 00180 $this->stopRendering(); 00181 } 00182 00183 return $output; 00184 } 00185 00186 /** 00187 * Renders a given section. 00188 * 00189 * @param string $sectionName Name of section to render 00190 * @param array $variables the variables to use. 00191 * @return string rendered template for the section 00192 * @throws Tx_Fluid_View_Exception_InvalidSectionException 00193 * @author Sebastian Kurfürst <sebastian@typo3.org> 00194 * @author Bastian Waidelich <bastian@typo3.org> 00195 */ 00196 public function renderSection($sectionName, array $variables) { 00197 $parsedTemplate = $this->getCurrentParsedTemplate(); 00198 00199 $sections = $parsedTemplate->getVariableContainer()->get('sections'); 00200 if(!array_key_exists($sectionName, $sections)) { 00201 throw new Tx_Fluid_View_Exception_InvalidSectionException('The given section does not exist!', 1227108982); 00202 } 00203 $section = $sections[$sectionName]; 00204 00205 $renderingContext = $this->getCurrentRenderingContext(); 00206 if ($this->getCurrentRenderingType() === self::RENDERING_LAYOUT) { 00207 // in case we render a layout right now, we will render a section inside a TEMPLATE. 00208 $renderingTypeOnNextLevel = self::RENDERING_TEMPLATE; 00209 } else { 00210 $variableContainer = $this->objectManager->create('Tx_Fluid_Core_ViewHelper_TemplateVariableContainer', $variables); 00211 $renderingContext = clone $renderingContext; 00212 $renderingContext->setTemplateVariableContainer($variableContainer); 00213 $renderingTypeOnNextLevel = $this->getCurrentRenderingType(); 00214 } 00215 00216 $renderingContext->getViewHelperVariableContainer()->add('Tx_Fluid_ViewHelpers_SectionViewHelper', 'isCurrentlyRenderingSection', 'TRUE'); 00217 00218 $this->startRendering($renderingTypeOnNextLevel, $parsedTemplate, $renderingContext); 00219 $output = $section->evaluate($renderingContext); 00220 $this->stopRendering(); 00221 00222 return $output; 00223 } 00224 00225 /** 00226 * Renders a partial. 00227 * 00228 * @param string $partialName 00229 * @param string $sectionName 00230 * @param array $variables 00231 * @param Tx_Fluid_Core_ViewHelper_ViewHelperVariableContainer $viewHelperVariableContainer the View Helper Variable container to use. 00232 * @return string 00233 * @author Sebastian Kurfürst <sebastian@typo3.org> 00234 * @author Bastian Waidelich <bastian@typo3.org> 00235 * @author Robert Lemke <robert@typo3.org> 00236 */ 00237 public function renderPartial($partialName, $sectionName, array $variables) { 00238 $partial = $this->templateParser->parse($this->getPartialSource($partialName)); 00239 $variableContainer = $this->objectManager->create('Tx_Fluid_Core_ViewHelper_TemplateVariableContainer', $variables); 00240 $renderingContext = clone $this->getCurrentRenderingContext(); 00241 $renderingContext->setTemplateVariableContainer($variableContainer); 00242 00243 $this->startRendering(self::RENDERING_PARTIAL, $partial, $renderingContext); 00244 if ($sectionName !== NULL) { 00245 $output = $this->renderSection($sectionName, $variables); 00246 } else { 00247 $output = $partial->render($renderingContext); 00248 } 00249 $this->stopRendering(); 00250 00251 return $output; 00252 } 00253 00254 /** 00255 * Resolve the template path and filename for the given action. If $actionName 00256 * is NULL, looks into the current request. 00257 * 00258 * @param string $actionName Name of the action. If NULL, will be taken from request. 00259 * @return string Full path to template 00260 * @throws Tx_Fluid_View_Exception_InvalidTemplateResourceException in case the template was not found 00261 */ 00262 abstract protected function getTemplateSource($actionName = NULL); 00263 00264 /** 00265 * Resolve the path and file name of the layout file, based on 00266 * $this->layoutPathAndFilename and $this->layoutPathAndFilenamePattern. 00267 * 00268 * In case a layout has already been set with setLayoutPathAndFilename(), 00269 * this method returns that path, otherwise a path and filename will be 00270 * resolved using the layoutPathAndFilenamePattern. 00271 * 00272 * @param string $layoutName Name of the layout to use. If none given, use "default" 00273 * @return string Path and filename of layout file 00274 * @throws Tx_Fluid_View_Exception_InvalidTemplateResourceException 00275 */ 00276 abstract protected function getLayoutSource($layoutName = 'default'); 00277 00278 /** 00279 * Figures out which partial to use. 00280 * 00281 * @param string $partialName The name of the partial 00282 * @return string the full path which should be used. The path definitely exists. 00283 * @throws Tx_Fluid_View_Exception_InvalidTemplateResourceException 00284 */ 00285 abstract protected function getPartialSource($partialName); 00286 00287 /** 00288 * Build parser configuration 00289 * 00290 * @return Tx_Fluid_Core_Parser_Configuration 00291 * @author Karsten Dambekalns <karsten@typo3.org> 00292 */ 00293 protected function buildParserConfiguration() { 00294 $parserConfiguration = $this->objectManager->create('Tx_Fluid_Core_Parser_Configuration'); 00295 if ($this->controllerContext->getRequest()->getFormat() === 'html') { 00296 $parserConfiguration->addInterceptor($this->objectManager->get('Tx_Fluid_Core_Parser_Interceptor_Escape')); 00297 00298 } 00299 return $parserConfiguration; 00300 } 00301 00302 /** 00303 * Returns TRUE if there is a layout defined in the given template via a <f:layout name="..." /> tag. 00304 * 00305 * @param Tx_Fluid_Core_Parser_ParsedTemplateInterface $parsedTemplate 00306 * @return boolean TRUE if a layout has been defined, FALSE otherwise. 00307 * @author Sebastian Kurfürst <sebastian@typo3.org> 00308 */ 00309 protected function isLayoutDefinedInTemplate(Tx_Fluid_Core_Parser_ParsedTemplateInterface $parsedTemplate) { 00310 $variableContainer = $parsedTemplate->getVariableContainer(); 00311 return ($variableContainer !== NULL && $variableContainer->exists('layoutName')); 00312 } 00313 00314 /** 00315 * Returns the name of the layout defined in the template, if one exists. 00316 * 00317 * @param Tx_Fluid_Core_Parser_ParsedTemplateInterface $parsedTemplate 00318 * @return string the Layout name 00319 * @author Sebastian Kurfürst <sebastian@typo3.org> 00320 */ 00321 protected function getLayoutNameInTemplate(Tx_Fluid_Core_Parser_ParsedTemplateInterface $parsedTemplate) { 00322 if ($this->isLayoutDefinedInTemplate($parsedTemplate)) { 00323 return $parsedTemplate->getVariableContainer()->get('layoutName'); 00324 } 00325 return NULL; 00326 } 00327 00328 /** 00329 * Start a new nested rendering. Pushes the given information onto the $renderingStack. 00330 * 00331 * @param int $type one of the RENDERING_* constants 00332 * @param Tx_Fluid_Core_Parser_ParsedTemplateInterface $parsedTemplate 00333 * @param Tx_Fluid_Core_Rendering_RenderingContextInterface $renderingContext 00334 * @return void 00335 * @author Sebastian Kurfürst <sebastian@typo3.org> 00336 */ 00337 protected function startRendering($type, Tx_Fluid_Core_Parser_ParsedTemplateInterface $parsedTemplate, Tx_Fluid_Core_Rendering_RenderingContextInterface $renderingContext) { 00338 array_push($this->renderingStack, array('type' => $type, 'parsedTemplate' => $parsedTemplate, 'renderingContext' => $renderingContext)); 00339 } 00340 00341 /** 00342 * Stops the current rendering. Removes one element from the $renderingStack. Make sure to always call this 00343 * method pair-wise with startRendering(). 00344 * 00345 * @return void 00346 * @author Sebastian Kurfürst <sebastian@typo3.org> 00347 */ 00348 protected function stopRendering() { 00349 array_pop($this->renderingStack); 00350 } 00351 00352 /** 00353 * Get the current rendering type. 00354 * 00355 * @return one of RENDERING_* constants 00356 * @author Sebastian Kurfürst <sebastian@typo3.org> 00357 */ 00358 protected function getCurrentRenderingType() { 00359 $currentRendering = end($this->renderingStack); 00360 return $currentRendering['type']; 00361 } 00362 00363 /** 00364 * Get the parsed template which is currently being rendered. 00365 * 00366 * @return Tx_Fluid_Core_Parser_ParsedTemplateInterface 00367 * @author Sebastian Kurfürst <sebastian@typo3.org> 00368 */ 00369 protected function getCurrentParsedTemplate() { 00370 $currentRendering = end($this->renderingStack); 00371 return $currentRendering['parsedTemplate']; 00372 } 00373 00374 /** 00375 * Get the rendering context which is currently used. 00376 * 00377 * @return Tx_Fluid_Core_Rendering_RenderingContextInterface 00378 * @author Sebastian Kurfürst <sebastian@typo3.org> 00379 */ 00380 protected function getCurrentRenderingContext() { 00381 $currentRendering = end($this->renderingStack); 00382 return $currentRendering['renderingContext']; 00383 } 00384 00385 /** 00386 * Tells if the view implementation can render the view for the given context. 00387 * 00388 * By default we assume that the view implementation can handle all kinds of 00389 * contexts. Override this method if that is not the case. 00390 * 00391 * @param Tx_Extbase_MVC_Controller_ControllerContext $controllerContext 00392 * @return boolean TRUE if the view has something useful to display, otherwise FALSE 00393 * @api 00394 */ 00395 public function canRender(Tx_Extbase_MVC_Controller_ControllerContext $controllerContext) { 00396 return TRUE; 00397 } 00398 00399 } 00400 00401 ?>
1.8.0