Attributes als Attribute-Set im Webshop darstellen

View this post in english at http://web-design.sayyor.com (short translation)

In Magento lassen sich, bedingt durch das EAV-Datenmodell, quasi beliebig viele Felder bzw. Attribute zu einem Produkt hinzufügen. Die neuen Attribute lassen sich zusätzlich noch im Administrationsbereich gruppiert darstellen - das schafft beim Pflegen deutlich mehr Übersicht aber warum diese Gruppierung nicht auch im Webshop darstellen? Wie das geht schauen wir uns heute einmal näher an.

Update: Die Gruppenansicht von Attributen ist nun per MagentoConnect direkt zum installieren verfügbar.

Vorab ein paar Grundlagen zum Anlegen von Attributen. Einfache Attribute lassen sich über Catalog/ Attributes/ Manage Attributes erstellen. Die einzelnen Attribute können dabei zu Attribute Sets zusammengefasst werden. Das Attribute-Set können wir uns wie einen Baum vorstellen - es gibt viele Äste, die Gruppen, die unsere einzelnen Attribute, die Blätter, tragen. Ein Baum hat dabei natürlich mehr Äste, Zweige und Blätter als unsere einfache Gruppierung in Magento. Im Admin sieht das ganze in der Regel wie folgt aus:

Cameras-Manage-Attribute-Sets-Attributes-Catalog-Magento-Admin_1272314071484

Nun, merken wir uns einmal die Attribute "megapixels", "dimensions", "model" und "manufactor". Für unser Produkt sollen diese Attribute einzeln und tabellarisch auf der Webseite dargestellt werden. Dazu müssen sie mit Hilfe von Catalog/ Attributes / Manage Attributes bearbeitet bzw. geprüft werden. Wichtig ist das überall der Wert von "Visible on Product View Page on Front-end" auf "Yes" steht. Diese Dropdown schaltet die Anzeige im Frontend für das jeweilige Attribute frei. Sind alle Attribute angepasst stellt Magento in das Basis-Installation alle Attribute wie folgt dar:

So lange nur ein paar Attribute angezeigt werden ist die Übersicht gewährleistet. Wollen wir jedoch eine größere Menge an Informationen zum Produkt auf diesem Wege anzeigen geht sie schnell verloren. Hier wäre es sinnvoll die Darstellung noch einmal in "General" und "Camera Attributes" zu gliedern. Magento gibt die Möglichkeit von Haus aus jedoch nicht her, deswegen erstellen wir unseren eigenen Block.

Eigenen Block erstellen

Unser Ziel ist es nicht nur die Attribute über den Block darzustellen sondern zusätzlich noch das Attribute-Set. Folgender Code hilft uns dabei weiter:

Datei: code/local/Mage/Catalog/Block/Product/View/Attributesgroups.php

<?php
class Mage_Catalog_Block_Product_View_Attributesgroups extends Mage_Core_Block_Template
{
    protected $_product = null;

    function getProduct()
    {
        if (!$this->_product) {
            $this->_product = Mage::registry('product');
        }
        return $this->_product;
    }

    public function getAdditionalData(array $excludeAttr = array())
    {
        $data = array();

        $product = $this->getProduct();
        $attributes = $product->getAttributes();
        foreach ($attributes as $attribute) {

            if ($attribute->getIsVisibleOnFront() && !in_array($attribute->getAttributeCode(), $excludeAttr)) {

                $value = $attribute->getFrontend()->getValue($product);

                // TODO this is temporary skipping eco taxes
                if (is_string($value)) {
                    if (strlen($value) && $product->hasData($attribute->getAttributeCode())) {
                        if ($attribute->getFrontendInput() == 'price') {
                            $value = Mage::app()->getStore()->convertPrice($value,true);
                        } elseif (!$attribute->getIsHtmlAllowedOnFront()) {
                            $value = $this->htmlEscape($value);
                        }

                        $group = 0;
                        if( $tmp = $attribute->getData('attribute_group_id') ) {
                        	$group = $tmp;
                        }

                        $data[$group]['items'][ $attribute->getAttributeCode()] = array(
                           'label' => $attribute->getFrontend()->getLabel(),
                           'value' => $value,
                           'code'  => $attribute->getAttributeCode()
                        );

                        $data[$group]['attrid'] = $attribute->getId();

                    }
                }
            }
        }

        // Noch Titel lesen
        foreach( $data AS $groupId => &$group ) {
        	$groupModel = Mage::getModel('eav/entity_attribute_group')->load( $groupId );
        	$group['title'] = $groupModel->getAttributeGroupName();
        }

        return $data;
    }
}

Im oberen Beispiel wurde der Magento-Kern Code benutzt und in einer eigenständigen Class um die Gruppendarstellung erweitert.

Ein kleiner Tipp am Rande: Die Magento-Controller sorgen dafür das in Mage::registry('product') immer das Produkt, das in dem Moment dargestellt werden soll, hinterlegt ist. So ist es jederzeit möglich Produkt-Darstellung-Blöcke auch in anderen Controller zu verwenden. Es muss durch den Controller nur gewährleistet sein das die Mage-Registry ein Produkt enthält.

Template vorbereiten

Nun haben wir einen Block der die Funktion beinhaltet alle Attribute gegliedert nach Gruppen zu zurückzugeben. Was wäre naheliegender als diese Funktion in einem Template aufzurufen und deren Informationen darzustellen?

Dabei: app/design/frontend/default/default/template/catalog/product/view/attributesgroups.phtml

<?php
    $_helper = $this->helper('catalog/output');
    $_product = $this->getProduct()
?>
<?php if($_additionalgroup = $this->getAdditionalData()): ?>
<div class="box-collateral box-additional">
    <h2><?php echo $this->__('Additional Information') ?></h2>

	<?php $i=0; foreach ($_additionalgroup as $_additional): $i++; ?>
		<h3><?php echo $this->__( $_additional['title'] )?></h3>
		<table class="data-table" id="product-attribute-specs-table-<?php echo $i?>">
		    <col width="25%" />
		    <col />
		    <tbody>
		    <?php foreach ($_additional['items'] as $_data): ?>
		        <tr>
		            <th class="label"><?php echo $this->htmlEscape($this->__($_data['label'])) ?></th>
		            <td class="data"><?php echo $_helper->productAttribute($_product, $_data['value'], $_data['code']) ?></td>
		        </tr>
		    <?php endforeach; ?>
		    </tbody>
		</table>
	    <script type="text/javascript">decorateTable('product-attribute-specs-table-<?php echo $i?>')</script>
	<?php endforeach; ?>

</div>
<?php endif;?>

Hier fügen wir nun zwischen jeder Gruppe eine neue H3-Überschrift ein. Damit die Möglichkeit der Übersetzung der Überschrift der Sets bei mehrsprachigen Shops bestehen bleibt wird diese durch den Aufruf von echo $this->__(...) ausgeben.

Layout aktualisieren

Letztlich müssen wir unseren Layout-XML noch sagen das wir unsere Attribute mit einem eigenen Block und einem anderen Template darstellen möchten. Dazu suchen wir in der catalog.xml die Zeile

<block type="catalog/product_view_attributes" name="product.attributes" as="additional" template="catalog/product/view/attributes.phtml"/>

und ersetzen sie durch

<block type="catalog/product_view_attributesgroups" name="product.attributes" as="additional" template="catalog/product/view/attributesgroups.phtml"/>

Schon wird anstelle der alten Produktdarstellung unsere eigene genutzt. Das Ergebnis sieht dann im Demo-Shop beim gleichen Produkt wie folgt aus:

Canon-Digital-Rebel-XT-8MP-Digital-SLR-Camera-with-EF-S-18-55mm-f3.5-5.6-Lens-Black_1272316461177-500x156


Ein Beitrag von Tobias Vogt
Tobias's avatar

Tobias Vogt arbeitet seit 2008 mit Magento und ist seit 2011 durch Magento zertifizierter Entwickler. Seit 2016 ist er Mitgründer und CTO bei der connect-io GmbH, einer Magento-Agentur mit Sitz im idyllischen Paderborn-Salzkotten. Er gehört zum Gründer-Team der Webguys und ist seit November 2011 Bachelor of Science (Wirtschaftsinformatik). Sie erreichen Ihn per E-Mail unter tobi@webguys.de.

Alle Beiträge von Tobias

Kommentare
CflpmLaesp am

Exactly why might have been whom? It truly most likely this rose bush wasn't mentioned as previous method because it doesn't evaporate detail Lang appropriately all that is needed so that it is considered. I hope that the majority of answers manufactured in Vringo's USPTO reaction to the 420 re test will be applied in its 664 response and i also urge day traders to see clearly. A practical USPTO examiner will see the patents not really identical, But nevertheless, long afterwards yahoo and the search engines need to assess if it must keep expecting that may JJ and a fresh court(The actual eventually case) Continues to discipline them to stoning involving all of marshmallows, nike air max 90 It looks mobile or portable wow is a merged handcase. You'll find splendid mobiles adventure at hand however is there in a continuous swamp together with waste. It's hard to find a very good championships, Perhaps even most excellent post brands end up being a avoided for the people seeking and unending more are let go a week, nike air max one Skip forward the actual legal struggle for you to the billion dollars rages on. A stock price of Vringo lags and / or merchants are challenged to get a reason to extra deal in. A $1 million published milliseconds judgment does nothing to re plan the fun yet fervor the store offers relished during the past. nike air max homme The msrp was fantastic try out achievement a vintage template however. As they situation 17 students not really exceptional, Yet unfortunately doable plus well known. Using summary i noticed that from the starting point all the people ruled out just about every person while having already present slumber setbacks. nike air max one I cannot learn from extremely dramas, However for me, Different drama/movie developing being renowned. Plus its not made to be grimy because love-making audio archival footage(What type a portion of everyone have been discussion are pleased is just, Shameless, Value,) Something like that. I additionally wouldn't browse the manga in front of(Too been told by it until finally eventually months within the the moment the theatre only agreed to be out doors) Rather anywhere since endures, The predicament may well most effective be preaching about those handling a bit criminal activity or normal facts ordering conspiracy as well as may participate in like an old, nike air max one

you may also like: http://canberra.climatexchange.org.au/climate-change-skills-training-forum/trackback http://www.boutiquealaval.com/member.php?action=profile&uid=13338 http://www.sarrasia.com/?q=node/add

Giulio am

Hi, I need this on my site. It is make on Magento 1.7, I followed all the step but not show the label attribute group.

Please any suggestion?

Giulio

Adarsh am

Hi Thanks for great solution on this.

Getting error on system.log file: Undefined index: title in ......../attributesgroups.phtml Undefined index: items in ......../attributesgroups.phtml

in phtml file I have echo $this->__( $_additional['title'] );

Please suggest.

Kind Regards Adarsh

DJ am

Hi guys,

Needed this! I just made a few changes to make it work with Magento 1.8. Not a super experienced code-writer so if you see any flaws please let me know.

For attributesgroups.phtml I used this: helper('catalog/output'); $_product = $this->getProduct() ?> getAdditionalData()): ?>

    __( $_additional['title'] )?>

                escapeHtml($this->__($_data['label'])) ?>
                productAttribute($_product, $_data['value'], $_data['code']) ?>

    decorateTable('product-attribute-specs-table-')

For attributesgroups.php I used this:

_product) { $this->_product = Mage::registry('product'); } return $this->_product; }

public function getAdditionalData(array $excludeAttr = array())
{
    $data = array();

    $product = $this->getProduct();
    $attributes = $product->getAttributes();
    foreach ($attributes as $attribute) {

        if ($attribute->getIsVisibleOnFront() && !in_array($attribute->getAttributeCode(), $excludeAttr)) {

            $value = $attribute->getFrontend()->getValue($product);

// zelf hier gezet if (!$product->hasData($attribute->getAttributeCode())) { $value = Mage::helper('catalog')->('N/A'); } elseif ((string)$value == '') { $value = Mage::helper('catalog')->('No'); } elseif ($attribute->getFrontendInput() == 'price' && is_string($value)) { $value = Mage::app()->getStore()->convertPrice($value, true); }

      $group = 0;
      if( $tmp = $attribute->getData('attribute_group_id') ) {
      $group = $tmp;
      }

            if (is_string($value) && strlen($value)) {
            $data[$group]['items'][$attribute->getAttributeCode()] = array(
                    'label' => $attribute->getStoreLabel(),
                    'value' => $value,
                    'code'  => $attribute->getAttributeCode()
                );
    $data[$group]['attrid'] = $attribute->getId();

// einde eigen content

            }
        }
    }

    // Noch Titel lesen
    foreach( $data AS $groupId => &$group ) {
        $groupModel = Mage::getModel('eav/entity_attribute_group')->load( $groupId );
        $group['title'] = $groupModel->getAttributeGroupName();
    }

    return $data;
}

}

Randy am

Hallo, kann es denn sein, dass das nicht mehr mit der 1.8 CE funktioniert? Ich bekomm es trotz genauer Einhaltung nicht dazu, das es läuft. Gruß

Lucrezia am

Super Extension! Vielen Dank

Gibt es eine Möglichkeit die GroupID zu beschränken? Also, dass nur die GroupID 25 (Bsp) ausgegeben wird. Habe schon ein paar Sachen ausprobiert aber als Codepfuscher und nicht Programmierer stehe ich ziemlich auf dem Schlauch.

Danke schon mal ... LG

Maxx am

Great tutorial, but what are the changes to make for working in 1.7 please?

Thanks in advance !

Andy am

Hi

This extension / code looks great but as a newbie to Magento and NOT using the default / core theme can anyone help me get this working on a different theme?

I have looked in the package file and can see lots of references to /frontend/base/default/layout but I want this to be /frontend/MyTheme/default/layout

Thanks in advance!

Stefan am

Hi Tobias, danke für den hilfreichen Artikel. Eine Frage hätte ich aber noch: Attributsets werden soweit ich das verstehe zum zusammenfassen von Attributen für eine bestimmte Artikelgruppe verwendet. Wenn ich aber z.B. ein Attributset für ein Auto mache, dann habe ich bei einem Auto mit Benzinmotor beispielsweise eine Zündkerze die beim Diesel nicht vorhanden ist. Oder nehmen wir einen Elektroherd, ein Gasherd hat z.B. keine Wattzahl - ein Elektroherd schon.

In einer Artikelübersicht sieht es daher immer etwas unschön aus, wenn dort Artikelfelder gelistet werden die einfach nicht zutreffen können.

Wahrscheinlich müsste man hier im Template abfragen welche Felder gefüllt sind und diese dann eventuell einfach ausblenden. Oder gibt es da einen klügeren Weg?

Grüße

Stefan

Tamayo am

Working on 1.7.

Change

To

Great tutorial. Just what I was looking for.

Ward am

I followed the tutorial, but it is not working on Magento 1.7.0.2

Anybody knows what to change to get it working?

Willing to pay.

P.s. Nice tutorial / website

Philipp am

Hi,

was müsste ich denn anpassen, damit es auch in 1.7 funktioniert?

Gruß Philipp

John am

Tell me how this can be done in version 1.6? I have yet to not succeed.

How to display Attribute Group Name on Product page? » What web developer needs? am

[...] for the same thing. First, I’m using Magento 1.5.0. Second, I found the answer in German here, with an extension already created, but the installation failed. So, I added [...]

ogg am

First, thanks a ton on this clean tutorial. Second, is there a way to fix special symbol problem? to be more specific, after installing your code i have "&" instead of "&" everything else is gr8 :)

Bruno am

Hello Tobias,

Thanks for the extention! I've installed it manualy on 1.5.0.1 and it works just the way I want!

For the error:

Fatal error: Call to a member function addToChildGroup() on a non-object in htdocs\magento\app\code\core\Mage\Core\Block\Abstract.php on line 649

just remove \ on the line for catalog.xml:

...template="catalog/product/view/attributesgroups.phtml"/>

should be

...template="catalog/product/view/attributesgroups.phtml">

Thanks and have a nice day!

Bruno

BTW I read German, but writing and speaking is a bit rusty after 25 years ...

Tobias Vogt am

Hi Martin,

ja bei Layout-Probleme sollte das kein Problem sein so. Aber immer dran denken den Cache aus zu lassen :)

Tobi

Martin am

Hallo Cache ist deaktiviert.

Kann ich die installierten Extensions einfach nach und nach deaktivieren und testen ob es geht?

Oder klappt das so nicht.

Viele Grüße und besten Dank!

Tobias Vogt am

Hi Martin,

hast du deinen Cache deaktiviert als du die Extension getestet hast? Klingt so als würden sich dort zwei Extension eventuell in die Quere kommen..

Tobi

Martin am

Hallo wir bekommen wie oben bereit schon erwähnt folgende Meldung:

Fatal error: Call to a member function addToChildGroup() on a non-object in htdocs\magento\app\code\core\Mage\Core\Block\Abstract.php on line 649

Trotz des BackUps der Änderung an die XML Dateien, die wir bis dato vorgenommen haben, erscheint die Fehlermeldung weiterhin.

Aber nur wenn wir in die Produktdetails gehen. Trotz der Deinstallation der Extension erscheint die Fehlermeldung immer noch.

Vielen Dank und viele Grüße

Dein Kommentar