[FEATURE] Fluid Tag Builder: Allow empty attributes 39/40139/6
authorSebastian Michaelsen <sebastian@michaelsen.io>
Tue, 9 Jun 2015 12:39:45 +0000 (14:39 +0200)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Sat, 18 Jul 2015 09:06:16 +0000 (11:06 +0200)
When using the Fluid Tag Builder to create tags an attribute can only be
set as a key/value pair. It should be possible render attributes with
the "empty attributes syntax".

http://www.w3.org/TR/html-markup/syntax.html#syntax-attributes

Releases: master
Resolves: #67372
Change-Id: Iae76f2eb82af79ad36e6a1f1d2485fa2070090df
Reviewed-on: http://review.typo3.org/40139
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/core/Documentation/Changelog/master/Feature-67372-AllowEmptyAttributeSyntaxInFluidTagBuilder.rst [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/ViewHelper/AbstractTagBasedViewHelper.php [changed mode: 0644->0755]
typo3/sysext/fluid/Classes/Core/ViewHelper/TagBuilder.php
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/AbstractTagBasedViewHelperTest.php [changed mode: 0644->0755]
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/TagBuilderTest.php

diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-67372-AllowEmptyAttributeSyntaxInFluidTagBuilder.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-67372-AllowEmptyAttributeSyntaxInFluidTagBuilder.rst
new file mode 100644 (file)
index 0000000..9a903fe
--- /dev/null
@@ -0,0 +1,27 @@
+==================================================================
+Feature: #67372 - Allow empty attribute syntax in fluid TagBuilder
+==================================================================
+
+Description
+===========
+
+Tags built with the TagBuilder may have empty attributes as they are allowed in the `HTML specifications`_ and are broadly supported by web browsers.
+The way to create empty attributes is to use ``->addAttribute($key, $value)`` or ``->addAttributes($array)`` just like before and provide an empty string as attribute value.
+
+
+Impact
+======
+
+If someone used an empty string as attribute value before, it will now be rendered with the empty attribute syntax which is exactly the same (according to the HTML specification).
+
+
+Examples
+========
+
+Usage example:
+
+.. code-block:: php
+
+       $this->tag->addAttribute('disabled', ''); // results in a tag like: <input disabled />
+
+.. _HTML specifications: http://www.w3.org/TR/html-markup/syntax.html#syntax-attributes
old mode 100644 (file)
new mode 100755 (executable)
index 5e80f6c..e55381f
@@ -80,7 +80,7 @@ abstract class AbstractTagBasedViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelp
 
                if (isset(self::$tagAttributes[get_class($this)])) {
                        foreach (self::$tagAttributes[get_class($this)] as $attributeName) {
-                               if ($this->hasArgument($attributeName) && $this->arguments[$attributeName] !== '') {
+                               if ($this->hasArgument($attributeName)) {
                                        $this->tag->addAttribute($attributeName, $this->arguments[$attributeName]);
                                }
                        }
index 07f1e83..dd7455a 100644 (file)
@@ -226,7 +226,11 @@ class TagBuilder {
                }
                $output = '<' . $this->tagName;
                foreach ($this->attributes as $attributeName => $attributeValue) {
-                       $output .= ' ' . $attributeName . '="' . $attributeValue . '"';
+                       if ($attributeValue === '' && $GLOBALS['TSFE']->config['config']['doctype'] === 'html5') {
+                               $output .= ' ' . $attributeName;
+                       } else {
+                               $output .= ' ' . $attributeName . '="' . $attributeValue . '"';
+                       }
                }
                if ($this->hasContent() || $this->forceClosingTag) {
                        $output .= '>' . $this->content . '</' . $this->tagName . '>';
old mode 100644 (file)
new mode 100755 (executable)
index 4d0f03b..561f9fd
@@ -53,6 +53,20 @@ class AbstractTagBasedViewHelperTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
        /**
         * @test
         */
+       public function emptyTagAttributeCallsTagBuilder() {
+               $mockTagBuilder = $this->getMock(\TYPO3\CMS\Fluid\Core\ViewHelper\TagBuilder::class, array('addAttribute'), array(), '', FALSE);
+               $mockTagBuilder->expects($this->once())->method('addAttribute')->with('foo', '');
+               $this->viewHelper->_set('tag', $mockTagBuilder);
+
+               $this->viewHelper->_call('registerTagAttribute', 'foo', 'string', 'Description', FALSE);
+               $arguments = array('foo' => '');
+               $this->viewHelper->setArguments($arguments);
+               $this->viewHelper->initialize();
+       }
+
+       /**
+        * @test
+        */
        public function additionalTagAttributesAreRenderedCorrectly() {
                $mockTagBuilder = $this->getMock(\TYPO3\CMS\Fluid\Core\ViewHelper\TagBuilder::class, array('addAttribute'), array(), '', FALSE);
                $mockTagBuilder->expects($this->once())->method('addAttribute')->with('foo', 'bar');
index 2b8c7dd..69fd807 100644 (file)
@@ -115,6 +115,21 @@ class TagBuilderTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        /**
         * @test
         */
+       public function emptyAttributesAreRenderedAccordingToHtmlDoctype() {
+               $GLOBALS['TSFE']->config['config']['doctype'] = 'html5';
+               $tagBuilder = new \TYPO3\CMS\Fluid\Core\ViewHelper\TagBuilder('tag');
+               $tagBuilder->addAttribute('attribute1', '');
+               $this->assertEquals('<tag attribute1 />', $tagBuilder->render(), 'Empty attribute syntax is used for HTML5 doctype');
+               $tagBuilder->reset();
+               $GLOBALS['TSFE']->config['config']['doctype'] = 'xhtml_trans';
+               $tagBuilder->setTagName('tag');
+               $tagBuilder->addAttribute('attribute1', '');
+               $this->assertEquals('<tag attribute1="" />', $tagBuilder->render(), 'Key value attribute syntax is used for XHTML doctype');
+       }
+
+       /**
+        * @test
+        */
        public function attributeValuesAreEscapedByDefault() {
                $tagBuilder = new \TYPO3\CMS\Fluid\Core\ViewHelper\TagBuilder('tag');
                $tagBuilder->addAttribute('foo', '<to be escaped>');