Ich erweitere das nochmal:
In die cms-element-image-gallery.html.twig kommt:
{% sw_extends '@Storefront/storefront/element/cms-element-image-gallery.html.twig' %}
{% block element_image_gallery_inner_item %}
<div class="gallery-slider-item-container">
<div class="gallery-slider-item is-{{ displayMode }} js-magnifier-container"
{% if minHeight and (displayMode == "cover" or displayMode == "contain") %} style="min-height: {{ minHeight }}"{% endif %}
{% if (displayMode == "standard" and image.isSpatialObject()) %} style="min-height: 240px"{% endif %}>
{% set attributes = {
class: 'img-fluid gallery-slider-image',
title: (image.translated.alt ?: fallbackImageTitle)
} %}
{# @experimental stableVersion:v6.7.0 feature:SPATIAL_BASES #}
{% block element_image_gallery_inner_item_spatial %}
{% if image.isSpatialObject() %}
<span class="badge bg-secondary m-3 position-absolute top-0 end-0 d-md-none">3D</span>
<div class="spatial-canvas-spinner position-absolute top-50 start-50 bg-white flex justify-content-center align-items-center" style="--bs-bg-opacity: .8;">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div class="gallery-slider-spatial-canvas-wrapper position-absolute start-0 end-0 top-0 bottom-0">
<canvas
data-spatial-gallery-slider-viewer
data-spatial-model-url="{{ image.url }}"
data-product-slider-position="{{ loop.index0 }}"
></canvas>
<span
class="spatial-canvas-note spatial-slider-movement-note position-absolute start-50 text-center badge mx-0 py-1 px-3 translate-middle-x"
data-spatial-movement-note
data-spatial-movement-note-touch-text="{{ 'component.cms.imageGallery.touchMove'|trans|striptags }}"
>
{{ 'component.cms.imageGallery.clickMove'|trans|striptags }}
</span>
{% if image.config.spatial.arReady %}
<div class="ar-button button"
data-spatial-ar-viewer
data-spatial-ar-viewer-options='{ "spatialArId": "{{ image.id }}" }'
data-spatial-model-url="{{ image.url }}">
{% sw_icon 'augmented' style {
'size': 'fluid'
} %}
</div>
{% sw_include '@Storefront/storefront/utilities/ar-overlay.html.twig' %}
{% endif %}
</div>
{# @experimental stableVersion:v6.7.0 feature:SPATIAL_BASES #}
{% block element_image_gallery_qr_code_modal %}
{% sw_include '@Storefront/storefront/utilities/qr-code-modal.html.twig'
with {
"qrCodeOptions": {
"params": {
"autostartAr": image.id
}
}
}
%}
{% endblock %}
{% elseif image.getMediaType().getName() === 'VIDEO' %}
{% set attributes = attributes|merge({ controls: true }) %}
{% if isProduct %}
{% set attributes = attributes|merge({ itemprop: 'video' }) %}
{% endif %}
{% sw_include '@Storefront/storefront/utilities/video.html.twig' with {
media: image,
attributes: attributes
} %}
{% else %}
{% set attributes = attributes|merge({
class: attributes.class ~ ' magnifier-image js-magnifier-image',
alt: (image.translated.alt ?: fallbackImageTitle),
'data-full-image': image.url
}) %}
{% if displayMode == 'cover' or displayMode == 'contain' %}
{% set attributes = attributes|merge({ 'data-object-fit': displayMode }) %}
{% endif %}
{% if isProduct %}
{% set attributes = attributes|merge({ itemprop: 'image' }) %}
{% endif %}
{% if loop.first %}
{% set attributes = attributes|merge({ fetchpriority: 'high' }) %}
{% endif %}
{% sw_thumbnails 'gallery-slider-image-thumbnails' with {
media: image,
attributes: attributes
} %}
{% endif %}
{% endblock %}
</div>
</div>
{% endblock %}
{% block element_image_gallery_inner_zoom_modal_slider_item %}
<div class="gallery-slider-item">
{% block element_image_gallery_inner_zoom_modal_slider_item_zoom_container %}
<div class="image-zoom-container"
{% if image.getMediaType().getName() !== 'VIDEO' %}data-image-zoom="true"{% endif %}>
{% set attributes = {
class: 'gallery-slider-image',
title: (image.translated.alt ?: fallbackImageTitle)
} %}
{% block element_image_gallery_inner_zoom_modal_slider_item_image %}
{# @experimental stableVersion:v6.7.0 feature:SPATIAL_BASES #}
{% block element_image_gallery_inner_zoom_modal_slider_item_image_spatial %}
{% if image.isSpatialObject() %}
{% sw_thumbnails 'gallery-slider-image-thumbnails' with {
media: image,
attributes: {
'class': 'd-none gallery-slider-image js-image-zoom-element js-load-img',
'alt': (image.translated.alt ?: fallbackImageTitle),
'title': (image.translated.title ?: fallbackImageTitle)
},
load: false,
loadOriginalImage: true,
autoColumnSizes: false
} %}
{% elseif image.getMediaType().getName() === 'VIDEO' %}
{% set attributes = attributes|merge({ controls: true }) %}
{% sw_include '@Storefront/storefront/utilities/video.html.twig' with {
media: image,
attributes: attributes
} %}
{% else %}
{% set attributes = attributes|merge({
class: attributes.class ~ ' js-image-zoom-element js-load-img',
alt: (image.translated.alt ?: fallbackImageTitle)
}) %}
{% sw_thumbnails 'gallery-slider-image-thumbnails' with {
media: image,
attributes: attributes,
load: false,
loadOriginalImage: true,
autoColumnSizes: false
} %}
{% endif %}
{% endblock %}
{% endblock %}
</div>
{# @experimental stableVersion:v6.7.0 feature:SPATIAL_BASES #}
{% block element_image_gallery_inner_zoom_modal_slider_item_zoom_container_spatial %}
{% if image.isSpatialObject() %}
<div class="spatial-canvas-spinner position-absolute top-50 start-50 translate-middle bg-white flex justify-content-center align-items-center" style="--bs-bg-opacity: .8;">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div class="gallery-slider-spatial-canvas-wrapper position-absolute start-0 end-0 top-0 bottom-0">
<canvas
data-spatial-zoom-gallery-slider-viewer
data-spatial-model-url="{{ image.url }}"
data-zoom-product-slider-position="{{ loop.index0 }}"
></canvas>
<span
class="spatial-canvas-note spatial-slider-movement-note position-absolute start-50 text-center badge mx-0 py-1 px-3 translate-middle-x"
data-spatial-movement-note
data-spatial-movement-note-touch-text="{{ 'component.cms.imageGallery.touchMove'|trans|striptags }}"
>
{{ 'component.cms.imageGallery.clickMove'|trans|striptags }}
</span>
{% if image.config.spatial.arReady %}
<div class="ar-button button mb-2"
data-spatial-ar-viewer
data-spatial-ar-viewer-options='{ "spatialArId": "{{ image.id }}" }'
data-spatial-model-url="{{ image.url }}">
{% sw_icon 'augmented' style {
'size': 'fluid'
} %}
</div>
{% sw_include '@Storefront/storefront/utilities/ar-overlay.html.twig' %}
{% endif %}
</div>
{% endif %}
{% endblock %}
{% endblock %}
</div>
{% endblock %}
Mit dem Code ab {% block element_image_gallery_inner_zoom_modal_slider_item %}
wird der Alt-Text auch angezeigt, wenn der Kunde aufs Bild klickt und dieses groß angezeigt wird.
Dann noch in die product/card/box-standard.html.twig
(sofern ihr diese einsetzt):
{% block component_product_box_image_link %}
<a href="{{ seoUrl('frontend.detail.page', { productId: id }) }}"
title="{{ name }}"
class="product-image-link is-{{ displayMode }}">
{% block component_product_box_image_link_inner %}
{% if cover.url and cover.isSpatialObject() == false %}
{% set attributes = {
class: 'product-image is-' ~ displayMode,
title: (cover.translated.alt ?: name)
} %}
{% if cover.getMediaType().getName() === 'VIDEO' %}
{% if config('core.listing.autoplayVideoInListing') %}
{% set attributes = attributes|merge({
autoplay: true,
loop: true
}) %}
{% endif %}
{% block component_product_box_video %}
{% sw_include '@Storefront/storefront/utilities/video.html.twig' with {
media: cover,
attributes: attributes
} %}
{% endblock %}
{% else %}
{% set attributes = attributes|merge({
alt: (cover.translated.alt ?: name),
loading: 'lazy'
}) %}
{% if displayMode == 'cover' or displayMode == 'contain' %}
{% set attributes = attributes|merge({ 'data-object-fit': displayMode }) %}
{% endif %}
{% block component_product_box_image_thumbnail %}
{% sw_thumbnails 'product-image-thumbnails' with {
media: cover,
sizes: sizes,
attributes: attributes
} %}
{% endblock %}
{% endif %}
{% else %}
{% block component_product_box_image_placeholder %}
<div class="product-image-placeholder">
{% sw_icon 'placeholder' style {
size: 'fluid'
} %}
</div>
{% endblock %}
{% endif %}
{% endblock %}
</a>
{% endblock %}
Das zeigt den Alt-Text bei Mouseover über Bilder von Produktempfehlungen/ähnliche Produkte und im Produkt-Listing. Hier würde nämlich auch normal der Bildername angezeigt.
Das passt so für mich, da ich vor Datenbankänderungen doch respekt habe und das so vermeiden kann.
Verbesserungsvorschläge und Ideen gerne willkommen.