Czy warto tworzyć instancję klasy getModel w szablonach phtml?

14

To pytanie dotyczy dobrych praktyk programistycznych w Magento.

Muszę pokazać (w liście produktów kategorii) produkt wraz z powiązanymi produktami w miniaturach. Więc edytowałem mypackage/mytheme/template/catalog/product/list.phtmlcoś takiego

<?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>';
    }
?>

I działa bardzo dobrze.

Ale moje pytanie brzmi: czy poprawne jest tworzenie instancji klasy modelu w plikach phtml?

Jeśli nie, jaki byłby najlepszy sposób na osiągnięcie tej funkcjonalności? Mam na myśli, który plik lepiej edytować lub jaką klasę lepiej dodać, gdzie? Pomocnik?

Czy możesz podać mały przykład lub rzucić okiem, które pliki lepiej edytować.

użytkownik604
źródło

Odpowiedzi:

10

Chcę się nie zgodzić z odpowiedzią Sonassi :)

Inicjowanie modelu w szablonie to zła praktyka. Czasami jest to potrzebne, a czasem też to robię. Ale jeśli jest to możliwe, powinieneś zapobiegać dodawaniu kodu do plików pHTML i tylko echopodanych rzeczy.

To oddzielenie obaw . Nie mieszaj HTML-a i kodowania. To powinno być w klasie Block.

Fabian Blechschmidt
źródło
3
Zgadzam się również z twoją niezgodą :) Ale załadowanie jednego modelu poza pętlę to nie koniec świata. W przeciwnym razie staje się to przypadkiem nieskończoności abstrakcji - dodawania dodatkowych klas istniejących jedynie w celu oddzielenia jednego wiersza kodu od widoku. Dodaje to tylko do przepisywania kosztów ogólnych, nie wspominając już o konserwacji.
Ben Lessani - Sonassi
Masz zbyt wiele czasu, jeśli chcesz poprawić wszystkie moje błędy ortograficzne, dzięki za to :-)
Fabian Blechschmidt
Btw, masz rację sonassi :-) To coś, na co powinniśmy uważać. Widziałem zapytania SQL w plikach phtml ... NIE NIE :-)
Fabian Blechschmidt
4

Nie ma nic złego w ładowaniu modelu do phtmlpliku. Ale zależy to od tego, dlaczego to robisz.

Jeśli potrzebujesz całego modelu i wszystkich powiązanych z nim danych, równie dobrze możesz załadować cały model.

Ale jeśli potrzebujesz tylko adresu URL produktu (z Twojego przykładu), możesz po prostu załadować prawidłową kolekcję

$_product->getRelatedProductCollection();

Następnie powtarzaj to w razie potrzeby

<?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
źródło
3

Chcę tu umieścić moje 5 centów. Powinniśmy szanować zasady architektury stosowane w Magento. Głównym wzorem architektonicznym zastosowanym w Magento jest MVC. W przypadku Magento „Widok” część zawiera kilka rzeczy (blok, szablon, układ). Bloki zostały utworzone w celu przeniesienia logiki przygotowywania danych z szablonu do innej klasy, aby szablony były bardziej przejrzyste i czytelne dla programistów frontendów. Tutaj chcę się zgodzić z Fabianem.

Jeśli chodzi o obawy Sonassi o zbyt wiele niepotrzebnych zajęć, sugeruję, aby oczekiwać MVC opartego na push. W tym przypadku patrzymy na kontrolera jako na dowódcę, który określa, który blok i jakie dane powinny mieć. Działanie w kontrolerze może zawierać wymagany kod, aby załadować dane i umieścić je w bloku (za pomocą magicznych ustawień) przed renderowaniem.

Dmitrij Vasilenko
źródło
3

Zgadzam się z Fabianem Blechschmidtem, że jest to zła praktyka i należy szanować separację obaw.

Aby dodać konstruktywną sugestię:

To jest coś, do czego przeznaczone są klasy Block. W twoim przypadku musisz przepisać, Mage_Catalog_Block_Product_List aby dodać żądaną funkcjonalność:

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;
}

Powinno być oczywiste, jak korzystać z tych metod w szablonie.

Uwaga: Rewrite nie oznacza edycji pliku podstawowego. Wykonaj samouczek dostosowywania, jeśli nie wiesz, jak przepisać blok.

Fabian Schmengler
źródło