diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/ImageViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/ImageViewHelper.php index 66502f417a92af97a3477d3fd2e6c2d54f9e0f60..2fab5aa383e9d6c7df27c75f311706fe00766b9c 100644 --- a/typo3/sysext/fluid/Classes/ViewHelpers/ImageViewHelper.php +++ b/typo3/sysext/fluid/Classes/ViewHelpers/ImageViewHelper.php @@ -203,8 +203,12 @@ final class ImageViewHelper extends AbstractTagBasedViewHelper $this->tag->addAttribute('width', $processedImage->getProperty('width')); $this->tag->addAttribute('height', $processedImage->getProperty('height')); - // The alt-attribute is mandatory to have valid html-code, therefore add it even if it is empty - if (empty($this->arguments['alt'])) { + if (is_string($this->arguments['alt'] ?? false) && $this->arguments['alt'] === '') { + // In case the "alt" attribute is explicitly set to an empty string, respect + // this to allow excluding it from screen readers, improving accessibility. + $this->tag->addAttribute('alt', ''); + } elseif (empty($this->arguments['alt'])) { + // The alt-attribute is mandatory to have valid html-code, therefore use "alternative" property or empty $this->tag->addAttribute('alt', $image->hasProperty('alternative') ? $image->getProperty('alternative') : ''); } // Add title-attribute from property if not already set and the property is not an empty string diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/ImageViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/ImageViewHelperTest.php index 22a4a988f66adbfb86f301ccdca331b3bebe216b..a970a94f13675d77b56fab468823027281bd88ce 100644 --- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/ImageViewHelperTest.php +++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/ImageViewHelperTest.php @@ -19,8 +19,13 @@ namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers; use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; use TYPO3\CMS\Core\Http\ServerRequest; +use TYPO3\CMS\Core\Resource\File; +use TYPO3\CMS\Core\Resource\Index\MetaDataRepository; +use TYPO3\CMS\Core\Resource\ResourceFactory; +use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters; use TYPO3\CMS\Extbase\Mvc\Request; +use TYPO3\CMS\Extbase\Service\ImageService; use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -182,4 +187,40 @@ final class ImageViewHelperTest extends FunctionalTestCase $context->getTemplatePaths()->setTemplateSource($template); self::assertMatchesRegularExpression($expected, (new TemplateView($context))->render()); } + + /** + * @test + */ + public function renderReturnsCorrectAltAttribute(): void + { + $imageServiceMock = $this->createMock(ImageService::class); + $imageServiceMock->method('getImage')->willReturn(new File([], $this->get(ResourceFactory::class)->getDefaultStorage())); + + $metaDataRepository = $this->createMock(MetaDataRepository::class); + $metaDataRepository->method('findByFileUid')->willReturn(['alternative' => 'alt text']); + + GeneralUtility::setSingletonInstance(ImageService::class, $imageServiceMock); + GeneralUtility::setSingletonInstance(MetaDataRepository::class, $metaDataRepository); + + $context = $this->get(RenderingContextFactory::class)->create(); + + // No alt attribute given - use metadata + $context->getTemplatePaths()->setTemplateSource( + '<f:image src="EXT:fluid/Tests/Functional/Fixtures/ViewHelpers/ImageViewHelperTest.jpg" />' + ); + self::assertStringContainsString( + 'alt="alt text"', + (new TemplateView($context))->render() + ); + + // Enforce empty alt attribute - omit metadata fallback + $context->getTemplatePaths()->setTemplateSource( + '<f:image src="EXT:fluid/Tests/Functional/Fixtures/ViewHelpers/ImageViewHelperTest.jpg" alt="" />' + ); + self::assertStringContainsString( + 'alt=""', + (new TemplateView($context))->render() + ); + + } }