Ist es gut, eine getModel-Klasse für Phtml-Vorlagen zu instanziieren?

14

Dies ist eine Frage zu guten Programmierpraktiken in Magento.

Ich muss (in der Kategorie Produktliste) das Produkt mit den zugehörigen Produkten in Miniaturansichten anzeigen. Also habe ich so mypackage/mytheme/template/catalog/product/list.phtmletwas bearbeitet

<?php 
    $related=$_product->getRelatedProductIds();
    if(count($related)>0){
        echo '<div class="a'.$ap.'"></div>';
        echo '<div class="li_p"><ul>';
        foreach($related as $rela){
            $rela_nom=Mage::getModel('catalog/product')->load($rela);
            echo '<li><a href="'.$rela_nom->getProductUrl().'"> <img src="'.$this->helper('catalog/image')->init($rela_nom, 'small_image')->resize(20).'" width="20" height="20"> </a><li>';
        }
        echo '</ul></div>';
    }
?>

Und es funktioniert sehr gut.

Aber meine Frage ist: Ist dies richtig, um eine Modellklasse für die HTML-Dateien zu instanziieren?

Wenn nicht, wie lässt sich diese Funktionalität am besten erreichen? Ich meine, welche Datei ist besser zu bearbeiten oder welche Klasse ist besser hinzuzufügen, wo? Ein Helfer?

Können Sie mir ein kleines Beispiel geben oder einen Blick darauf werfen, welche Dateien besser zu bearbeiten sind?

user604
quelle

Antworten:

10

Ich möchte Sonassis Antwort nicht zustimmen :)

Das Initiieren eines Modells in der Vorlage ist eine schlechte Praxis. Manchmal wird es gebraucht und manchmal mache ich es auch. Aber wenn es möglich ist, sollten Sie verhindern, dass Code zu Ihren pHTML-Dateien hinzugefügt wird und nur echobestimmte Dinge.

Es ist die Trennung von Sorgen . Verwechsle nicht HTML und Code. Dies sollte in der Klasse Block sein.

Fabian Blechschmidt
quelle
3
Ich stimme auch Ihrer Uneinigkeit zu :) Aber das Laden eines einzelnen Modells außerhalb einer Schleife ist nicht das Ende der Welt. Andernfalls wird es zu einer Abstraktion ohne Ende, bei der zusätzliche Klassen hinzugefügt werden, die lediglich dazu dienen, eine einzelne Codezeile von der Ansicht zu trennen. Es trägt nur dazu bei, den Overhead umzuschreiben, ganz zu schweigen von der Wartung.
Ben Lessani - Sonassi
Sie haben zu mich Zeit, wenn Sie alle meine Rechtschreibfehler korrigieren möchten, danke dafür :-)
Fabian Blechschmidt
Übrigens, du hast recht, Sonassi :-) Es ist nur etwas, mit dem wir vorsichtig sein sollten. Ich habe SQL-Abfragen in HTML-Dateien gesehen ... NEIN NEIN :-)
Fabian Blechschmidt
4

Es ist nichts falsch daran, ein Modell in eine phtmlDatei zu laden . Aber es hängt davon ab, warum Sie es tun.

Wenn Sie das gesamte Modell und alle damit verbundenen Daten benötigen, können Sie auch das gesamte Modell laden.

Wenn Sie jedoch nur die Produkt-URL (aus Ihrem Beispiel) benötigen, können Sie einfach die richtige Sammlung laden

$_product->getRelatedProductCollection();

Wiederholen Sie dies nach Bedarf

<?php $_relatedCollection = $_product->getRelatedProductCollection(); ?>
<?php foreach ($_relatedCollection as $_item): ?>
<li>
  <a href="<?php echo $_item->getProductUrl(); ?>">
    <img src="<?php echo $this->helper('catalog/image')->init($_item, 'small_image')->resize(20); ?>" width="20" height="20">
  </a>
<li>
<?php endforeach; ?>
Ben Lessani - Sonassi
quelle
3

Willst du meine 5 Cent hier setzen. Wir sollten Architekturprinzipien respektieren, die in Magento verwendet werden. Das wichtigste in Magento verwendete Architekturmuster ist MVC. Im Falle von Magento enthält "View" mehrere Dinge (Block, Vorlage, Layout). Es wurden Blöcke erstellt, um die Datenvorbereitungslogik von der Vorlage in eine andere Klasse zu verschieben, damit die Vorlagen für Frontend-Entwickler übersichtlicher und lesbarer werden. Hier möchte ich Fabian zustimmen.

Was Sonassis Bedenken in Bezug auf zu viele nicht benötigte Klassen betrifft, schlage ich vor, mich auf Push-basierte MVC zu freuen. In diesem Fall betrachten wir den Controller als Kommandeur, der definiert, welchen Block und welche Daten er haben soll. Die Aktion in der Steuerung kann den erforderlichen Code enthalten, um Daten zu laden und vor dem Rendern (über Magic Setter) zu blockieren.

Dmitriy Vasilenko
quelle
3

Ich stimme Fabian Blechschmidt zu, dass es sich um eine schlechte Praxis handelt und Sie die Trennung von Bedenken respektieren sollten.

So fügen Sie einen konstruktiven Vorschlag hinzu:

Dafür sind die Block-Klassen gedacht. In Ihrem Fall müssten Sie neu schreiben Mage_Catalog_Block_Product_List , um die gewünschte Funktionalität hinzuzufügen:

public function hasRelatedProducts()
{
    return count($this->getRelatedProductIds()) > 0;
}
public function getRelatedProducts()
{
    $products = array();
    foreach ($this->getRelatedProductIds() as $id) {
        $products[] = Mage::getModel('catalog/product')->load($id);
    }
    return $products;
}

Es sollte offensichtlich sein, wie diese Methoden in der Vorlage verwendet werden.

Hinweis: Rewrite bedeutet nicht, die Kerndatei zu bearbeiten. Befolgen Sie das Tutorial zum Anpassen, wenn Sie nicht wissen, wie Sie einen Block umschreiben können.

Fabian Schmengler
quelle