Vor kurzem haben wir Euch gezeigt, wie Ihr das Listing individuell anpassen könnt.
Heute geht es um die Detailansicht der Artikel, die man ähnlich bearbeiten kann.
Die Detailansicht soll ein vollflächiges Bild enthalten und darunter den "In den Warenkorb" Button, sowie Preis und ein paar weitere Buttons.
Es ist hilfreich, wenn Ihr unsere Videoserie zu Smarty und Less Anpassungen gesehen habt.
Erstmal sieht die Standardansicht so aus.
So soll das ganze nachher aussehen.
Zuerst definieren wir unser eigenes Layout im Backend.
Dafür geht es in die Grundeinstellungen und auf die Storefront. Dort wählen wir Warenkorb / Artikeldetails und fügen unter "Verfügbare Templates Detailseite": unseres so hinzu:
:Standard;emzFullpic.tpl:emzFullpic;
Damit bleibt dem Standard erhalten und unseres kommt hinzu.
Die Template Datei emzFullpic.tpl müssen wir in diesem Verzeichnis anlegen:
"themes/Frontend/TestTheme/frontend/detail"
und leiten als erstes von der Originalen index.tpl ableiten:
{extends file='parent:frontend/detail/index.tpl'}
Dann können wir die Ansicht anpassen wie wir wollen. Nachdem der Block überschrieben wird, füge ich eine eigene div hinzu, um die LESS Anpassungen nur für unser Template zu nutzen. Hier der Code für unser Beispiel:
{extends file='parent:frontend/detail/index.tpl'}
{* Main content *}
{block name='frontend_index_content'}
<div class="emz--detail-fullpic">
<div class="content product--details" itemscope itemtype="http://schema.org/Product"{if !{config name=disableArticleNavigation}} data-product-navigation="{url module="widgets" controller="listing" action="productNavigation"}" data-category-id="{$sArticle.categoryID}" data-main-ordernumber="{$sArticle.mainVariantNumber}"{/if} data-ajax-wishlist="true" data-compare-ajax="true"{if $theme.ajaxVariantSwitch} data-ajax-variants-container="true"{/if}>
{* The configurator selection is checked at this early point
to use it in different included files in the detail template. *}
{block name='frontend_detail_index_configurator_settings'}
{* Variable for tracking active user variant selection *}
{$activeConfiguratorSelection = true}
{if $sArticle.sConfigurator && ($sArticle.sConfiguratorSettings.type == 1 || $sArticle.sConfiguratorSettings.type == 2)}
{* If user has no selection in this group set it to false *}
{foreach $sArticle.sConfigurator as $configuratorGroup}
{if !$configuratorGroup.selected_value}
{$activeConfiguratorSelection = false}
{/if}
{/foreach}
{/if}
{/block}
<div class="product--detail-upper block-group">
{* Product image *}
{block name='frontend_detail_index_image_container'}
<div class="product--image-container image-slider{if $sArticle.image && {config name=sUSEZOOMPLUS}} product--image-zoom{/if}"
{if $sArticle.image}
data-image-slider="true"
data-image-gallery="true"
data-maxZoom="{$theme.lightboxZoomFactor}"
data-thumbnails=".image--thumbnails"
{/if}>
{include file="frontend/detail/image.tpl"}
</div>
{/block}
{* "Buy now" box container *}
{block name='frontend_detail_index_buy_container'}
<div class="product--buybox block{if $sArticle.sConfigurator && $sArticle.sConfiguratorSettings.type==2} is--wide{/if}">
{block name="frontend_detail_rich_snippets_brand"}
<meta itemprop="brand" content="{$sArticle.supplierName|escape}"/>
{/block}
{block name="frontend_detail_rich_snippets_weight"}
{if $sArticle.weight}
<meta itemprop="weight" content="{$sArticle.weight} kg"/>
{/if}
{/block}
{block name="frontend_detail_rich_snippets_height"}
{if $sArticle.height}
<meta itemprop="height" content="{$sArticle.height} cm"/>
{/if}
{/block}
{block name="frontend_detail_rich_snippets_width"}
{if $sArticle.width}
<meta itemprop="width" content="{$sArticle.width} cm"/>
{/if}
{/block}
{block name="frontend_detail_rich_snippets_depth"}
{if $sArticle.length}
<meta itemprop="depth" content="{$sArticle.length} cm"/>
{/if}
{/block}
{block name="frontend_detail_rich_snippets_release_date"}
{if $sArticle.sReleasedate}
<meta itemprop="releaseDate" content="{$sArticle.sReleasedate}"/>
{/if}
{/block}
{block name='frontend_detail_buy_laststock'}
{if !$sArticle.isAvailable && ($sArticle.isSelectionSpecified || !$sArticle.sConfigurator)}
{include file="frontend/_includes/messages.tpl" type="error" content="{s name='DetailBuyInfoNotAvailable' namespace='frontend/detail/buy'}{/s}"}
{/if}
{/block}
{* Product email notification *}
{block name="frontend_detail_index_notification"}
{if $sArticle.notification && $sArticle.instock <= 0 && $ShowNotification}
{include file="frontend/plugins/notification/index.tpl"}
{/if}
{/block}
{* Product data *}
{block name='frontend_detail_index_buy_container_inner'}
<div itemprop="offers" itemscope itemtype="{if $sArticle.sBlockPrices}http://schema.org/AggregateOffer{else}http://schema.org/Offer{/if}" class="buybox--inner">
{block name='frontend_detail_index_data'}
{if $sArticle.sBlockPrices}
{$lowestPrice=false}
{$highestPrice=false}
{foreach $sArticle.sBlockPrices as $blockPrice}
{if $lowestPrice === false || $blockPrice.price < $lowestPrice}
{$lowestPrice=$blockPrice.price}
{/if}
{if $highestPrice === false || $blockPrice.price > $highestPrice}
{$highestPrice=$blockPrice.price}
{/if}
{/foreach}
<meta itemprop="lowPrice" content="{$lowestPrice}" />
<meta itemprop="highPrice" content="{$highestPrice}" />
<meta itemprop="offerCount" content="{$sArticle.sBlockPrices|count}" />
{else}
<meta itemprop="priceCurrency" content="{$Shop->getCurrency()->getCurrency()}"/>
{/if}
{include file="frontend/detail/data.tpl" sArticle=$sArticle sView=1}
{/block}
{block name='frontend_detail_index_after_data'}{/block}
{* Configurator drop down menu's *}
{block name="frontend_detail_index_configurator"}
<div class="product--configurator">
{if $sArticle.sConfigurator}
{if $sArticle.sConfiguratorSettings.type == 1}
{include file="frontend/detail/config_step.tpl"}
{elseif $sArticle.sConfiguratorSettings.type == 2}
{include file="frontend/detail/config_variant.tpl"}
{else}
{include file="frontend/detail/config_upprice.tpl"}
{/if}
{/if}
</div>
{/block}
{* Include buy button and quantity box *}
{block name="frontend_detail_index_buybox"}
{include file="frontend/detail/buy.tpl"}
{/block}
{* Product actions *}
{block name="frontend_detail_index_actions"}
<nav class="product--actions">
{include file="frontend/detail/actions.tpl"}
</nav>
{/block}
</div>
{/block}
{* Product - Base information *}
{block name='frontend_detail_index_buy_container_base_info'}
<ul class="product--base-info list--unstyled">
{* Product SKU *}
{block name='frontend_detail_data_ordernumber'}
<li class="base-info--entry entry--sku">
{* Product SKU - Label *}
{block name='frontend_detail_data_ordernumber_label'}
<strong class="entry--label">
{s name="DetailDataId" namespace="frontend/detail/data"}{/s}
</strong>
{/block}
{* Product SKU - Content *}
{block name='frontend_detail_data_ordernumber_content'}
<meta itemprop="productID" content="{$sArticle.articleDetailsID}"/>
<span class="entry--content" itemprop="sku">
{$sArticle.ordernumber}
</span>
{/block}
</li>
{/block}
{* Product attributes fields *}
{block name='frontend_detail_data_attributes'}
{* Product attribute 1 *}
{block name='frontend_detail_data_attributes_attr1'}
{if $sArticle.attr1}
<li class="base-info--entry entry-attribute">
<strong class="entry--label">
{s namespace="frontend/detail/index" name="DetailAttributeField1Label"}{/s}:
</strong>
<span class="entry--content">
{$sArticle.attr1|escape}
</span>
</li>
{/if}
{/block}
{* Product attribute 2 *}
{block name='frontend_detail_data_attributes_attr2'}
{if $sArticle.attr2}
<li class="base-info--entry entry-attribute">
<strong class="entry--label">
{s namespace="frontend/detail/index" name="DetailAttributeField2Label"}{/s}:
</strong>
<span class="entry--content">
{$sArticle.attr2|escape}
</span>
</li>
{/if}
{/block}
{/block}
</ul>
{/block}
</div>
{/block}
</div>
{* Product bundle hook point *}
{block name="frontend_detail_index_bundle"}{/block}
{block name="frontend_detail_index_detail"}
{* Tab navigation *}
{block name="frontend_detail_index_tabs"}
{include file="frontend/detail/tabs.tpl"}
{/block}
{/block}
{* Crossselling tab panel *}
{block name="frontend_detail_index_tabs_cross_selling"}
{$showAlsoViewed = {config name=similarViewedShow}}
{$showAlsoBought = {config name=alsoBoughtShow}}
<div class="tab-menu--cross-selling"{if $sArticle.relatedProductStreams} data-scrollable="true"{/if}>
{* Tab navigation *}
{block name="frontend_detail_index_tabs_navigation"}
<div class="tab--navigation">
{block name="frontend_detail_index_tabs_navigation_inner"}
{block name="frontend_detail_index_related_similiar_tabs"}
{* Tab navigation - Accessory products *}
{block name="frontend_detail_tabs_entry_related"}
{if $sArticle.sRelatedArticles && !$sArticle.crossbundlelook}
<a href="#content--related-products" title="{s namespace="frontend/detail/tabs" name='DetailTabsAccessories'}{/s}" class="tab--link">
{s namespace="frontend/detail/tabs" name='DetailTabsAccessories'}{/s}
<span class="product--rating-count-wrapper">
<span class="product--rating-count">{$sArticle.sRelatedArticles|@count}</span>
</span>
</a>
{/if}
{/block}
{* Similar products *}
{block name="frontend_detail_index_recommendation_tabs_entry_similar_products"}
{if count($sArticle.sSimilarArticles) > 0}
<a href="#content--similar-products" title="{s namespace="frontend/detail/index" name="DetailRecommendationSimilarLabel"}{/s}" class="tab--link">{s namespace="frontend/detail/index" name="DetailRecommendationSimilarLabel"}{/s}</a>
{/if}
{/block}
{/block}
{* Customer also bought *}
{block name="frontend_detail_index_tabs_entry_also_bought"}
{if $showAlsoBought}
<a href="#content--also-bought" title="{s namespace="frontend/detail/index" name="DetailRecommendationAlsoBoughtLabel"}{/s}" class="tab--link">{s namespace="frontend/detail/index" name="DetailRecommendationAlsoBoughtLabel"}{/s}</a>
{/if}
{/block}
{* Customer also viewed *}
{block name="frontend_detail_index_tabs_entry_also_viewed"}
{if $showAlsoViewed}
<a href="#content--customer-viewed" title="{s namespace="frontend/detail/index" name="DetailRecommendationAlsoViewedLabel"}{/s}" class="tab--link">{s namespace="frontend/detail/index" name="DetailRecommendationAlsoViewedLabel"}{/s}</a>
{/if}
{/block}
{* Related product streams *}
{block name="frontend_detail_index_tabs_entry_related_product_streams"}
{foreach $sArticle.relatedProductStreams as $key => $relatedProductStream}
<a href="#content--related-product-streams-{$key}" title="{$relatedProductStream.name}" class="tab--link">{$relatedProductStream.name}</a>
{/foreach}
{/block}
{/block}
</div>
{/block}
{* Tab content container *}
{block name="frontend_detail_index_outer_tabs"}
<div class="tab--container-list">
{block name="frontend_detail_index_inner_tabs"}
{block name='frontend_detail_index_before_tabs'}{/block}
{* Accessory articles *}
{block name="frontend_detail_index_tabs_related"}
{if $sArticle.sRelatedArticles && !$sArticle.crossbundlelook}
<div class="tab--container">
{block name="frontend_detail_index_tabs_related_inner"}
<div class="tab--header">
<a href="#" class="tab--title" title="{s namespace="frontend/detail/tabs" name='DetailTabsAccessories'}{/s}">
{s namespace="frontend/detail/tabs" name='DetailTabsAccessories'}{/s}
<span class="product--rating-count-wrapper">
<span class="product--rating-count">{$sArticle.sRelatedArticles|@count}</span>
</span>
</a>
</div>
<div class="tab--content content--related">{include file="frontend/detail/tabs/related.tpl"}</div>
{/block}
</div>
{/if}
{/block}
{* Similar products slider *}
{if $sArticle.sSimilarArticles}
{block name="frontend_detail_index_tabs_similar"}
<div class="tab--container">
{block name="frontend_detail_index_tabs_similar_inner"}
<div class="tab--header">
<a href="#" class="tab--title" title="{s namespace="frontend/detail/index" name="DetailRecommendationSimilarLabel"}{/s}">{s namespace="frontend/detail/index" name="DetailRecommendationSimilarLabel"}{/s}</a>
</div>
<div class="tab--content content--similar">{include file='frontend/detail/tabs/similar.tpl'}</div>
{/block}
</div>
{/block}
{/if}
{* "Customers bought also" slider *}
{if $showAlsoBought}
{block name="frontend_detail_index_tabs_also_bought"}
<div class="tab--container">
{block name="frontend_detail_index_tabs_also_bought_inner"}
<div class="tab--header">
<a href="#" class="tab--title" title="{s namespace="frontend/detail/index" name='DetailRecommendationAlsoBoughtLabel'}{/s}">{s namespace="frontend/detail/index" name='DetailRecommendationAlsoBoughtLabel'}{/s}</a>
</div>
<div class="tab--content content--also-bought">{action module=widgets controller=recommendation action=bought articleId=$sArticle.articleID}</div>
{/block}
</div>
{/block}
{/if}
{* "Customers similar viewed" slider *}
{if $showAlsoViewed}
{block name="frontend_detail_index_tabs_also_viewed"}
<div class="tab--container">
{block name="frontend_detail_index_tabs_also_viewed_inner"}
<div class="tab--header">
<a href="#" class="tab--title" title="{s namespace="frontend/detail/index" name='DetailRecommendationAlsoViewedLabel'}{/s}">{s namespace="frontend/detail/index" name='DetailRecommendationAlsoViewedLabel'}{/s}</a>
</div>
<div class="tab--content content--also-viewed">{action module=widgets controller=recommendation action=viewed articleId=$sArticle.articleID}</div>
{/block}
</div>
{/block}
{/if}
{* Related product streams *}
{foreach $sArticle.relatedProductStreams as $key => $relatedProductStream}
{block name="frontend_detail_index_tabs_related_product_streams"}
<div class="tab--container" data-tab-id="productStreamSliderId-{$relatedProductStream.id}">
{block name="frontend_detail_index_tabs_related_product_streams_inner"}
<div class="tab--header">
<a href="#" class="tab--title" title="{$relatedProductStream.name}">{$relatedProductStream.name}</a>
</div>
<div class="tab--content content--related-product-streams-{$key}">
{include file='frontend/detail/tabs/product_streams.tpl'}
</div>
{/block}
</div>
{/block}
{/foreach}
{block name='frontend_detail_index_after_tabs'}{/block}
{/block}
</div>
{/block}
</div>
{/block}
</div>
</div>
{/block}
Für unser Beispiel wird auch noch die "image.tpl" bearbeitet.
Hier sieht man eine wichtige Zeile, damit die Änderungen nur für unser erstelltes Template gemacht werden.
{if $sArticle.template == "emzFullpic.tpl"}
Das ist die ganze Datei "image.tpl" für unser Beispiel.
{extends file='parent:frontend/detail/image.tpl'}
{block name="frontend_detail_image"}
{if $sArticle.template == "emzFullpic.tpl"}
{* Product image - Gallery *}
{block name="frontend_detail_image_box"}
{strip}
<div class="image-slider--container{if !$sArticle.image} no--image{/if}{if !count($sArticle.images)} no--thumbnails{/if}">
<div class="image-slider--slide">
{block name='frontend_detail_image_default_image_slider_item'}
<div class="image--box image-slider--item">
{block name='frontend_detail_image_default_image_element'}
{$alt = $sArticle.articleName|escape}
{if $sArticle.image.description}
{$alt = $sArticle.image.description|escape}
{/if}
<span class="image--element"
{if $sArticle.image}
data-img-large="{$sArticle.image.thumbnails[2].source}"
data-img-small="{$sArticle.image.thumbnails[0].source}"
data-img-original="{$sArticle.image.source}"
{/if}
data-alt="{$alt}">
{block name='frontend_detail_image_default_image_media'}
<span class="image--media">
{if isset($sArticle.image.thumbnails)}
{block name='frontend_detail_image_default_picture_element'}
<img srcset="{$sArticle.image.thumbnails[1].sourceSet}" alt="{$alt}" itemprop="image" />
{/block}
{else}
{block name='frontend_detail_image_fallback'}
<img src="{link file='frontend/_public/src/img/no-picture.jpg'}" alt="{$alt}" itemprop="image" />
{/block}
{/if}
</span>
{/block}
</span>
{/block}
</div>
{/block}
{foreach $sArticle.images as $image}
{block name='frontend_detail_images_image_slider_item'}
<div class="image--box image-slider--item">
{block name='frontend_detail_images_image_element'}
{$alt = $sArticle.articleName|escape}
{if $image.description}
{$alt = $image.description|escape}
{/if}
<span class="image--element"
data-img-large="{$image.thumbnails[2].source}"
data-img-small="{$image.thumbnails[0].source}"
data-img-original="{$image.source}"
data-alt="{$alt}">
{block name='frontend_detail_images_image_media'}
<span class="image--media">
{if isset($image.thumbnails)}
{block name='frontend_detail_images_picture_element'}
<img srcset="{$image.thumbnails[1].sourceSet}" alt="{$alt}" itemprop="image" />
{/block}
{else}
{block name='frontend_detail_images_fallback'}
<img src="{link file='frontend/_public/src/img/no-picture.jpg'}" alt="{$alt}" itemprop="image" />
{/block}
{/if}
</span>
{/block}
</span>
{/block}
</div>
{/block}
{/foreach}
</div>
</div>
{/strip}
{/block}
{* Product image - Dot navigation *}
{block name='frontend_detail_image_box_dots'}
{if $sArticle.images}
<div class="image--dots image-slider--dots panel--dot-nav">
<a href="#" class="dot--link"> </a>
{foreach $sArticle.images as $image}
<a href="#" class="dot--link"> </a>
{/foreach}
</div>
{/if}
{/block}
{* Product image - Thumbnails *}
{block name='frontend_detail_image_thumbs'}
{include file="frontend/detail/images.tpl"}
{/block}
{else}
{$smarty.block.parent}
{/if}
{/block}
Nun kommen wir zu den LESS Anpassungen, um alles neu zu gestalten.
Wie man diese Datei einbindet, sollte durch das oben genannte Tutorial klar sein.
.emz--detail-fullpic{
.product--detail-upper.block-group{
text-align: -webkit-center;
.product--image-container.image-slider.product--image-zoom{
width: 100%;
margin:4%;
margin-left: 0;
.js--img-zoom--flyout{
display: none !important;
}
.js--img-zoom--lens{
display: none !important;
}
.image--thumbnails.image-slider--thumbnails{
width: 100%;
height: 70px;
margin: 10px;
text-align: -webkit-center;
.image-slider--thumbnails-slide{
right: 0px;
height: 70px;
.thumbnail--link{
margin-right: 20px;
margin-bottom: 0;
display: inline-block;
}
}
}
.image-slider--slide{
.image--element{
span img{
height: 100%;
}
}
}
.image--box.image-slider--item{
//display: none;
}
.image--dots.image-slider--dots.panel--dot-nav{
padding: 0;
margin-top: 10px;
}
.image-slider--container{
width: 100%;
}
}
.product--buybox.block{
float: inherit;
.product--price.price--unit{
display: none;
}
.product--tax{
display: none;
}
.product--delivery{
display: none;
}
.product--actions{
text-align: -webkit-center;
.action--form{
float:none;
display: inline-block;
}
}
.base-info--entry{
text-align: -webkit-center;
&.entry--sku{
left: -5%;
position: relative;
}
}
}
}
}
Das Ganze wird einem Artikel zugewiesen, indem man den Artikel bearbeitet und unter Stammdaten bei Template unser eigenes Template auswählt.
Zu guter Letzt Artikel speichern, wie so oft Cache leeren, Theme kompilieren und schon können wir unser neues Design anschauen.
Wenn Ihr eigene Designs erstellt, schickt uns gerne ein Screenshot davon!
Viel Spaß beim kreativen Entfalten.
Unsere Standorte
Zentrale
Technologiepark 23
33100 Paderborn
Leipzig
Bernhardstraße 34
04315 Leipzig
Kontakt
E-Mail: support@8mylez.com
Telefon: +49 (0) 5251 284 710
Shopware Dienstleistungen
Über 8mylez
✓ 38 Mitarbeiter
✓ Shopware Gold Partner
✓ 40.000+ Plugin Downloads
✓ 160+ betreute Shops
✓ Full-Service Shopware Agentur
✓ 70 Shopware Videos auf Youtube
✓ Alle Shopware Zertifizierungen
Social
Götz
es fehlt das
div class="emz--detail-fullpic"
im Quickview
Götz
Bei vorhandenem Storytelling Plugin und genutztem Quickview überschreibt die eingebundene image.tpl auch das Quickview Fensters.
Quickview lädt nicht die emzFullpic.tpl sondern seine eigene index.tpl (/custom/plugins/SwagEmotionAdvanced/Resources/views/widgets/swag_emotion_advanced/index.tpl) included aber diese image.tpl und die Abfrage {if $sArticle.template == "emzFullpic.tpl"} greift.
Somit mischt sich da was...
Nicht weiter schlimm, kann aber less Probleme machen,
da die Anpassungen nicht greifen und das Standard Atikeltemplate mit
Es fehlt das im Quickview,
um das zu umgehen, einfach die obige image.tpl als neue Datei z.B. emzImage.tpl speichern und in der emzFullpic.tpl den include anpassen.
Tolle Lernhilfe! Weiter so. Danke!
Viele Grüße
Götz
Gerriet
Gibt es die Möglichkeit, dass Bilder, die einer Variante zugewiesen wurden, auch unterhalb des Artikel angezeigt werden?
Ähnlich wie Bilder, welche nicht zugeordnet wurden?
Viele Grüße Gerriet
Ewald Gering
das kann auch gemacht werden. Dazu einfach die Blöcke mit in die 'index.tpl' und dann noch mit Less richtig platzieren.
Viele Grüße
Ewald
Sacha
Hilfe wäre suuuuper :-)
So bei mir mit Template-Datei:
So ohne Template-Datei:
Kunden haben sich ebenfalls angesehen
Ewald Gering
das Problem lag an den Textbausteinen.
Da wir hier neue angelegt haben und kein Inhalt eingefügt haben.
Ich habe den Code aktualisiert und auf die Originalen Textbausteine verwiesen.
Wenn du eigene Texte verwenden möchtest, kannst du natürlich die namepsaces wieder ändern.
Viele Grüße,
Ewald
andreas
Super macht weiter so!!!!
Ein Danke an euch!
Andreas
Ewald Gering
vielen Dank für das nette Feedback.
Wir versuchen immer neue coole Sachen mit euch teilen zu können :)
Viele Grüße,
Ewald
Was denkst du?