[+BUGFIX] Fluid (View): Refactored TemplateView, which is now automatically backporte...
authorSebastian Kurfürst <sebastian@typo3.org>
Mon, 3 Aug 2009 10:52:32 +0000 (10:52 +0000)
committerSebastian Kurfürst <sebastian@typo3.org>
Mon, 3 Aug 2009 10:52:32 +0000 (10:52 +0000)
[+FEATURE] Fluid: Added Layout and Partial support. This adds <f:render>, <f:layout> and <f:section> as ViewHelpers. See the blog example for an example.
[!!!] [~TASK] Fluid (ViewHelpers): Updated AbstractFormViewHelper and SelectViewHelper. Everything should still work as expected, but here there might still be some issues. Please test thoroughly and report any problems!

13 files changed:
typo3/sysext/fluid/Classes/Compatibility/ObjectFactory.php
typo3/sysext/fluid/Classes/View/TemplateView.php
typo3/sysext/fluid/Classes/View/TemplateViewInterface.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Form/AbstractFormViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/HiddenViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/SelectViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/SubmitViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/TextareaViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/TextboxViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/UploadViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/LayoutViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/RenderViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/SectionViewHelper.php [new file with mode: 0644]

index f15545c..4f9f4f0 100644 (file)
@@ -27,6 +27,9 @@
 class Tx_Fluid_Compatibility_ObjectFactory implements t3lib_Singleton {
 
        protected $injectors = array(
+               'Tx_Fluid_ViewHelpers_Form_AbstractFormViewHelper' => array(
+                       'injectPersistenceManager' => 'Tx_Extbase_Persistence_Manager'
+               ),
                'Tx_Fluid_Core_ViewHelper_AbstractViewHelper' => array(
                        'injectValidatorResolver' => 'Tx_Extbase_Validation_ValidatorResolver',
                        'injectReflectionService' => 'Tx_Extbase_Reflection_Service'
index 04f36fa..0b6a6ff 100644 (file)
@@ -1,57 +1,68 @@
 <?php
 
 /*                                                                        *
- * This script is part of the TYPO3 project - inspiring people to share!  *
+ * This script belongs to the FLOW3 package "Fluid".                      *
  *                                                                        *
- * TYPO3 is free software; you can redistribute it and/or modify it under *
- * the terms of the GNU General Public License version 2 as published by  *
- * the Free Software Foundation.                                          *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version.                                             *
  *                                                                        *
  * This script is distributed in the hope that it will be useful, but     *
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
- * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General      *
- * Public License for more details.                                       *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
 
 /**
- * @package
- * @subpackage
- * @version $Id:$
+ * The main template view. Should be used as view if you want Fluid Templating
+ *
+ * @version $Id: TemplateView.php 2960 2009-08-01 10:13:10Z sebastian $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  */
+class Tx_Fluid_View_TemplateView extends Tx_Extbase_MVC_View_AbstractView implements Tx_Fluid_View_TemplateViewInterface {
 
-class Tx_Fluid_View_TemplateView extends Tx_Extbase_MVC_View_AbstractView {
+       /**
+        * Pattern for fetching information from controller object name
+        * @var string
+        */
+       protected $PATTERN_CONTROLLER = '/^TxFLUID_NAMESPACE_SEPARATOR\w*FLUID_NAMESPACE_SEPARATOR(?:(?P<SubpackageName>.*)FLUID_NAMESPACE_SEPARATOR)?ControllerFLUID_NAMESPACE_SEPARATOR(?P<ControllerName>\w*)Controller$/';
 
+       /**
+        * @var Tx_Fluid_Core_Parser_TemplateParser
+        */
        protected $templateParser;
 
-       protected $objectFactory;
-
-       public function __construct() {
-               $this->templateParser = Tx_Fluid_Compatibility_TemplateParserBuilder::build();
-               $this->objectFactory = t3lib_div::makeInstance('Tx_Fluid_Compatibility_ObjectFactory');
-       }
        /**
-        * Pattern for fetching information from controller object name
+        * Pattern to be resolved for @templateRoot in the other patterns.
         * @var string
         */
-       const PATTERN_CONTROLLER = '/^Tx_\w*_(?:(?P<SubpackageName>.*)_)?Controller_(?P<ControllerName>\w*)Controller$/';
+       protected $templateRootPathPattern = '@packageResources/Private';
 
        /**
         * File pattern for resolving the template file
         * @var string
         */
-       protected $templatePathAndFilenamePattern = '@packageResources/Private/Templates/@subpackage@controller/@action.html';
+       protected $templatePathAndFilenamePattern = '@templateRoot/Templates/@controller/@action.@format';
 
        /**
         * Directory pattern for global partials. Not part of the public API, should not be changed for now.
         * @var string
         * @internal
         */
-       private $globalPartialBasePath = '@packageResources/Private/Templates';
+       private $partialPathAndFilenamePattern = '@templateRoot/Partials/@partial.@format';
 
        /**
-        * @var array
+        * File pattern for resolving the layout
+        * @var string
         */
-       protected $contextVariables = array();
+       protected $layoutPathAndFilenamePattern = '@templateRoot/Layouts/@layout.@format';
 
        /**
         * Path and filename of the template file. If set,  overrides the templatePathAndFilenamePattern
@@ -65,36 +76,31 @@ class Tx_Fluid_View_TemplateView extends Tx_Extbase_MVC_View_AbstractView {
         */
        protected $layoutPathAndFilename = NULL;
 
-       /**
-        * Name of current action to render
-        * @var string
-        */
-       protected $actionName;
-
-       /**
-        * Settings
-        * @var array
-        */
-       protected $settings;
+       public function __construct() {
+                                               $this->templateParser = Tx_Fluid_Compatibility_TemplateParserBuilder::build();
+                                               $this->objectFactory = t3lib_div::makeInstance('Tx_Fluid_Compatibility_ObjectFactory');
+                                       }
+       // Here, the backporter can insert a constructor method, which is needed for Fluid v4.
 
        /**
-        * Initialize view
+        * Inject the template parser
         *
+        * @param Tx_Fluid_Core_Parser_TemplateParser $templateParser The template parser
         * @return void
         * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
-       public function initializeView() {
+       public function injectTemplateParser(Tx_Fluid_Core_Parser_TemplateParser $templateParser) {
+               $this->templateParser = $templateParser;
        }
 
        /**
-        * Inject the settings
+        * Initialize view
         *
-        * @param array $settings Settings
         * @return void
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
         */
-       public function injectSettings($settings) {
-               $this->settings = $settings;
+       public function initializeView() {
        }
 
        /**
@@ -104,18 +110,31 @@ class Tx_Fluid_View_TemplateView extends Tx_Extbase_MVC_View_AbstractView {
         * @param string $templatePathAndFilename Template file path
         * @return void
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
         */
        public function setTemplatePathAndFilename($templatePathAndFilename) {
                $this->templatePathAndFilename = $templatePathAndFilename;
        }
 
+       /**
+        * Sets the path and name of the layout file. Overrides the dynamic resolving of the layout file.
+        *
+        * @param string $layoutPathAndFilename Path and filename of the layout file
+        * @return void
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
+        */
+       public function setLayoutPathAndFilename($layoutPathAndFilename) {
+               $this->layoutPathAndFilename = $layoutPathAndFilename;
+       }
 
        /**
         * Build the rendering context
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        protected function buildRenderingContext($variableContainer = NULL) {
                if ($variableContainer === NULL) {
-                       $variableContainer = $this->objectFactory->create('Tx_Fluid_Core_ViewHelper_TemplateVariableContainer', $this->contextVariables);
+                       $variableContainer = $this->objectFactory->create('Tx_Fluid_Core_ViewHelper_TemplateVariableContainer', $this->viewData);
                }
                $renderingConfiguration = $this->objectFactory->create('Tx_Fluid_Core_Rendering_RenderingConfiguration');
                $renderingConfiguration->setObjectAccessorPostProcessor($this->objectFactory->create('Tx_Fluid_Core_Rendering_HTMLSpecialCharsPostProcessor'));
@@ -139,100 +158,146 @@ class Tx_Fluid_View_TemplateView extends Tx_Extbase_MVC_View_AbstractView {
         * @param string $actionName If set, the view of the specified action will be rendered instead. Default is the action specified in the Request object
         * @return string Rendered Template
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
         */
        public function render($actionName = NULL) {
-               $this->contextVariables['settings'] = $this->settings;
-               $this->actionName = $actionName;
+               $templatePathAndFilename = $this->resolveTemplatePathAndFilename($actionName);
 
-               $parsedTemplate = $this->parseTemplate($this->resolveTemplatePathAndFilename());
+               $parsedTemplate = $this->parseTemplate($templatePathAndFilename);
 
-               /*$variableContainer = $parsedTemplate->getVariableContainer();
+               $variableContainer = $parsedTemplate->getVariableContainer();
                if ($variableContainer !== NULL && $variableContainer->exists('layoutName')) {
                        return $this->renderWithLayout($variableContainer->get('layoutName'));
-               }*/
+               }
+
                $renderingContext = $this->buildRenderingContext();
                return $parsedTemplate->render($renderingContext);
        }
 
        /**
-        * Renders a partial. If $partialName starts with /, the partial is resolved globally. Else, locally.
-        * SHOULD NOT BE USED BY USERS!
-        * @internal
+        * Resolve the template path and filename for the given action. If action is null, looks into the current request.
+        *
+        * @param string $actionName Name of the action. If NULL, will be taken from request.
+        * @return string Full path to template
         * @author Sebastian Kurfürst <sebastian@typo3.org>
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
-/*     public function renderPartial($partialName, $sectionToRender, array $variables) {
-               if ($partialName[0] === '/') {
-                       $partialBasePath = str_replace('@package', $this->packageManager->getPackagePath($this->request->getControllerPackageKey()), $this->globalPartialBasePath);
-                       $partialName = substr($partialName, 1);
-               } else {
-                       $partialBasePath = dirname($this->resolveTemplatePathAndFilename());
+       protected function resolveTemplatePathAndFilename($actionName = NULL) {
+               if ($this->templatePathAndFilename !== NULL) {
+                       return $this->templatePathAndFilename;
                }
-               $partialNameSplitted = explode('/', $partialName);
-               $partialFileName = '_' . array_pop($partialNameSplitted) . '.html';
-               $partialDirectoryName = $partialBasePath . '/' . implode('/', $partialNameSplitted);
-
-               $partialPathAndFileName = $partialDirectoryName . '/' . $partialFileName;
 
-               $partial = $this->parseTemplate($partialPathAndFileName);
-               $syntaxTree = $partial->getRootNode();
+               $actionName = ($actionName !== NULL ? $actionName : $this->controllerContext->getRequest()->getControllerActionName());
+               $actionName = strtolower($actionName);
 
-               $variables['view'] = $this;
-               $variableContainer = $this->objectFactory->create('Tx_Fluid_Core_VariableContainer', $variables);
+               $paths = $this->expandGenericPathPattern($this->templatePathAndFilenamePattern, FALSE, FALSE);
 
-               if ($sectionToRender !== NULL) {
-                       $sections = $partial->getVariableContainer()->get('sections');
-                       if(!array_key_exists($sectionToRender, $sections)) {
-                               throw new \F3\Fluid\Core\RuntimeException('The given section does not exist!', 1227108983);
+               foreach ($paths as $key => $path) {
+                       $path = str_replace('@action', $actionName, $path);
+                       if (file_exists($path)) {
+                               return $path;
                        }
-                       $syntaxTree = $sections[$sectionToRender];
-               } else {
-                       $syntaxTree = $partial->getRootNode();
                }
-               $syntaxTree->setVariableContainer($variableContainer);
-               return $syntaxTree->render();
-       }*/
+               throw new Tx_Fluid_Core_RuntimeException('The template files "' . implode('", "', $paths) . '" could not be loaded.', 1225709595);
+       }
+
+
 
        /**
-        * Add a variable to the context.
-        * Can be chained, so $template->addVariable(..., ...)->addVariable(..., ...); is possible,
+        * Renders a given section.
         *
-        * @param string $key Key of variable
-        * @param object $value Value of object
-        * @return \F3\Fluid\View\TemplateView an instance of $this, to enable chaining.
+        * @param string $sectionName Name of section to render
+        * @return rendered template for the section
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @author Bastian Waidelich <bastian@typo3.org>
         */
-       public function assign($key, $value) {
-               if ($key === 'view') throw new Tx_Fluid_Core_RuntimeException('The variable "view" cannot be set using assign().', 1233317880);
-               $this->contextVariables[$key] = $value;
-               return $this;
+       public function renderSection($sectionName) {
+               $parsedTemplate = $this->parseTemplate($this->resolveTemplatePathAndFilename());
+
+               $templateTree = $parsedTemplate->getRootNode();
+
+               $sections = $parsedTemplate->getVariableContainer()->get('sections');
+               if(!array_key_exists($sectionName, $sections)) {
+                       throw new Tx_Fluid_Core_RuntimeException('The given section does not exist!', 1227108982);
+               }
+               $section = $sections[$sectionName];
+
+               $renderingContext = $this->buildRenderingContext();
+               $section->setRenderingContext($renderingContext);
+               return $section->evaluate();
        }
 
        /**
-        * Return the current request
+        * Render a template with a given layout.
         *
-        * @return \F3\FLOW3\MVC\Web\Request the current request
+        * @param string $layoutName Name of layout
+        * @return string rendered HTML
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @author Bastian Waidelich <bastian@typo3.org>
         */
-       public function getRequest() {
-               return $this->request;
+       public function renderWithLayout($layoutName) {
+               $parsedTemplate = $this->parseTemplate($this->resolveLayoutPathAndFilename($layoutName));
+
+               $renderingContext = $this->buildRenderingContext();
+               return $parsedTemplate->render($renderingContext);
        }
 
        /**
-        * Parse the given template and return it.
+        * Resolve the path and file name of the layout fil, based on $this->layoutPathAndFilename and
+        * $this->layoutPathAndFilenamePattern.
         *
-        * Will cache the results for one call.
+        * In case a layout has already been set with setLayoutPathAndFilename(), this method returns that
+        * path, otherwise a path and filename will be resolved using the layoutPathAndFilenamePattern.
         *
-        * @param $templatePathAndFilename absolute filename of the template to be parsed
-        * @return \F3\Fluid\Core\ParsedTemplateInterface the parsed template tree
+        * @param string $layoutName Name of the layout to use. If none given, use "default"
+        * @return string Path and filename of layout file
         * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
-       protected function parseTemplate($templatePathAndFilename) {
-               $templateSource = file_get_contents($templatePathAndFilename, FILE_TEXT);
-               if ($templateSource === FALSE) {
-                       throw new Tx_Fluid_Core_RuntimeException('The template file "' . $templatePathAndFilename . '" could not be loaded.', 1225709595);
+       protected function resolveLayoutPathAndFilename($layoutName = 'default') {
+               if ($this->layoutPathAndFilename) {
+                       return $this->layoutPathAndFilename;
                }
-               return $this->templateParser->parse($templateSource);
+
+               $paths = $this->expandGenericPathPattern($this->layoutPathAndFilenamePattern, TRUE, TRUE);
+               foreach ($paths as $key => $path) {
+                       $path = str_replace('@layout', $layoutName, $path);
+                       if (file_exists($path)) {
+                               return $path;
+                       }
+               }
+               throw new Tx_Fluid_Core_RuntimeException('The template files "' . implode('", "', $paths) . '" could not be loaded.', 1225709595);
+       }
+
+       /**
+        * Renders a partial.
+        * SHOULD NOT BE USED BY USERS!
+        *
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @author Bastian Waidelich <bastian@typo3.org>
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function renderPartial($partialName, $sectionToRender, array $variables) {
+               $partial = $this->parseTemplate($this->resolvePartialPathAndFilename($partialName));
+               $variableContainer = $this->objectFactory->create('Tx_Fluid_Core_ViewHelper_TemplateVariableContainer', $variables);
+               $renderingContext = $this->buildRenderingContext($variableContainer);
+               return $partial->render($renderingContext);
+       }
+
+       /**
+        * Figures out which partial to use.
+        *
+        * @param string $partialName The name of the partial
+        * @return string the full path which should be used. The path definitely exists.
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       protected function resolvePartialPathAndFilename($partialName) {
+               $paths = $this->expandGenericPathPattern($this->partialPathAndFilenamePattern, TRUE, TRUE);
+               foreach ($paths as $key => $path) {
+                       $path = str_replace('@partial', $partialName, $path);
+                       if (file_exists($path)) {
+                               return $path;
+                       }
+               }
+               throw new Tx_Fluid_Core_RuntimeException('The template files "' . implode('", "', $paths) . '" could not be loaded.', 1225709595);
        }
 
        /**
@@ -240,39 +305,110 @@ class Tx_Fluid_View_TemplateView extends Tx_Extbase_MVC_View_AbstractView {
         *
         * @return boolean
         * @author Karsten Dambekalns <karsten@typo3.org>
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
         */
        public function hasTemplate() {
-               return file_exists($this->resolveTemplatePathAndFilename());
+               try {
+                       $this->resolveTemplatePathAndFilename();
+                       return TRUE;
+               } catch (Tx_Fluid_Core_RuntimeException $e) {
+                       return FALSE;
+               }
        }
 
        /**
-        * Resolve the path and name of the template, based on $this->templatePathAndFilename and $this->templatePathAndFilenamePattern.
-        * In case a template has been set with $this->setTemplatePathAndFilename, it just uses the given template file.
-        * Otherwise, it resolves the $this->templatePathAndFilenamePattern
+        * Parse the given template and return it.
         *
-        * @return string Path and filename of template file
+        * Will cache the results for one call.
+        *
+        * @param string $templatePathAndFilename absolute filename of the template to be parsed
+        * @return Tx_Fluid_Core_Parser_ParsedTemplateInterface the parsed template tree
         * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
-       protected function resolveTemplatePathAndFilename() {
-               if ($this->templatePathAndFilename !== NULL) {
-                       return $this->templatePathAndFilename;
-               } else {
-                       $actionName = ($this->actionName !== NULL ? $this->actionName : $this->controllerContext->getRequest()->getControllerActionName());
-                       $matches = array();
-                       preg_match(self::PATTERN_CONTROLLER, $this->controllerContext->getRequest()->getControllerObjectName(), $matches);
-                       $subpackageName = '';
-                       if ($matches['SubpackageName'] !== '') {
-                               $subpackageName = str_replace('\\', '/', $matches['SubpackageName']);
-                               $subpackageName .= '/';
-                       }
+       protected function parseTemplate($templatePathAndFilename) {
+               $templateSource = file_get_contents($templatePathAndFilename);
+
+               return $this->templateParser->parse($templateSource);
+       }
+
+       /**
+        * Resolves the template root to be used inside other paths.
+        * @return string Path to template root directory
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       protected function getTemplateRootPath() {
+               return str_replace('@package', t3lib_extMgm::extPath($this->controllerContext->getRequest()->getControllerExtensionKey()), $this->templateRootPathPattern);
+       }
+
+       /**
+        * Processes @templateRoot, @subpackage, @controller, and @format placeholders inside $pattern.
+        * This method is used to generate "fallback chains" for file system locations where a certain Partial can reside.
+        *
+        * If $bubbleControllerAndSubpackage is FALSE and $formatIsOptional is FALSE, then the resulting array will only have one element
+        * with all the above placeholders replaced.
+        *
+        * If you set $bubbleControllerAndSubpackage to TRUE, then you will get an array with potentially many elements:
+        * The first element of the array is like above. The second element has the @controller part set to "" (the empty string)
+        * The third element now has the @controller part again stripped off, and has the last subpackage part stripped off as well.
+        * This continues until both @subpackage and @controller are empty.
+        *
+        * Example for $bubbleControllerAndSubpackage is TRUE, we have the Tx_Fluid_MySubPackage_Controller_MyController as Controller Object Name and the current format is "html"
+        * If pattern is @templateRoot/Templates/@controller/@action.@format, then the resulting array is:
+        *  - Resources/Private/Templates/MySubPackage/My/@action.html
+        *  - Resources/Private/Templates/MySubPackage/@action.html
+        *  - Resources/Private/Templates/@action.html
+        *
+        * If you set $formatIsOptional to TRUE, then for any of the above arrays, every element will be duplicated  - once with @format
+        * replaced by the current request format, and once with .@format stripped off.
+        *
+        * @param string $pattern Pattern to be resolved
+        * @param boolean $bubbleControllerAndSubpackage if TRUE, then we successively split off parts from @controller and @subpackage until both are empty.
+        * @param boolean $formatIsOptional if TRUE, then half of the resulting strings will have .@format stripped off, and the other half will have it.
+        * @return array unix style path
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       protected function expandGenericPathPattern($pattern, $bubbleControllerAndSubpackage, $formatIsOptional) {
+               $pattern = str_replace('@templateRoot', $this->getTemplateRootPath(), $pattern);
+
+               $this->PATTERN_CONTROLLER = str_replace('FLUID_NAMESPACE_SEPARATOR', preg_quote(Tx_Fluid_Fluid::NAMESPACE_SEPARATOR), $this->PATTERN_CONTROLLER);
+               preg_match($this->PATTERN_CONTROLLER, $this->controllerContext->getRequest()->getControllerObjectName(), $matches);
+
+               $subpackageParts = array();
+               if ($matches['SubpackageName'] !== '') {
+                       $subpackageParts = explode(Tx_Fluid_Fluid::NAMESPACE_SEPARATOR, $matches['SubpackageName']);
+               }
+
+               $controllerName = NULL;
+               if (strpos($pattern, '@controller') !== FALSE) {
                        $controllerName = $matches['ControllerName'];
-                       $templatePathAndFilename = str_replace('@package', t3lib_extMgm::extPath($this->controllerContext->getRequest()->getControllerExtensionKey()), $this->templatePathAndFilenamePattern);
-                       $templatePathAndFilename = str_replace('@subpackage', $subpackageName, $templatePathAndFilename);
-                       $templatePathAndFilename = str_replace('@controller', $controllerName, $templatePathAndFilename);
-                       $templatePathAndFilename = str_replace('@action', strtolower($actionName), $templatePathAndFilename);
+               }
+
+               $results = array();
 
-                       return $templatePathAndFilename;
+               if ($controllerName !== NULL) {
+                       $i = -1;
+               } else {
+                       $i = 0;
                }
+
+               do {
+                       $temporaryPattern = $pattern;
+                       if ($i < 0) {
+                               $temporaryPattern = str_replace('@controller', $controllerName, $temporaryPattern);
+                       } else {
+                               $temporaryPattern = str_replace('//', '/', str_replace('@controller', '', $temporaryPattern));
+                       }
+                       $temporaryPattern = str_replace('@subpackage', implode('/', ($i<0 ? $subpackageParts : array_slice($subpackageParts, $i))), $temporaryPattern);
+
+                       $results[] = t3lib_div::fixWindowsFilePath(str_replace('@format', html, $temporaryPattern));
+                       if ($formatIsOptional) {
+                               $results[] =  t3lib_div::fixWindowsFilePath(str_replace('.@format', '', $temporaryPattern));
+                       }
+
+               } while($i++ < count($subpackageParts) && $bubbleControllerAndSubpackage);
+
+               return $results;
        }
 }
 ?>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/View/TemplateViewInterface.php b/typo3/sysext/fluid/Classes/View/TemplateViewInterface.php
new file mode 100644 (file)
index 0000000..e96bc6d
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+
+/*                                                                        *
+ * This script belongs to the FLOW3 package "Fluid".                      *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version.                                             *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * Interface of Fluids Template view
+ *
+ * @version $Id: TemplateViewInterface.php 2902 2009-07-27 21:41:23Z sebastian $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+interface Tx_Fluid_View_TemplateViewInterface extends Tx_Extbase_MVC_View_ViewInterface {
+
+       /**
+        * Inject the template parser
+        *
+        * @param Tx_Fluid_Core_Parser_TemplateParser $templateParser The template parser
+        * @return void
+        * @api
+        */
+       public function injectTemplateParser(Tx_Fluid_Core_Parser_TemplateParser $templateParser);
+
+       /**
+        * Sets the path and name of of the template file. Effectively overrides the
+        * dynamic resolving of a template file.
+        *
+        * @param string $templatePathAndFilename Template file path
+        * @return void
+        * @api
+        */
+       public function setTemplatePathAndFilename($templatePathAndFilename);
+
+       /**
+        * Sets the path and name of the layout file. Overrides the dynamic resolving of the layout file.
+        *
+        * @param string $layoutPathAndFilename Path and filename of the layout file
+        * @return void
+        * @api
+        */
+       public function setLayoutPathAndFilename($layoutPathAndFilename);
+
+       /**
+        * Renders a given section.
+        *
+        * @param string $sectionName Name of section to render
+        * @return rendered template for the section
+        * @api
+        */
+       public function renderSection($sectionName);
+
+       /**
+        * Render a template with a given layout.
+        *
+        * @param string $layoutName Name of layout
+        * @return string rendered HTML
+        * @api
+        */
+       public function renderWithLayout($layoutName);
+
+       /**
+        * Checks whether a template can be resolved for the current request context.
+        *
+        * @return boolean
+        * @api
+        */
+       public function hasTemplate();
+
+}
+?>
index e36a392..0621259 100644 (file)
  *                                                                        */
 
 /**
- * @package Fluid
- * @subpackage ViewHelpers
- * @version $Id: AbstractFormViewHelper.php 2522 2009-06-02 10:32:21Z k-fish $
- */
-
-/**
  * Abstract Form View Helper. Bundles functionality related to direct property access of objects in other Form ViewHelpers.
  *
  * If you set the "property" attribute to the name of the property to resolve from the object, this class will
  * automatically set the name and value of a form element.
  *
- * @package Fluid
- * @subpackage ViewHelpers
- * @version $Id: AbstractFormViewHelper.php 2522 2009-06-02 10:32:21Z k-fish $
+ * @version $Id: AbstractFormViewHelper.php 2914 2009-07-28 18:26:38Z bwaidelich $
  * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @scope prototype
  */
 abstract class Tx_Fluid_ViewHelpers_Form_AbstractFormViewHelper extends Tx_Fluid_Core_ViewHelper_TagBasedViewHelper {
 
        /**
+        * @var \Tx_Extbase_Persistence_ManagerInterface
+        */
+       protected $persistenceManager;
+
+       /**
+        * Injects the FLOW3 Persistence Manager
+        *
+        * @param Tx_Extbase_Persistence_ManagerInterface $persistenceManager
+        * @return void
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function injectPersistenceManager(Tx_Extbase_Persistence_ManagerInterface $persistenceManager) {
+               $this->persistenceManager = $persistenceManager;
+       }
+
+       /**
         * Initialize arguments.
         *
         * @return void
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
         */
        public function initializeArguments() {
                parent::initializeArguments();
                $this->registerArgument('name', 'string', 'Name of input tag');
                $this->registerArgument('value', 'mixed', 'Value of input tag');
-               $this->registerArgument('property', 'string', 'Name of Object Property. If used in conjunction with <f3:form object="...">, "name" and "value" properties will be ignored.');
+               $this->registerArgument('property', 'string', 'Name of Object Property. If used in conjunction with <f:form object="...">, "name" and "value" properties will be ignored.');
        }
 
        /**
@@ -61,11 +70,11 @@ abstract class Tx_Fluid_ViewHelpers_Form_AbstractFormViewHelper extends Tx_Fluid
         * @author Sebastian Kurfürst <sebastian@typo3.org>
         * @author Robert Lemke <robert@typo3.org>
         * @author Karsten Dambekalns <karsten@typo3.org>
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        protected function getName() {
                $name = ($this->isObjectAccessorMode()) ? $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'formName') . '[' . $this->arguments['property'] . ']' : $this->arguments['name'];
-               if (is_object($this->arguments['value']) && is_callable(array($this->arguments['value'], 'getUid'))) {
+               if (is_object($this->arguments['value']) && NULL !== $this->persistenceManager->getBackend()->getIdentifierByObject($this->arguments['value'])
+                               && (!$this->persistenceManager->getBackend()->isNewObject($this->arguments['value']))) {
                        $name .= '[uid]';
                }
                return $name;
@@ -75,24 +84,43 @@ abstract class Tx_Fluid_ViewHelpers_Form_AbstractFormViewHelper extends Tx_Fluid
         * Get the value of this form element.
         * Either returns arguments['value'], or the correct value for Object Access.
         *
-        * @return string Value
+        * @return mixed Value
         * @author Sebastian Kurfürst <sebastian@typo3.org>
         * @author Robert Lemke <robert@typo3.org>
         * @author Bastian Waidelich <bastian@typo3.org>
         */
        protected function getValue() {
-               if ($this->isObjectAccessorMode() && $this->viewHelperVariableContainer->exists('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObject') && ($this->arguments['value'] === NULL)) {
-                       $value = $this->getObjectValue($this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObject'), $this->arguments['property']);
-               } else {
+               $value = NULL;
+               if ($this->arguments->hasArgument('value')) {
                        $value = $this->arguments['value'];
+               } elseif ($this->isObjectAccessorMode() && $this->viewHelperVariableContainer->exists('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObject')) {
+                       $value = $this->getPropertyValue();
                }
-               if (is_object($this->arguments['value']) && is_callable(array($this->arguments['value'], 'getUid'))) {
-                       $value = $this->arguments['value']->getUid();
+               if (is_object($value)) {
+                       $identifier = $this->persistenceManager->getBackend()->getIdentifierByObject($value);
+                       if ($identifier !== NULL) {
+                               $value = $identifier;
+                       }
                }
                return $value;
        }
 
        /**
+        * Get the current property of the object bound to this form.
+        *
+        * @return mixed Value
+        * @author Bastian Waidelich <bastian@typo3.org>
+        */
+       protected function getPropertyValue() {
+               $formObject = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObject');
+               $propertyName = $this->arguments['property'];
+               if (is_array($formObject)) {
+                       return isset($formObject[$propertyName]) ? $formObject[$propertyName] : NULL;
+               }
+               return Tx_Extbase_Reflection_ObjectAccess::getProperty($formObject, $propertyName);
+       }
+
+       /**
         * Internal method which checks if we should evaluate a domain object or just output arguments['name'] and arguments['value']
         *
         * @return boolean TRUE if we should evaluate the domain object, FALSE otherwise.
@@ -102,40 +130,52 @@ abstract class Tx_Fluid_ViewHelpers_Form_AbstractFormViewHelper extends Tx_Fluid
                return (($this->arguments['property'] !== NULL) && $this->viewHelperVariableContainer->exists('Tx_Fluid_ViewHelpers_FormViewHelper', 'formName')) ? TRUE : FALSE;
        }
 
+
        /**
-        * Get object value. Calls the appropriate getter.
+        * Add an CSS class if this view helper has errors
         *
-        * @param object $object Object to get the value from
-        * @param string $propertyName Name of property to get.
-        * @todo replace with something generic.
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @return void
+        * @author Christopher Hlubek <hlubek@networkteam.com>
+        * @author Bastian Waidelich <bastian@typo3.org>
         */
-       private function getObjectValue($object, $propertyName) {
-               $getterMethodName = 'get' . ucfirst($propertyName);
-               return $object->$getterMethodName();
+       protected function setErrorClassAttribute() {
+               if ($this->arguments->hasArgument('class')) {
+                       $cssClass = $this->arguments['class'] . ' ';
+               } else {
+                       $cssClass = '';
+               }
+               $errors = $this->getErrorsForProperty();
+               if (count($errors) > 0) {
+                       if ($this->arguments->hasArgument('errorClass')) {
+                               $cssClass .= $this->arguments['errorClass'];
+                       } else {
+                               $cssClass .= 'f3-form-error';
+                       }
+                       $this->tag->addAttribute('class', $cssClass);
+               }
        }
-       
+
        /**
         * Get errors for the property and form name of this view helper
         *
-        * @return array An array of F3\FLOW3\Error\Error objects
+        * @return array An array of Tx_Fluid_Error_Error objects
+        * @author Christopher Hlubek <hlubek@networkteam.com>
+        * @author Bastian Waidelich <bastian@typo3.org>
         */
        protected function getErrorsForProperty() {
+               if (!$this->arguments->hasArgument('property')) {
+                       return array();
+               }
                $errors = $this->controllerContext->getRequest()->getErrors();
                $formName = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'formName');
-
-               if ($this->arguments->hasArgument('property')) {
-                       $propertyName = $this->arguments['property'];
-
-                       $formErrors = array();
-                       foreach ($errors as $error) {
-                               if ($error instanceof Tx_Extbase_Validation_PropertyError && $error->getPropertyName() == $formName) {
-                                       
-                                       $formErrors = $error->getErrors();
-                                       foreach ($formErrors as $formError) {
-                                               if ($formError instanceof Tx_Extbase_Validation_PropertyError && $formError->getPropertyName() == $propertyName) {
-                                                       return $formError->getErrors();
-                                               }
+               $propertyName = $this->arguments['property'];
+               $formErrors = array();
+               foreach ($errors as $error) {
+                       if ($error instanceof Tx_Extbase_Validation_PropertyError && $error->getPropertyName() === $formName) {
+                               $formErrors = $error->getErrors();
+                               foreach ($formErrors as $formError) {
+                                       if ($formError instanceof Tx_Extbase_Validation_PropertyError && $formError->getPropertyName() === $propertyName) {
+                                               return $formError->getErrors();
                                        }
                                }
                        }
index 71944dd..fc89440 100644 (file)
  *                                                                        */
 
 /**
- * @package Fluid
- * @subpackage ViewHelpers
- * @version $Id: HiddenViewHelper.php 2279 2009-05-19 21:16:46Z k-fish $
- */
-
-/**
  * Renders an <input type="hidden" ...> tag.
  *
  * = Examples =
@@ -41,9 +35,7 @@
  * You can also use the "property" attribute if you have bound an object to the form.
  * See <f:form> for more documentation.
  *
- * @package Fluid
- * @subpackage ViewHelpers
- * @version $Id: HiddenViewHelper.php 2279 2009-05-19 21:16:46Z k-fish $
+ * @version $Id: HiddenViewHelper.php 2813 2009-07-16 14:02:34Z k-fish $
  * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @scope prototype
  */
@@ -59,6 +51,7 @@ class Tx_Fluid_ViewHelpers_Form_HiddenViewHelper extends Tx_Fluid_ViewHelpers_Fo
         *
         * @return void
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
         */
        public function initializeArguments() {
                parent::initializeArguments();
@@ -70,6 +63,7 @@ class Tx_Fluid_ViewHelpers_Form_HiddenViewHelper extends Tx_Fluid_ViewHelpers_Fo
         *
         * @return string
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
         */
        public function render() {
                $this->tag->addAttribute('type', 'hidden');
index 88504c9..df6695c 100644 (file)
  *                                                                        */
 
 /**
- * @package Fluid
- * @subpackage ViewHelpers
- * @version $Id: SelectViewHelper.php 2279 2009-05-19 21:16:46Z k-fish $
- */
-
-/**
  * This view helper generates a <select> dropdown list for the use with a form.
  *
  * = Basic usage =
  * The array key is used as option key, and the value is used as human-readable name.
  *
  * <code title="Basic usage">
- * <f3:form.select name="paymentOptions" options="{payPal: 'PayPal International Services', visa: 'VISA Card'}" />
+ * <f:form.select name="paymentOptions" options="{payPal: 'PayPal International Services', visa: 'VISA Card'}" />
  * </code>
  *
  * = Pre-select a value =
  *
- * To pre-select a value, set "selectedValue" to the option key which should be selected.
+ * To pre-select a value, set "value" to the option key which should be selected.
  * <code title="Default value">
- * <f3:form.select name="paymentOptions" options="{payPal: 'PayPal International Services', visa: 'VISA Card'}" selectedValue="visa" />
+ * <f:form.select name="paymentOptions" options="{payPal: 'PayPal International Services', visa: 'VISA Card'}" value="visa" />
  * </code>
  * Generates a dropdown box like above, except that "VISA Card" is selected.
  *
- * If the select box is a multi-select box (multiple="true"), then "selectedValue" can be an array as well.
+ * If the select box is a multi-select box (multiple="true"), then "value" can be an array as well.
  *
  * = Usage on domain objects =
  *
  * If you want to output domain objects, you can just pass them as array into the "options" parameter.
  * To define what domain object value should be used as option key, use the "optionValueField" variable. Same goes for optionLabelField.
+ * If neither is given, the Identifier (UUID/uid) and the __toString() method are tried as fallbacks.
  *
  * If the optionValueField variable is set, the getter named after that value is used to retrieve the option key.
  * If the optionLabelField variable is set, the getter named after that value is used to retrieve the option value.
  *
  * <code title="Domain objects">
- * <f3:form.select name="users" options="{userArray}" optionValueField="id" optionLabelField="firstName" />
+ * <f:form.select name="users" options="{userArray}" optionValueField="id" optionLabelField="firstName" />
  * </code>
  * In the above example, the userArray is an array of "User" domain objects, with no array key specified.
  *
  * So, in the above example, the method $user->getId() is called to retrieve the key, and $user->getFirstName() to retrieve the displayed value of each entry.
  *
- * The "selectedValue" property now expects a domain object, and tests for object equivalence.
+ * The "value" property now expects a domain object, and tests for object equivalence.
  *
- * @package Fluid
- * @subpackage ViewHelpers
- * @version $Id: SelectViewHelper.php 2279 2009-05-19 21:16:46Z k-fish $
+ * @version $Id: SelectViewHelper.php 2914 2009-07-28 18:26:38Z bwaidelich $
  * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @scope prototype
  */
@@ -88,15 +81,18 @@ class Tx_Fluid_ViewHelpers_Form_SelectViewHelper extends Tx_Fluid_ViewHelpers_Fo
         *
         * @return void
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
         */
        public function initializeArguments() {
                parent::initializeArguments();
                $this->registerUniversalTagAttributes();
                $this->registerTagAttribute('multiple', 'string', 'if set, multiple select field');
                $this->registerTagAttribute('size', 'string', 'Size of input field');
-               $this->registerArgument('options', 'array', 'Associative array with internal IDs as key, and the values are displayed in the select box', FALSE);
-               $this->registerArgument('optionValueField', 'string', 'If specified, will call the appropriate getter on each object to determine the value.', FALSE);
-               $this->registerArgument('optionLabelField', 'string', 'If specified, will call the appropriate getter on each object to determine the label.', FALSE);
+               $this->registerTagAttribute('disabled', 'string', 'Specifies that the input element should be disabled when the page loads');
+               $this->registerArgument('options', 'array', 'Associative array with internal IDs as key, and the values are displayed in the select box', TRUE);
+               $this->registerArgument('optionValueField', 'string', 'If specified, will call the appropriate getter on each object to determine the value.');
+               $this->registerArgument('optionLabelField', 'string', 'If specified, will call the appropriate getter on each object to determine the label.');
+               $this->registerArgument('errorClass', 'string', 'CSS class to set if there are errors for this view helper', FALSE, 'f3-form-error');
        }
 
        /**
@@ -105,6 +101,7 @@ class Tx_Fluid_ViewHelpers_Form_SelectViewHelper extends Tx_Fluid_ViewHelpers_Fo
         * @return string rendered tag.
         * @author Sebastian Kurfürst <sebastian@typo3.org>
         * @author Bastian Waidelich <bastian@typo3.org>
+        * @api
         */
        public function render() {
                $name = $this->getName();
@@ -115,6 +112,8 @@ class Tx_Fluid_ViewHelpers_Form_SelectViewHelper extends Tx_Fluid_ViewHelpers_Fo
                $this->tag->addAttribute('name', $name);
                $this->tag->setContent($this->renderOptionTags());
 
+               $this->setErrorClassAttribute();
+
                return $this->tag->render();
        }
 
@@ -139,16 +138,46 @@ class Tx_Fluid_ViewHelpers_Form_SelectViewHelper extends Tx_Fluid_ViewHelpers_Fo
         *
         * @return array an associative array of options, key will be the value of the option tag
         * @author Bastian Waidelich <bastian@typo3.org>
+        * @author Karsten Dambekalns <karsten@typo3.org>
         */
        protected function getOptions() {
-               if (!$this->arguments->hasArgument('optionValueField')) {
-                       return $this->arguments['options'];
-               }
                $options = array();
-               foreach ($this->arguments['options'] as $domainObject) {
-                       $value = Tx_Extbase_Reflection_ObjectAccess::getProperty($domainObject, $this->arguments['optionValueField']);
-                       $label = Tx_Extbase_Reflection_ObjectAccess::getProperty($domainObject, $this->arguments['optionLabelField']);
-                       $options[$value] = $label;
+               foreach ($this->arguments['options'] as $key => $value) {
+                       if (is_object($value)) {
+
+                               if ($this->arguments->hasArgument('optionValueField')) {
+                                       $key = Tx_Extbase_Reflection_ObjectAccess::getProperty($value, $this->arguments['optionValueField']);
+                                       if (is_object($key)) {
+                                               if (method_exists($key, '__toString')) {
+                                                       $key = (string)$key;
+                                               } else {
+                                                       throw new Tx_Fluid_Core_ViewHelper_Exception('Identifying value for object of class "' . get_class($value) . '" was an object.' , 1247827428);
+                                               }
+                                       }
+                               } elseif ($this->persistenceManager->getBackend()->getIdentifierByObject($value) !== NULL) {
+                                       $key = $this->persistenceManager->getBackend()->getIdentifierByObject($value);
+                               } elseif (method_exists($value, '__toString')) {
+                                       $key = (string)$value;
+                               } else {
+                                       throw new Tx_Fluid_Core_ViewHelper_Exception('No identifying value for object of class "' . get_class($value) . '" found.' , 1247826696);
+                               }
+
+                               if ($this->arguments->hasArgument('optionLabelField')) {
+                                       $value = Tx_Extbase_Reflection_ObjectAccess::getProperty($value, $this->arguments['optionLabelField']);
+                                       if (is_object($value)) {
+                                               if (method_exists($value, '__toString')) {
+                                                       $value = (string)$value;
+                                               } else {
+                                                       throw new Tx_Fluid_Core_ViewHelper_Exception('Label value for object of class "' . get_class($value) . '" was an object without a __toString() method.' , 1247827553);
+                                               }
+                                       }
+                               } elseif (method_exists($value, '__toString')) {
+                                       $value = (string)$value;
+                               } elseif ($this->persistenceManager->getBackend()->getIdentifierByObject($value) !== NULL) {
+                                       $value = $this->persistenceManager->getBackend()->getIdentifierByObject($value);
+                               }
+                       }
+                       $options[$key] = $value;
                }
                return $options;
        }
index 4756fd3..650baad 100644 (file)
  *                                                                        */
 
 /**
- * @package Fluid
- * @subpackage ViewHelpers
- * @version $Id: SubmitViewHelper.php 2279 2009-05-19 21:16:46Z k-fish $
- */
-
-/**
  * Creates a submit button.
  *
  * = Examples =
@@ -45,9 +39,7 @@
   * Output:
  * <input type="submit" name="mySubmit" value="Send Mail" />
  *
- * @package Fluid
- * @subpackage ViewHelpers
- * @version $Id: SubmitViewHelper.php 2279 2009-05-19 21:16:46Z k-fish $
+ * @version $Id: SubmitViewHelper.php 2914 2009-07-28 18:26:38Z bwaidelich $
  * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @scope prototype
  */
@@ -63,9 +55,11 @@ class Tx_Fluid_ViewHelpers_Form_SubmitViewHelper extends Tx_Fluid_Core_ViewHelpe
         *
         * @return void
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
         */
        public function initializeArguments() {
                parent::initializeArguments();
+               $this->registerTagAttribute('disabled', 'string', 'Specifies that the input element should be disabled when the page loads');
                $this->registerUniversalTagAttributes();
        }
 
@@ -77,6 +71,7 @@ class Tx_Fluid_ViewHelpers_Form_SubmitViewHelper extends Tx_Fluid_Core_ViewHelpe
         * @return string
         * @author Sebastian Kurfürst <sebastian@typo3.org>
         * @author Bastian Waidelich <bastian@typo3.org>
+        * @api
         */
        public function render($name = '', $value = '') {
                $this->tag->addAttribute('type', 'submit');
index 4d2e745..5416b19 100644 (file)
  *                                                                        */
 
 /**
- * @package Fluid
- * @subpackage ViewHelpers
- * @version $Id: TextareaViewHelper.php 2279 2009-05-19 21:16:46Z k-fish $
- */
-
-/**
  * Textarea view helper.
  * The value of the text area needs to be set via the "value" attribute, as with all other form ViewHelpers.
  *
@@ -39,9 +33,7 @@
  * Output:
  * <textarea name="myTextArea">This is shown inside the textarea</textarea>
  *
- * @package Fluid
- * @subpackage ViewHelpers
- * @version $Id: TextareaViewHelper.php 2279 2009-05-19 21:16:46Z k-fish $
+ * @version $Id: TextareaViewHelper.php 2914 2009-07-28 18:26:38Z bwaidelich $
  * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @scope prototype
  */
@@ -57,11 +49,14 @@ class Tx_Fluid_ViewHelpers_Form_TextareaViewHelper extends Tx_Fluid_ViewHelpers_
         *
         * @return void
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
         */
        public function initializeArguments() {
                parent::initializeArguments();
                $this->registerTagAttribute('rows', 'int', 'The number of rows of a text area', TRUE);
                $this->registerTagAttribute('cols', 'int', 'The number of columns of a text area', TRUE);
+               $this->registerTagAttribute('disabled', 'string', 'Specifies that the input element should be disabled when the page loads');
+               $this->registerArgument('errorClass', 'string', 'CSS class to set if there are errors for this view helper', FALSE, 'f3-form-error');
                $this->registerUniversalTagAttributes();
        }
 
@@ -71,12 +66,15 @@ class Tx_Fluid_ViewHelpers_Form_TextareaViewHelper extends Tx_Fluid_ViewHelpers_
         * @return string
         * @author Sebastian Kurfürst <sebastian@typo3.org>
         * @author Bastian Waidelich <bastian@typo3.org>
+        * @api
         */
        public function render() {
                $this->tag->forceClosingTag(TRUE);
                $this->tag->addAttribute('name', $this->getName());
                $this->tag->setContent($this->getValue());
 
+               $this->setErrorClassAttribute();
+
                return $this->tag->render();
        }
 }
index b60cc82..6feff71 100644 (file)
  *                                                                        */
 
 /**
- * @package Fluid
- * @subpackage ViewHelpers
- * @version $Id: TextboxViewHelper.php 2279 2009-05-19 21:16:46Z k-fish $
- */
-
-/**
  * View Helper which creates a simple Text Box (<input type="text">).
  *
   * = Examples =
@@ -38,9 +32,7 @@
  * Output:
  * <input type="text" name="myTextBox" value="default value" />
  *
- * @package Fluid
- * @subpackage ViewHelpers
- * @version $Id: TextboxViewHelper.php 2279 2009-05-19 21:16:46Z k-fish $
+ * @version $Id: TextboxViewHelper.php 2914 2009-07-28 18:26:38Z bwaidelich $
  * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @scope prototype
  */
@@ -56,9 +48,15 @@ class Tx_Fluid_ViewHelpers_Form_TextboxViewHelper extends Tx_Fluid_ViewHelpers_F
         *
         * @return void
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @author Christopher Hlubek <hlubek@networkteam.com>
+        * @api
         */
        public function initializeArguments() {
                parent::initializeArguments();
+               $this->registerTagAttribute('disabled', 'string', 'Specifies that the input element should be disabled when the page loads');
+               $this->registerTagAttribute('maxlength', 'int', 'The maxlength attribute of the input field (will not be validated)');
+               $this->registerTagAttribute('readonly', 'string', 'The readonly attribute of the input field');
+               $this->registerTagAttribute('size', 'int', 'The size of the input field');
                $this->registerArgument('errorClass', 'string', 'CSS class to set if there are errors for this view helper', FALSE, 'f3-form-error');
                $this->registerUniversalTagAttributes();
        }
@@ -68,35 +66,18 @@ class Tx_Fluid_ViewHelpers_Form_TextboxViewHelper extends Tx_Fluid_ViewHelpers_F
         *
         * @return string
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
         */
        public function render() {
                $this->tag->addAttribute('type', 'text');
                $this->tag->addAttribute('name', $this->getName());
                $this->tag->addAttribute('value', $this->getValue());
 
-               $this->addErrorStyleClass();
-               
+               $this->setErrorClassAttribute();
+
                return $this->tag->render();
        }
 
-       /**
-        * Add an CSS class if this view helper has errors
-        *
-        * @return void
-        * @author Christopher Hlubek <hlubek@networkteam.com>
-        */
-       protected function addErrorStyleClass() {
-               if ($this->arguments->hasArgument('class')) {
-                       $styleClass = $this->arguments['class'] . ' ';
-               } else {
-                       $styleClass = '';
-               }
-               $errors = $this->getErrorsForProperty();
-               if (count($errors) > 0) {
-                       $styleClass .= $this->arguments['errorClass'];
-                       $this->tag->addAttribute('class', $styleClass);
-               }
-       }
 }
 
 ?>
\ No newline at end of file
index 32af74f..a9ad3e9 100644 (file)
  *                                                                        */
 
 /**
- * @package Fluid
- * @subpackage ViewHelpers
- * @version $Id: UploadViewHelper.php 2279 2009-05-19 21:16:46Z k-fish $
- */
-
-/**
  * A view helper which generates an <input type="file"> HTML element.
  * Make sure to set enctype="multipart/form-data" on the form!
  *
@@ -39,9 +33,7 @@
  * Output:
  * <input type="file" name="file" />
  *
- * @package Fluid
- * @subpackage ViewHelpers
- * @version $Id: UploadViewHelper.php 2279 2009-05-19 21:16:46Z k-fish $
+ * @version $Id: UploadViewHelper.php 2914 2009-07-28 18:26:38Z bwaidelich $
  * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @scope prototype
  */
@@ -57,9 +49,12 @@ class Tx_Fluid_ViewHelpers_Form_UploadViewHelper extends Tx_Fluid_ViewHelpers_Fo
         *
         * @return void
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
         */
        public function initializeArguments() {
                parent::initializeArguments();
+               $this->registerTagAttribute('disabled', 'string', 'Specifies that the input element should be disabled when the page loads');
+               $this->registerArgument('errorClass', 'string', 'CSS class to set if there are errors for this view helper', FALSE, 'f3-form-error');
                $this->registerUniversalTagAttributes();
        }
 
@@ -68,11 +63,14 @@ class Tx_Fluid_ViewHelpers_Form_UploadViewHelper extends Tx_Fluid_ViewHelpers_Fo
         *
         * @return string
         * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
         */
        public function render() {
                $this->tag->addAttribute('type', 'file');
                $this->tag->addAttribute('name', $this->getName());
 
+               $this->setErrorClassAttribute();
+
                return $this->tag->render();
        }
 }
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/LayoutViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/LayoutViewHelper.php
new file mode 100644 (file)
index 0000000..ef9b6dc
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+
+/*                                                                        *
+ * This script belongs to the FLOW3 package "Fluid".                      *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version.                                             *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * With this tag, you can select a layout to be used.
+ *
+ * @version $Id: LayoutViewHelper.php 2914 2009-07-28 18:26:38Z bwaidelich $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ * @scope prototype
+ * @todo refine documentation
+ */
+class Tx_Fluid_ViewHelpers_LayoutViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractViewHelper implements Tx_Fluid_Core_ViewHelper_Facets_PostParseInterface {
+
+       /**
+        * Initialize arguments
+        *
+        * @return void
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
+        */
+       public function initializeArguments() {
+               $this->registerArgument('name', 'string', 'Name of layout to use. If none given, "default" is used.', TRUE);
+       }
+
+       /**
+        * On the post parse event, add the "layoutName" variable to the variable container so it can be used by the TemplateView.
+        *
+        * @param Tx_Fluid_Core_Parser_SyntaxTree_ViewHelperNode $syntaxTreeNode
+        * @param array $viewHelperArguments
+        * @param Tx_Fluid_Core_ViewHelper_TemplateVariableContainer $variableContainer
+        * @return void
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       static public function postParseEvent(Tx_Fluid_Core_Parser_SyntaxTree_ViewHelperNode $syntaxTreeNode, array $viewHelperArguments, Tx_Fluid_Core_ViewHelper_TemplateVariableContainer $variableContainer) {
+               if (isset($viewHelperArguments['name'])) {
+                       $viewHelperArguments['name']->setRenderingContext(new Tx_Fluid_Core_Rendering_RenderingContext());
+                       $layoutName = $viewHelperArguments['name']->evaluate();
+               } else {
+                       $layoutName = 'default';
+               }
+
+               $variableContainer->add('layoutName', $layoutName);
+       }
+
+       /**
+        * This tag will not be rendered at all.
+        *
+        * @return void
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
+        */
+       public function render() {
+       }
+}
+
+
+?>
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/RenderViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/RenderViewHelper.php
new file mode 100644 (file)
index 0000000..83a81b7
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+/*                                                                        *
+ * This script belongs to the FLOW3 package "Fluid".                      *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version.                                             *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ *
+ * @version $Id: RenderViewHelper.php 2813 2009-07-16 14:02:34Z k-fish $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ * @scope prototype
+ */
+class Tx_Fluid_ViewHelpers_RenderViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractViewHelper {
+
+       /**
+        * Renders the content.
+        *
+        * @param string $section Name of section to render. If used in a layout, renders a section of the main content file. If used inside a standard template, renders a section of the same file.
+        * @param string $partial Reference to a partial.
+        * @param array $arguments Arguments to pass to the partial.
+        * @return string
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
+        */
+       public function render($section = '', $partial = '', $arguments = array()) {
+               if ($partial !== '') {
+                       return $this->viewHelperVariableContainer->getView()->renderPartial($partial, $section, $arguments);
+               } elseif ($section !== '') {
+                       return $this->viewHelperVariableContainer->getView()->renderSection($section);
+               }
+               return '';
+       }
+
+
+}
+
+
+?>
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/SectionViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/SectionViewHelper.php
new file mode 100644 (file)
index 0000000..d0f4bf9
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+
+/*                                                                        *
+ * This script belongs to the FLOW3 package "Fluid".                      *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version.                                             *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * A Section view helper
+ *
+ * @version $Id: SectionViewHelper.php 2813 2009-07-16 14:02:34Z k-fish $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ * @scope prototype
+ */
+class Tx_Fluid_ViewHelpers_SectionViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractViewHelper implements Tx_Fluid_Core_ViewHelper_Facets_PostParseInterface {
+
+       /**
+        * Initialize the arguments.
+        *
+        * @return void
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
+        */
+       public function initializeArguments() {
+               $this->registerArgument('name', 'string', 'Name of the section', TRUE);
+       }
+
+       /**
+        * Save the associated view helper node in a static public class variable.
+        * called directly after the view helper was built.
+        *
+        * @param Tx_Fluid_Core_Parser_SyntaxTree_ViewHelperNode $syntaxTreeNode
+        * @param array $viewHelperArguments
+        * @param Tx_Fluid_Core_ViewHelper_TemplateVariableContainer $variableContainer
+        * @return void
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       static public function postParseEvent(Tx_Fluid_Core_Parser_SyntaxTree_ViewHelperNode $syntaxTreeNode, array $viewHelperArguments, Tx_Fluid_Core_ViewHelper_TemplateVariableContainer $variableContainer) {
+               $viewHelperArguments['name']->setRenderingContext(new Tx_Fluid_Core_Rendering_RenderingContext());
+
+               $sectionName = $viewHelperArguments['name']->evaluate();
+               if (!$variableContainer->exists('sections')) {
+                       $variableContainer->add('sections', array());
+               }
+               $sections = $variableContainer->get('sections');
+               $sections[$sectionName] = $syntaxTreeNode;
+               $variableContainer->remove('sections');
+               $variableContainer->add('sections', $sections);
+       }
+
+       /**
+        * Rendering directly returns all child nodes.
+        *
+        * @return string HTML String of all child nodes.
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
+        */
+       public function render() {
+               return $this->renderChildren();
+       }
+}
+
+?>