[TASK] Use FAL functions for image rendering 11/25511/13
authorAlexander Stehlik <alexander.stehlik@googlemail.com>
Sun, 2 Feb 2014 17:07:35 +0000 (18:07 +0100)
committerFrans Saris <franssaris@gmail.com>
Tue, 4 Mar 2014 17:00:26 +0000 (18:00 +0100)
Instead of relying on the backward compatiblity layer of the
FrontendContentAdapterService when rendering images with
css_styled_content the render_textpic method is modified so that it
is also be possible to use FAL functions and properties for image
rendering.

The captionsSplit / imageTextSplit constants are removed because
every image has its own properties for that with FAL and they are
not needed any more.

The globalCaption rendering was removed because the captions are now
always attached to a single image.

The longdescURL handling was also removed because the files do not
have this property at the moment and the longdescURL field for
tt_content records is also not visible in the Backend.

Resolves: #53764
Releases: 6.2
Change-Id: I1d9c8ad1d7a498816e724960613818a05d587d4f
Reviewed-on: https://review.typo3.org/25511
Reviewed-by: Markus Klein
Tested-by: Markus Klein
Reviewed-by: Frans Saris
Tested-by: Frans Saris
typo3/sysext/css_styled_content/Classes/Controller/CssStyledContentController.php
typo3/sysext/css_styled_content/pi1/locallang.xlf
typo3/sysext/css_styled_content/static/constants.txt
typo3/sysext/css_styled_content/static/setup.txt

index 85819d6..0264db3 100644 (file)
@@ -28,6 +28,7 @@ namespace TYPO3\CMS\CssStyledContent\Controller;
  ***************************************************************/
 
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\MathUtility;
 
 /**
  * Plugin class - instantiated from TypoScript.
@@ -470,6 +471,9 @@ class CssStyledContentController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlug
                if (!$renderMethod || $renderMethod == 'table') {
                        return $this->cObj->IMGTEXT($conf);
                }
+               if (isset($conf['preRenderRegisters.'])) {
+                       $this->cObj->LOAD_REGISTER($conf['preRenderRegisters.'], 'LOAD_REGISTER');
+               }
                // Specific configuration for the chosen rendering method
                if (is_array($conf['rendering.'][$renderMethod . '.'])) {
                        $conf = array_replace_recursive($conf, $conf['rendering.'][$renderMethod . '.']);
@@ -483,12 +487,16 @@ class CssStyledContentController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlug
                        // No images, that's easy
                        return $content;
                }
-               $imgs = GeneralUtility::trimExplode(',', $imgList);
+               $imgs = GeneralUtility::trimExplode(',', $imgList, TRUE);
+               if (count($imgs) === 0) {
+                       // The imgList was not empty but did only contain empty values
+                       return $content;
+               }
                $imgStart = (int)$this->cObj->stdWrap($conf['imgStart'], $conf['imgStart.']);
                $imgCount = count($imgs) - $imgStart;
                $imgMax = (int)$this->cObj->stdWrap($conf['imgMax'], $conf['imgMax.']);
                if ($imgMax) {
-                       $imgCount = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($imgCount, 0, $imgMax);
+                       $imgCount = MathUtility::forceIntegerInRange($imgCount, 0, $imgMax);
                }
                $imgPath = $this->cObj->stdWrap($conf['imgPath'], $conf['imgPath.']);
                // Does we need to render a "global caption" (below the whole image block)?
@@ -497,9 +505,13 @@ class CssStyledContentController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlug
                        // If we just have one image, the caption relates to the image, so it is not "global"
                        $renderGlobalCaption = FALSE;
                }
+               $imgListContainsReferenceUids = (bool)(isset($conf['imgListContainsReferenceUids.'])
+                       ? $this->cObj->stdWrap($conf['imgListContainsReferenceUids'], $conf['imgListContainsReferenceUids.'])
+                       : $conf['imgListContainsReferenceUids']);
                // Use the calculated information (amount of images, if global caption is wanted) to choose a different rendering method for the images-block
                $GLOBALS['TSFE']->register['imageCount'] = $imgCount;
                $GLOBALS['TSFE']->register['renderGlobalCaption'] = $renderGlobalCaption;
+               $fallbackRenderMethod = '';
                if ($conf['fallbackRendering']) {
                        $fallbackRenderMethod = $this->cObj->cObjGetSingle($conf['fallbackRendering'], $conf['fallbackRendering.']);
                }
@@ -577,7 +589,7 @@ class CssStyledContentController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlug
                                $imgKey = $a + $imgStart;
 
                                /** @var $file \TYPO3\CMS\Core\Resource\File */
-                               if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($imgs[$imgKey])) {
+                               if (MathUtility::canBeInterpretedAsInteger($imgs[$imgKey])) {
                                        $file = $this->getResourceFactory()->getFileObject((int)$imgs[$imgKey]);
                                } else {
                                        $file = $this->getResourceFactory()->getFileObjectFromCombinedIdentifier($imgPath . $imgs[$imgKey]);
@@ -606,8 +618,9 @@ class CssStyledContentController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlug
                for ($a = 0; $a < $imgCount; $a++) {
                        $imgKey = $a + $imgStart;
                        // If the image cannot be interpreted as integer (therefore filename and no FAL id), add the image path
-                       if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($imgs[$imgKey])) {
+                       if (MathUtility::canBeInterpretedAsInteger($imgs[$imgKey])) {
                                $totalImagePath = (int)$imgs[$imgKey];
+                               $this->initializeCurrentFileInContentObjectRenderer($totalImagePath, $imgListContainsReferenceUids);
                        } else {
                                $totalImagePath = $imgPath . $imgs[$imgKey];
                        }
@@ -816,6 +829,13 @@ class CssStyledContentController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlug
                                                // Register IMAGE_NUM_CURRENT for the caption
                                                $GLOBALS['TSFE']->register['IMAGE_NUM_CURRENT'] = $imageKey;
                                                $this->cObj->data[$this->cObj->currentValKey] = $origImages[$imageKey]['origFile'];
+                                               if (MathUtility::canBeInterpretedAsInteger($imgs[$imageKey])) {
+                                                       $this->initializeCurrentFileInContentObjectRenderer((int)$imgs[$imageKey], $imgListContainsReferenceUids);
+                                               } elseif (!isset($imgs[$imageKey])) {
+                                                       // If not all columns in the last row are filled $imageKey gets larger than
+                                                       // the array. In that case we clear the current file.
+                                                       $this->cObj->setCurrentFile(NULL);
+                                               }
                                                // Get the image if not an empty cell
                                                if (isset($imgsTag[$imageKey])) {
                                                        $image = $this->cObj->stdWrap($imgsTag[$imageKey], $conf['imgTagStdWrap.']);
@@ -941,6 +961,9 @@ class CssStyledContentController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlug
                                        $GLOBALS['TSFE']->register['imagewidth'] = $origImages[$imgKey][0];
                                        $GLOBALS['TSFE']->register['imagespace'] = $imageSpace;
                                        $GLOBALS['TSFE']->register['imageheight'] = $origImages[$imgKey][1];
+                                       if (MathUtility::canBeInterpretedAsInteger($imgs[$imgKey])) {
+                                               $this->initializeCurrentFileInContentObjectRenderer(intval($imgs[$imgKey]), $imgListContainsReferenceUids);
+                                       }
                                        if ($imageSpace > $maxImageSpace) {
                                                $maxImageSpace = $imageSpace;
                                        }
@@ -1035,7 +1058,8 @@ class CssStyledContentController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlug
                                $images = $this->cObj->stdWrap($images, $conf['imageStdWrapNoWidth.']);
                        }
                }
-               return str_replace(
+
+               $output = str_replace(
                        array(
                                '###TEXT###',
                                '###IMAGES###',
@@ -1048,6 +1072,32 @@ class CssStyledContentController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlug
                        ),
                        $this->cObj->cObjGetSingle($conf['layout'], $conf['layout.'])
                );
+
+               if (isset($conf['preRenderRegisters.'])) {
+                       $this->cObj->LOAD_REGISTER($conf['preRenderRegisters.'], 'RESTORE_REGISTER');
+               }
+
+               return $output;
+       }
+
+       /**
+        * Loads the file / file reference object and sets it in the
+        * currentFile property of the ContentObjectRenderer.
+        *
+        * This makes the file data available during image rendering.
+        *
+        * @param int $fileUid The UID of the file or file reference (depending on $treatAsReference) that should be loaded.
+        * @param bool $treatAsReference If TRUE the given UID will be used to load a file reference otherwise it will be used to load a regular file.
+        * @return void
+        */
+       protected function initializeCurrentFileInContentObjectRenderer($fileUid, $treatAsReference) {
+               $resourceFactory = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance();
+               if ($treatAsReference) {
+                       $imageFile = $resourceFactory->getFileReferenceObject($fileUid);
+               } else {
+                       $imageFile = $resourceFactory->getFileObject($fileUid);
+               }
+               $this->cObj->setCurrentFile($imageFile);
        }
 
        /***********************************
index eb7f267..7701270 100644 (file)
@@ -69,6 +69,9 @@
                        <trans-unit id="eIcon.caption" xml:space="preserve">
                                <source>Edit image caption</source>
                        </trans-unit>
+                       <trans-unit id="eIcon.caption_position" xml:space="preserve">
+                               <source>Edit image caption alignment</source>
+                       </trans-unit>
                        <trans-unit id="eIcon.bullets" xml:space="preserve">
                                <source>Edit bullet list</source>
                        </trans-unit>
index 77d8897..b8a008c 100644 (file)
@@ -50,9 +50,6 @@ styles.content.imgtext {
     # cat=content/cImage/c5; type=string; label= Lightbox rel="" attribute: Which rel="" attribute to use for lightbox links (only applicable if lightbox rendering is enabled)
   linkWrap.lightboxRelAttribute = lightbox[{field:uid}]
 
-  captionSplit = 0
-    # cat=content/cImage/e1; type=boolean; label= Images, text split: If this is checked, then the image text (caption, alt, title, longdesc) will be split by each line and they will appear on the corresponding images in the imagelist.
-  imageTextSplit = 1
     # cat=content/cImage/e2; type=string; label= Images, empty title handling: How will the 'title' attribute be handled if no title is given for an image. Possible choices: "keepEmpty", "useAlt" or "removeAttr". Recommended for accessibility is "removeAttr". For correct tooltips on IE, use "keepEmpty". For previous TYPO3 behaviour, use "useAlt".
   emptyTitleHandling = removeAttr
     # cat=content/cImage/e3; type=boolean; label= Images, title in link: Do you want the 'title' attribute to be added to the surrounding <a> tag, if present? Recommended for accessibility is "true".
index 7d131ae..c0ef255 100644 (file)
@@ -634,15 +634,42 @@ tt_content.image.20 = USER
 tt_content.image.20 {
        userFunc = TYPO3\CMS\CssStyledContent\Controller\CssStyledContentController->render_textpic
 
+       preRenderRegisters {
+               // To optimize performance we load all image captions into a register
+               // because we need to know if at least one image has a caption at
+               // multiple places to determine the render method.
+               allImageCaptions.cObject = FILES
+               allImageCaptions.cObject {
+                       references {
+                               table = tt_content
+                               uid.field = uid
+                               fieldName = image
+                       }
+                       renderObj = TEXT
+                       renderObj.data = file:current:description
+               }
+       }
+
        # Image source
-       imgList.field = image
-       imgList.override.field = image_fileUids
+       imgList.cObject = FILES
+       imgList.cObject {
+               references < tt_content.image.20.preRenderRegisters.allImageCaptions.cObject.references
+               renderObj = TEXT
+               renderObj.data = file:current:uid
+               renderObj.wrap = |,
+       }
        imgPath = uploads/pics/
 
+       // This needs to be set because the UID list generated in the imgList
+       // setting contains UIDs of file references (not files).
+       imgListContainsReferenceUids = 1
+
        # Single image rendering
        imgObjNum = 1
        1 {
-               file.import.current = 1
+               // Since the current file is a reference we need to use uid_local
+               // to get the UID of the original file.
+               file.import.data = file:current:uid_local
                file.width.field = imagewidth
 
                layoutKey = {$styles.content.imgtext.layoutKey}
@@ -698,6 +725,7 @@ tt_content.image.20 {
                        width = {$styles.content.imgtext.linkWrap.width}
                        height = {$styles.content.imgtext.linkWrap.height}
                        effects = {$styles.content.imgtext.linkWrap.effects}
+                       treatIdAsReference = 1
 
                        JSwindow = 1
                        JSwindow.newWindow = {$styles.content.imgtext.linkWrap.newWindow}
@@ -706,14 +734,10 @@ tt_content.image.20 {
                        directImageLink = {$styles.content.imgtext.linkWrap.lightboxEnabled}
 
                        enable.field = image_zoom
-                       enable.ifEmpty.typolink.parameter.field = image_link
-                       enable.ifEmpty.typolink.parameter.listNum.splitChar = 10
-                       enable.ifEmpty.typolink.parameter.listNum.stdWrap.data = register : IMAGE_NUM_CURRENT
+                       enable.ifEmpty.typolink.parameter.data = file:current:link
                        enable.ifEmpty.typolink.returnLast = url
 
-                       typolink.parameter.field = image_link
-                       typolink.parameter.listNum.splitChar = 10
-                       typolink.parameter.listNum.stdWrap.data = register : IMAGE_NUM_CURRENT
+                       typolink.parameter.data = file:current:link
 
                        typolink.target < lib.parseTarget
                        typolink.target =
@@ -728,59 +752,12 @@ tt_content.image.20 {
 
                altText = TEXT
                altText {
-                       field = altText
+                       data = file:current:alternative
                        stripHtml = 1
-                       split.token.char = 10
-                       split.token.if.isTrue = {$styles.content.imgtext.imageTextSplit}
-                       split.returnKey.data = register : IMAGE_NUM_CURRENT
-               }
-
-               params =
-               params {
-                       override {
-                               dataWrap = aria-describedby="csc-longdesc-{field:uid}-{register:IMAGE_NUM_CURRENT}"
-                               if {
-                                       isTrue {
-                                               cObject = TEXT
-                                               cObject {
-                                                       field = imagecaption
-                                                       required = 1
-                                                       parseFunc =< lib.parseFunc
-                                                       split {
-                                                               token {
-                                                                       char = 10
-                                                                       if.isPositive = {$styles.content.imgtext.imageTextSplit} + {$styles.content.imgtext.captionSplit}
-                                                               }
-                                                               returnKey.data = register : IMAGE_NUM_CURRENT
-                                                       }
-                                               }
-                                       }
-                                       isFalse = 1
-                                       isFalse {
-                                               if {
-                                                       isFalse {
-                                                               cObject = TEXT
-                                                               cObject {
-                                                                       field = longdescURL
-                                                                       split {
-                                                                               token {
-                                                                                       char = 10
-                                                                               }
-                                                                               returnKey.data = register : IMAGE_NUM_CURRENT
-                                                                       }
-                                                               }
-                                                       }
-                                               }
-                                       }
-                                       isPositive = {$styles.content.imgtext.imageTextSplit} + {$styles.content.imgtext.captionSplit}
-                                       value = html5
-                                       equals.data = TSFE:config|config|doctype
-                               }
-                       }
                }
 
                titleText < .altText
-               titleText.field = titleText
+               titleText.data = file:current:title
 
                longdescURL {
                        parameter {
@@ -820,46 +797,19 @@ tt_content.image.20 {
                1 {
                        1 = TEXT
                        1 {
-                               field = imagecaption
+                               data = file:current:description
                                required = 1
                                parseFunc =< lib.parseFunc
                                br = 1
-                               split.token.char = 10
-                               split.token.if.isPositive = {$styles.content.imgtext.imageTextSplit} + {$styles.content.imgtext.captionSplit}
-                               split.returnKey.data = register : IMAGE_NUM_CURRENT
-                       }
-                       stdWrap {
-                               required = 1
-                               typolink {
-                                       parameter {
-                                               field = longdescURL
-                                               trim = 1
-                                               split {
-                                                       token {
-                                                               char = 10
-                                                       }
-                                                       returnKey.data = register : IMAGE_NUM_CURRENT
-                                               }
-                                               if {
-                                                       value = html5
-                                                       equals.data = TSFE:config|config|doctype
-                                               }
-                                       }
-                                       ATagParams {
-                                               dataWrap = id="csc-longdesc-{field:uid}-{register:IMAGE_NUM_CURRENT}"
-                                       }
-                                       target = {$styles.content.links.target}
-                                       extTarget = {$styles.content.links.extTarget}
-                               }
                        }
                }
        }
 
-       # captionSplit is deprecated, use imageTextSplit instead
-       captionSplit = {$styles.content.imgtext.captionSplit}
        captionAlign.field = imagecaption_position
-       # caption/alttext/title/longdescURL splitting
-       imageTextSplit = {$styles.content.imgtext.imageTextSplit}
+
+       // This needs to be set to TRUE because otherwise render_textpic will
+       // render a global caption which we do not have.
+       imageTextSplit = 1
 
        borderThick = {$styles.content.imgtext.borderThick}
        borderClass = {$styles.content.imgtext.borderClass}
@@ -1031,7 +981,7 @@ tt_content.image.20 {
                                10 = TEXT
                                10 {
                                        if {
-                                               isTrue.field = imagecaption
+                                               isTrue.data = file:current:description
                                                value = 1
                                                equals.data = register:imageCount
                                        }
@@ -1045,30 +995,18 @@ tt_content.image.20 {
                                                value = 1
                                                isGreaterThan.data = register:imageCount
                                                isTrue.if.isFalse.data = register:renderGlobalCaption
-                                               isTrue.field = imagecaption
+                                               isTrue.data = register:allImageCaptions
                                        }
                                        value = splitCaption
                                }
 
-                               # Multiple images and one global caption
-                               30 = TEXT
-                               30 {
-                                       if {
-                                               value = 1
-                                               isGreaterThan.data = register:imageCount
-                                               isTrue.if.isTrue.data = register:renderGlobalCaption
-                                               isTrue.field = imagecaption
-                                       }
-                                       value = globalCaption
-                               }
-
                                # Multiple images and no caption at all
                                40 = TEXT
                                40 {
                                        if {
                                                value = 1
                                                isGreaterThan.data = register:imageCount
-                                               isFalse.field = imagecaption
+                                               isFalse.data = register:allImageCaptions
                                        }
                                        value = noCaption
                                }
@@ -1201,54 +1139,15 @@ tt_content.image.20 {
                                }
                        }
                }
-               globalCaption {
-                       # Just one image without a caption
-                       fallbackRendering < tt_content.image.20.rendering.singleNoCaption.fallbackRendering.10
-                       allStdWrap {
-                               dataWrap = <div class="csc-textpic-imagewrap"><table>###CAPTION###<tbody> | </tbody></table></div>
-                               dataWrap {
-                                       override = <figure class="csc-textpic-imagewrap" data-csc-images="{register:imageCount}" data-csc-cols="{field:imagecols}"> | ###CAPTION###</figure>
-                                       override {
-                                               if {
-                                                       value = html5
-                                                       equals.data = TSFE:config|config|doctype
-                                               }
-                                       }
-                               }
-                       }
-                       singleStdWrap {
-                               wrap = <div class="csc-textpic-image###CLASSES###"> | </div>
-                               wrap {
-                                       override = <div class="csc-textpic-image###CLASSES###"> | </div>
-                               }
-                       }
-                       rowStdWrap.wrap = <div class="csc-textpic-imagerow"> | </div>
-                       noRowsStdWrap.wrap = <div class="csc-textpic-imagerow csc-textpic-imagerow-none"> | </div>
-                       lastRowStdWrap.wrap = <div class="csc-textpic-imagerow csc-textpic-imagerow-last"> | </div>
-                       columnStdWrap.wrap = <div class="csc-textpic-imagecolumn###CLASSES###"> | </div>
-                       caption {
-                               required = 1
-                               wrap = <caption class="csc-textpic-caption"> | </caption>
-                               wrap {
-                                       override = <figcaption class="csc-textpic-caption###CLASSES###"> | </figcaption>
-                                       override {
-                                               if {
-                                                       value = html5
-                                                       equals.data = TSFE:config|config|doctype
-                                               }
-                                       }
-                               }
-                       }
-               }
        }
        renderMethod = singleNoCaption
 
-       editIcons = tt_content : image [imageorient|imagewidth|imageheight], [imagecols|image_noRows|imageborder],[image_link|image_zoom],[image_compression|image_effects|image_frames],imagecaption[imagecaption_position]
+       editIcons = tt_content : image [imageorient|imagewidth|imageheight],[imagecols|image_noRows|imageborder],[image_zoom],[image_compression|image_effects|image_frames],[imagecaption_position]
        editIcons.iconTitle.data = LLL:EXT:css_styled_content/pi1/locallang.xml:eIcon.images
 
-       caption.editIcons = tt_content : imagecaption[imagecaption_position]
+       caption.editIcons = tt_content : imagecaption_position
        caption.editIcons.beforeLastTag=1
-       caption.editIcons.iconTitle.data = LLL:EXT:css_styled_content/pi1/locallang.xml:eIcon.caption
+       caption.editIcons.iconTitle.data = LLL:EXT:css_styled_content/pi1/locallang.xml:eIcon.caption_position
 
        stdWrap.prefixComment = 2 | Image block:
 }