|
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 * The main template view. Should be used as view if you want Fluid Templating 00025 * 00026 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later 00027 * @api 00028 */ 00029 class Tx_Fluid_View_TemplateView extends Tx_Fluid_View_AbstractTemplateView { 00030 00031 /** 00032 * Pattern to be resolved for @templateRoot in the other patterns. 00033 * @var string 00034 */ 00035 protected $templateRootPathPattern = '@packageResourcesPath/Private/Templates'; 00036 00037 /** 00038 * Pattern to be resolved for @partialRoot in the other patterns. 00039 * @var string 00040 */ 00041 protected $partialRootPathPattern = '@packageResourcesPath/Private/Partials'; 00042 00043 /** 00044 * Pattern to be resolved for @layoutRoot in the other patterns. 00045 * @var string 00046 */ 00047 protected $layoutRootPathPattern = '@packageResourcesPath/Private/Layouts'; 00048 00049 /** 00050 * Path to the template root. If NULL, then $this->templateRootPathPattern will be used. 00051 * @var string 00052 */ 00053 protected $templateRootPath = NULL; 00054 00055 /** 00056 * Path to the partial root. If NULL, then $this->partialRootPathPattern will be used. 00057 * @var string 00058 */ 00059 protected $partialRootPath = NULL; 00060 00061 /** 00062 * Path to the layout root. If NULL, then $this->layoutRootPathPattern will be used. 00063 * @var string 00064 */ 00065 protected $layoutRootPath = NULL; 00066 00067 /** 00068 * File pattern for resolving the template file 00069 * @var string 00070 */ 00071 protected $templatePathAndFilenamePattern = '@templateRoot/@subpackage/@controller/@action.@format'; 00072 00073 /** 00074 * Directory pattern for global partials. Not part of the public API, should not be changed for now. 00075 * @var string 00076 */ 00077 private $partialPathAndFilenamePattern = '@partialRoot/@subpackage/@partial.@format'; 00078 00079 /** 00080 * File pattern for resolving the layout 00081 * @var string 00082 */ 00083 protected $layoutPathAndFilenamePattern = '@layoutRoot/@layout.@format'; 00084 00085 /** 00086 * Path and filename of the template file. If set, overrides the templatePathAndFilenamePattern 00087 * @var string 00088 */ 00089 protected $templatePathAndFilename = NULL; 00090 00091 /** 00092 * Path and filename of the layout file. If set, overrides the layoutPathAndFilenamePattern 00093 * @var string 00094 */ 00095 protected $layoutPathAndFilename = NULL; 00096 00097 public function __construct() { 00098 $this->injectTemplateParser(Tx_Fluid_Compatibility_TemplateParserBuilder::build()); 00099 $this->injectObjectManager(t3lib_div::makeInstance('Tx_Extbase_Object_ObjectManager')); 00100 $this->setRenderingContext($this->objectManager->create('Tx_Fluid_Core_Rendering_RenderingContext')); 00101 } 00102 00103 public function initializeView() { 00104 } 00105 00106 // Here, the backporter can insert a constructor method, which is needed for Fluid v4. 00107 00108 /** 00109 * Sets the path and name of of the template file. Effectively overrides the 00110 * dynamic resolving of a template file. 00111 * 00112 * @param string $templatePathAndFilename Template file path 00113 * @return void 00114 * @author Sebastian Kurfürst <sebastian@typo3.org> 00115 * @api 00116 */ 00117 public function setTemplatePathAndFilename($templatePathAndFilename) { 00118 $this->templatePathAndFilename = $templatePathAndFilename; 00119 } 00120 00121 /** 00122 * Sets the path and name of the layout file. Overrides the dynamic resolving of the layout file. 00123 * 00124 * @param string $layoutPathAndFilename Path and filename of the layout file 00125 * @return void 00126 * @author Sebastian Kurfürst <sebastian@typo3.org> 00127 * @api 00128 */ 00129 public function setLayoutPathAndFilename($layoutPathAndFilename) { 00130 $this->layoutPathAndFilename = $layoutPathAndFilename; 00131 } 00132 00133 /** 00134 * Checks whether a template can be resolved for the current request context. 00135 * 00136 * @return boolean 00137 * @author Karsten Dambekalns <karsten@typo3.org> 00138 * @author Sebastian Kurfürst <sebastian@typo3.org> 00139 * @api 00140 */ 00141 public function canRender(Tx_Extbase_MVC_Controller_ControllerContext $controllerContext) { 00142 $this->setControllerContext($controllerContext); 00143 try { 00144 $this->getTemplateSource(); 00145 return TRUE; 00146 } catch (Tx_Fluid_View_Exception_InvalidTemplateResourceException $e) { 00147 return FALSE; 00148 } 00149 } 00150 00151 /** 00152 * Set the root path to the templates. 00153 * If set, overrides the one determined from $this->templateRootPathPattern 00154 * 00155 * @param string $templateRootPath Root path to the templates. If set, overrides the one determined from $this->templateRootPathPattern 00156 * @return void 00157 * @author Sebastian Kurfürst <sebastian@typo3.org> 00158 * @api 00159 */ 00160 public function setTemplateRootPath($templateRootPath) { 00161 $this->templateRootPath = $templateRootPath; 00162 } 00163 00164 /** 00165 * Resolve the template path and filename for the given action. If $actionName 00166 * is NULL, looks into the current request. 00167 * 00168 * @param string $actionName Name of the action. If NULL, will be taken from request. 00169 * @return string Full path to template 00170 * @throws Tx_Fluid_View_Exception_InvalidTemplateResourceException 00171 * @author Sebastian Kurfürst <sebastian@typo3.org> 00172 */ 00173 protected function getTemplateSource($actionName = NULL) { 00174 if ($this->templatePathAndFilename !== NULL) { 00175 $templatePathAndFilename = $this->templatePathAndFilename; 00176 } else { 00177 $actionName = ($actionName !== NULL ? $actionName : $this->controllerContext->getRequest()->getControllerActionName()); 00178 00179 $paths = $this->expandGenericPathPattern($this->templatePathAndFilenamePattern, FALSE, FALSE); 00180 $found = FALSE; 00181 foreach ($paths as &$templatePathAndFilename) { 00182 // These tokens are replaced by the Backporter for the graceful fallback in version 4. 00183 $fallbackPath = str_replace('@action', $actionName, $templatePathAndFilename); 00184 $templatePathAndFilename = str_replace('@action', ucfirst($actionName), $templatePathAndFilename); 00185 if (file_exists($templatePathAndFilename)) { 00186 $found = TRUE; 00187 // additional check for deprecated template filename for case insensitive file systems (Windows) 00188 $realFileName = basename(realpath($templatePathAndFilename)); 00189 if ($realFileName !== ucfirst($realFileName)) { 00190 t3lib_div::deprecationLog('the template filename "' . t3lib_div::fixWindowsFilePath(realpath($templatePathAndFilename)) . '" is lowercase. This is deprecated since TYPO3 4.4. Please rename the template to "' . basename($templatePathAndFilename) . '"'); 00191 } 00192 break; 00193 } elseif (file_exists($fallbackPath)) { 00194 t3lib_div::deprecationLog('the template filename "' . $fallbackPath . '" is lowercase. This is deprecated since TYPO3 4.4. Please rename the template to "' . basename($templatePathAndFilename) . '"'); 00195 $found = TRUE; 00196 $templatePathAndFilename = $fallbackPath; 00197 break; 00198 } 00199 } 00200 if (!$found) { 00201 throw new Tx_Fluid_View_Exception_InvalidTemplateResourceException('Template could not be loaded. I tried "' . implode('", "', $paths) . '"', 1225709595); 00202 } 00203 } 00204 00205 $templateSource = file_get_contents($templatePathAndFilename); 00206 if ($templateSource === FALSE) { 00207 throw new Tx_Fluid_View_Exception_InvalidTemplateResourceException('"' . $templatePathAndFilename . '" is not a valid template resource URI.', 1257246929); 00208 } 00209 return $templateSource; 00210 } 00211 00212 /** 00213 * Resolve the path and file name of the layout file, based on 00214 * $this->layoutPathAndFilename and $this->layoutPathAndFilenamePattern. 00215 * 00216 * In case a layout has already been set with setLayoutPathAndFilename(), 00217 * this method returns that path, otherwise a path and filename will be 00218 * resolved using the layoutPathAndFilenamePattern. 00219 * 00220 * @param string $layoutName Name of the layout to use. If none given, use "default" 00221 * @return string Path and filename of layout file 00222 * @throws Tx_Fluid_View_Exception_InvalidTemplateResourceException 00223 * @author Sebastian Kurfürst <sebastian@typo3.org> 00224 */ 00225 protected function getLayoutSource($layoutName = 'default') { 00226 if ($this->layoutPathAndFilename !== NULL) { 00227 $layoutPathAndFilename = $this->layoutPathAndFilename; 00228 } else { 00229 $paths = $this->expandGenericPathPattern($this->layoutPathAndFilenamePattern, TRUE, TRUE); 00230 $found = FALSE; 00231 foreach ($paths as &$layoutPathAndFilename) { 00232 $layoutPathAndFilename = str_replace('@layout', $layoutName, $layoutPathAndFilename); 00233 if (file_exists($layoutPathAndFilename)) { 00234 $found = TRUE; 00235 break; 00236 } 00237 } 00238 00239 if (!$found) { 00240 throw new Tx_Fluid_View_Exception_InvalidTemplateResourceException('The template files "' . implode('", "', $paths) . '" could not be loaded.', 1225709595); 00241 } 00242 } 00243 00244 $layoutSource = file_get_contents($layoutPathAndFilename); 00245 if ($layoutSource === FALSE) { 00246 throw new Tx_Fluid_View_Exception_InvalidTemplateResourceException('"' . $layoutPathAndFilename . '" is not a valid template resource URI.', 1257246929); 00247 } 00248 return $layoutSource; 00249 } 00250 00251 /** 00252 * Figures out which partial to use. 00253 * 00254 * @param string $partialName The name of the partial 00255 * @return string the full path which should be used. The path definitely exists. 00256 * @throws Tx_Fluid_View_Exception_InvalidTemplateResourceException 00257 * @author Sebastian Kurfürst <sebastian@typo3.org> 00258 */ 00259 protected function getPartialSource($partialName) { 00260 $paths = $this->expandGenericPathPattern($this->partialPathAndFilenamePattern, TRUE, TRUE); 00261 $found = FALSE; 00262 foreach ($paths as &$partialPathAndFilename) { 00263 $partialPathAndFilename = str_replace('@partial', $partialName, $partialPathAndFilename); 00264 if (file_exists($partialPathAndFilename)) { 00265 $found = TRUE; 00266 break; 00267 } 00268 } 00269 if (!$found) { 00270 throw new Tx_Fluid_View_Exception_InvalidTemplateResourceException('The template files "' . implode('", "', $paths) . '" could not be loaded.', 1225709595); 00271 } 00272 $partialSource = file_get_contents($partialPathAndFilename); 00273 if ($partialSource === FALSE) { 00274 throw new Tx_Fluid_View_Exception_InvalidTemplateResourceException('"' . $partialPathAndFilename . '" is not a valid template resource URI.', 1257246929); 00275 } 00276 return $partialSource; 00277 } 00278 00279 /** 00280 * Resolves the template root to be used inside other paths. 00281 * 00282 * @return string Path to template root directory 00283 * @author Sebastian Kurfürst <sebastian@typo3.org> 00284 */ 00285 protected function getTemplateRootPath() { 00286 if ($this->templateRootPath !== NULL) { 00287 return $this->templateRootPath; 00288 } else { 00289 return str_replace('@packageResourcesPath', t3lib_extMgm::extPath($this->controllerContext->getRequest()->getControllerExtensionKey()) . 'Resources/', $this->templateRootPathPattern); 00290 } 00291 } 00292 00293 /** 00294 * Set the root path to the partials. 00295 * If set, overrides the one determined from $this->partialRootPathPattern 00296 * 00297 * @param string $partialRootPath Root path to the partials. If set, overrides the one determined from $this->partialRootPathPattern 00298 * @return void 00299 * @author Bastian Waidelich <bastian@typo3.org> 00300 * @api 00301 */ 00302 public function setPartialRootPath($partialRootPath) { 00303 $this->partialRootPath = $partialRootPath; 00304 } 00305 00306 /** 00307 * Resolves the partial root to be used inside other paths. 00308 * 00309 * @return string Path to partial root directory 00310 * @author Bastian Waidelich <bastian@typo3.org> 00311 */ 00312 protected function getPartialRootPath() { 00313 if ($this->partialRootPath !== NULL) { 00314 return $this->partialRootPath; 00315 } else { 00316 return str_replace('@packageResourcesPath', t3lib_extMgm::extPath($this->controllerContext->getRequest()->getControllerExtensionKey()) . 'Resources/', $this->partialRootPathPattern); 00317 } 00318 } 00319 00320 /** 00321 * Set the root path to the layouts. 00322 * If set, overrides the one determined from $this->layoutRootPathPattern 00323 * 00324 * @param string $layoutRootPath Root path to the layouts. If set, overrides the one determined from $this->layoutRootPathPattern 00325 * @return void 00326 * @author Bastian Waidelich <bastian@typo3.org> 00327 * @api 00328 */ 00329 public function setLayoutRootPath($layoutRootPath) { 00330 $this->layoutRootPath = $layoutRootPath; 00331 } 00332 00333 /** 00334 * Resolves the layout root to be used inside other paths. 00335 * 00336 * @return string Path to layout root directory 00337 * @author Bastian Waidelich <bastian@typo3.org> 00338 */ 00339 protected function getLayoutRootPath() { 00340 if ($this->layoutRootPath !== NULL) { 00341 return $this->layoutRootPath; 00342 } else { 00343 return str_replace('@packageResourcesPath', t3lib_extMgm::extPath($this->controllerContext->getRequest()->getControllerExtensionKey()) . 'Resources/', $this->layoutRootPathPattern); 00344 } 00345 } 00346 00347 /** 00348 * Processes @templateRoot, @subpackage, @controller, and @format placeholders inside $pattern. 00349 * This method is used to generate "fallback chains" for file system locations where a certain Partial can reside. 00350 * 00351 * If $bubbleControllerAndSubpackage is FALSE and $formatIsOptional is FALSE, then the resulting array will only have one element 00352 * with all the above placeholders replaced. 00353 * 00354 * If you set $bubbleControllerAndSubpackage to TRUE, then you will get an array with potentially many elements: 00355 * The first element of the array is like above. The second element has the @controller part set to "" (the empty string) 00356 * The third element now has the @controller part again stripped off, and has the last subpackage part stripped off as well. 00357 * This continues until both @subpackage and @controller are empty. 00358 * 00359 * Example for $bubbleControllerAndSubpackage is TRUE, we have the Tx_Fluid_MySubPackage_Controller_MyController as Controller Object Name and the current format is "html" 00360 * If pattern is @templateRoot/@controller/@action.@format, then the resulting array is: 00361 * - Resources/Private/Templates/MySubPackage/My/@action.html 00362 * - Resources/Private/Templates/MySubPackage/@action.html 00363 * - Resources/Private/Templates/@action.html 00364 * 00365 * If you set $formatIsOptional to TRUE, then for any of the above arrays, every element will be duplicated - once with @format 00366 * replaced by the current request format, and once with .@format stripped off. 00367 * 00368 * @param string $pattern Pattern to be resolved 00369 * @param boolean $bubbleControllerAndSubpackage if TRUE, then we successively split off parts from @controller and @subpackage until both are empty. 00370 * @param boolean $formatIsOptional if TRUE, then half of the resulting strings will have .@format stripped off, and the other half will have it. 00371 * @return array unix style path 00372 * @author Sebastian Kurfürst <sebastian@typo3.org> 00373 * @author Robert Lemke <robert@typo3.org> 00374 */ 00375 protected function expandGenericPathPattern($pattern, $bubbleControllerAndSubpackage, $formatIsOptional) { 00376 $pattern = str_replace('@templateRoot', $this->getTemplateRootPath(), $pattern); 00377 $pattern = str_replace('@partialRoot', $this->getPartialRootPath(), $pattern); 00378 $pattern = str_replace('@layoutRoot', $this->getLayoutRootPath(), $pattern); 00379 00380 $subpackageKey = $this->controllerContext->getRequest()->getControllerSubpackageKey(); 00381 $controllerName = $this->controllerContext->getRequest()->getControllerName(); 00382 00383 $subpackageParts = ($subpackageKey !== NULL) ? explode(Tx_Fluid_Fluid::NAMESPACE_SEPARATOR, $subpackageKey) : array(); 00384 00385 $results = array(); 00386 00387 $i = ($controllerName === NULL) ? 0 : -1; 00388 do { 00389 $temporaryPattern = $pattern; 00390 if ($i < 0) { 00391 $temporaryPattern = str_replace('@controller', $controllerName, $temporaryPattern); 00392 } else { 00393 $temporaryPattern = str_replace('//', '/', str_replace('@controller', '', $temporaryPattern)); 00394 } 00395 $temporaryPattern = str_replace('@subpackage', implode('/', ($i<0 ? $subpackageParts : array_slice($subpackageParts, $i))), $temporaryPattern); 00396 00397 $results[] = t3lib_div::fixWindowsFilePath(str_replace('@format', $this->controllerContext->getRequest()->getFormat(), $temporaryPattern)); 00398 if ($formatIsOptional) { 00399 $results[] = t3lib_div::fixWindowsFilePath(str_replace('.@format', '', $temporaryPattern)); 00400 } 00401 00402 } while($i++ < count($subpackageParts) && $bubbleControllerAndSubpackage); 00403 return $results; 00404 } 00405 00406 } 00407 00408 ?>
1.8.0