[FEATURE] Add MediaViewHelper 24/38624/11
authorFrans Saris <franssaris@gmail.com>
Fri, 10 Apr 2015 19:19:23 +0000 (21:19 +0200)
committerFrans Saris <franssaris@gmail.com>
Fri, 21 Aug 2015 14:49:35 +0000 (16:49 +0200)
In order to comfortably render video, audio and all other file types
with a registered Renderer class (RenderingRegistry introduced with
#61800) in FE, we add a new ViewHelper.

The new MediaViewHelper first checks if there is a Renderer present for
the given file. If not, it will as fallback render a image tag.
This way it is a replacement for the ImageViewHelper in most cases.

Releases: master
Resolves: #66366
Change-Id: I4f92b5f1030238aacb544e45a35189f4e3d0732e
Reviewed-on: http://review.typo3.org/38624
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Sascha Egerer <sascha@sascha-egerer.de>
Reviewed-by: Markus Sommer <markussom@posteo.de>
Tested-by: Markus Sommer <markussom@posteo.de>
Reviewed-by: Frans Saris <franssaris@gmail.com>
Tested-by: Frans Saris <franssaris@gmail.com>
typo3/sysext/core/Documentation/Changelog/master/Feature-66366-IntroducedMediaViewHelper.rst [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/MediaViewHelper.php [new file with mode: 0644]

diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-66366-IntroducedMediaViewHelper.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-66366-IntroducedMediaViewHelper.rst
new file mode 100644 (file)
index 0000000..a8a848b
--- /dev/null
@@ -0,0 +1,39 @@
+============================================
+Feature: #66366 - Introduced MediaViewHelper
+============================================
+
+Description
+===========
+
+In order to comfortably render video, audio and all other file types with a registered Renderer class (RenderingRegistry
+introduced with #61800) in FE, the ``MediaViewHelper`` has been added.
+
+The ``MediaViewHelper`` first checks if there is a Renderer present for the given file. If not,  it will as fallback
+render a image tag. This way it is a replacement for the ImageViewHelper in most cases. classes for rendering video and
+audio tags.
+
+Examples:
+---------
+
+.. code-block:: html
+
+    <code title="Image Object">
+        <f:media file="{file}" width="400" height="375" />
+    </code>
+    <output>
+        <img alt="alt set in image record" src="fileadmin/_processed_/323223424.png" width="396" height="375" />
+    </output>
+
+    <code title="MP4 Video Object">
+        <f:media file="{file}" width="400" height="375" />
+    </code>
+    <output>
+        <video width="400" height="375" controls><source src="fileadmin/user_upload/my-video.mp4" type="video/mp4"></video>
+    </output>
+
+    <code title="MP4 Video Object with loop and autoplay option set">
+        <f:media file="{file}" width="400" height="375" additionalConfig="{loop: '1', autoplay: '1'}" />
+    </code>
+    <output>
+        <video width="400" height="375" controls loop><source src="fileadmin/user_upload/my-video.mp4" type="video/mp4"></video>
+    </output>
\ No newline at end of file
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/MediaViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/MediaViewHelper.php
new file mode 100644 (file)
index 0000000..dadc36a
--- /dev/null
@@ -0,0 +1,144 @@
+<?php
+namespace TYPO3\CMS\Fluid\ViewHelpers;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Resource\FileInterface;
+use TYPO3\CMS\Core\Resource\FileReference;
+use TYPO3\CMS\Core\Resource\Rendering\RendererRegistry;
+use TYPO3\CMS\Extbase\Domain\Model\AbstractFileFolder;
+use TYPO3\CMS\Extbase\Service\ImageService;
+use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
+
+/**
+ * Render a given media file with the correct html tag.
+ *
+ * It asks the RendererRegister for the correct Renderer class and if not found it falls
+ * back to the ImageViewHelper as that is the "Renderer" class for images in Fluid context.
+ *
+ * = Examples =
+ *
+ * <code title="Image Object">
+ *     <f:media file="{file}" width="400" height="375" />
+ * </code>
+ * <output>
+ *     <img alt="alt set in image record" src="fileadmin/_processed_/323223424.png" width="396" height="375" />
+ * </output>
+ *
+ * <code title="MP4 Video Object">
+ *     <f:media file="{file}" width="400" height="375" />
+ * </code>
+ * <output>
+ *     <video width="400" height="375" controls><source src="fileadmin/user_upload/my-video.mp4" type="video/mp4"></video>
+ * </output>
+ *
+ * <code title="MP4 Video Object with loop and autoplay option set">
+ *     <f:media file="{file}" width="400" height="375" additionalConfig="{loop: '1', autoplay: '1'}" />
+ * </code>
+ * <output>
+ *     <video width="400" height="375" controls loop><source src="fileadmin/user_upload/my-video.mp4" type="video/mp4"></video>
+ * </output>
+ */
+class MediaViewHelper extends AbstractTagBasedViewHelper {
+
+       /**
+        * @var string
+        */
+       protected $tagName = 'img';
+
+       /**
+        * Initialize arguments.
+        *
+        * @return void
+        */
+       public function initializeArguments() {
+               parent::initializeArguments();
+               $this->registerUniversalTagAttributes();
+               $this->registerTagAttribute('alt', 'string', 'Specifies an alternate text for an image', FALSE);
+       }
+
+       /**
+        * Render a given media file
+        *
+        * @param FileInterface|AbstractFileFolder $file
+        * @param array $additionalConfig This array can hold additional configuration that is passed though to the Renderer object
+        * @param string $width This can be a numeric value representing the fixed width of in pixels. But you can also perform simple calculations by adding "m" or "c" to the value. See imgResource.width for possible options.
+        * @param string $height This can be a numeric value representing the fixed height in pixels. But you can also perform simple calculations by adding "m" or "c" to the value. See imgResource.width for possible options.
+        * @return string Rendered tag
+        */
+       public function render($file, $additionalConfig = array(), $width = NULL, $height = NULL) {
+
+               // get Resource Object (non ExtBase version)
+               if (is_callable(array($file, 'getOriginalResource'))) {
+                       // We have a domain model, so we need to fetch the FAL resource object from there
+                       $file = $file->getOriginalResource();
+               }
+
+               $fileRenderer = RendererRegistry::getInstance()->getRenderer($file);
+
+               // Fallback to image when no renderer is found
+               if ($fileRenderer === NULL) {
+                       return $this->renderImage($file, $width, $height);
+               } else {
+                       $additionalConfig = array_merge_recursive($this->arguments, $additionalConfig);
+                       return $fileRenderer->render($file, $width, $height, $additionalConfig);
+               }
+       }
+
+       /**
+        * Render img tag
+        *
+        * @param FileInterface $image
+        * @param string $width
+        * @param string $height
+        * @return string Rendered img tag
+        */
+       protected function renderImage(FileInterface $image, $width, $height) {
+               $crop = $image instanceof FileReference ? $image->getProperty('crop') : NULL;
+               $processingInstructions = array(
+                       'width' => $width,
+                       'height' => $height,
+                       'crop' => $crop,
+               );
+               $imageService = $this->getImageService();
+               $processedImage = $imageService->applyProcessingInstructions($image, $processingInstructions);
+               $imageUri = $imageService->getImageUri($processedImage);
+
+               $this->tag->addAttribute('src', $imageUri);
+               $this->tag->addAttribute('width', $processedImage->getProperty('width'));
+               $this->tag->addAttribute('height', $processedImage->getProperty('height'));
+
+               $alt = $image->getProperty('alternative');
+               $title = $image->getProperty('title');
+
+               // The alt-attribute is mandatory to have valid html-code, therefore add it even if it is empty
+               if (empty($this->arguments['alt'])) {
+                       $this->tag->addAttribute('alt', $alt);
+               }
+               if (empty($this->arguments['title']) && $title) {
+                       $this->tag->addAttribute('title', $title);
+               }
+
+               return $this->tag->render();
+       }
+
+       /**
+        * Return an instance of ImageService
+        *
+        * @return ImageService
+        */
+       protected function getImageService() {
+               return $this->objectManager->get(ImageService::class);
+       }
+}