Хорошо ли создавать экземпляр класса getModel в шаблонах phtml?

14

Это вопрос относительно хорошей практики программирования в Magento.

Мне нужно показать (в списке товаров категории) товар с сопутствующими товарами в виде миниатюр. Поэтому я отредактировал mypackage/mytheme/template/catalog/product/list.phtmlчто-то вроде этого

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

И это работает очень хорошо.

Но мой вопрос: правильно ли создавать экземпляр класса модели в файлах phtml?

Если нет, то как лучше всего достичь этой функциональности? Я имею в виду, какой файл лучше редактировать или какой класс лучше добавить, где? Помощник?

Можете ли вы привести небольшой пример или дать мне представление о том, какие файлы лучше редактировать.

user604
источник

Ответы:

10

Я хочу не согласиться с ответом Сонасси :)

Инициирование модели в шаблоне - плохая практика. Иногда это нужно, а иногда и я тоже. Но если это возможно, вы должны запретить добавлять код в ваши файлы pHTML и толькоecho данные вещи.

Это разделение интересов . Не путайте HTML и кодирование. Это должно быть в классе Block.

Фабиан Блехшмидт
источник
3
Я также согласен с вашим несогласием :) Но загрузка одной модели вне цикла - это еще не конец света. В противном случае это становится бесконечным случаем абстракции - добавление дополнительных классов, существующих просто для отделения одной строки кода от представления. Это просто добавляет, чтобы переписать накладные расходы, не говоря уже о техническом обслуживании.
Бен Лессани - Сонасси
У вас слишком мало времени, если вы хотите исправить все мои орфографические ошибки, спасибо за это :-)
Фабиан Блехшмидт
Кстати, вы правы sonassi :-) Это просто то, с чем мы должны быть осторожны. Я видел SQL-запросы в phtml-файлах ... НЕТ НЕТ :-)
Фабиан Блехшмидт
4

Нет ничего плохого в загрузке модели в phtmlфайл. Но это зависит от того, почему вы это делаете.

Если вам нужна вся модель и все данные, связанные с ней, то вы также можете загрузить всю модель.

Но если вам просто нужен URL продукта (из вашего примера), вы можете просто загрузить правильную коллекцию

$_product->getRelatedProductCollection();

Затем повторите это по мере необходимости

<?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; ?>
Бен Лессани - Сонасси
источник
3

Хочу поставить мои 5 центов здесь. Мы должны уважать принципы архитектуры, которые используются в Magento. Основной архитектурный образец, используемый в Magento - MVC. В случае Magento «View» часть содержит несколько вещей (блок, шаблон, макет). Блоки были созданы для перемещения логики подготовки данных из шаблона в другой класс, чтобы сделать шаблоны более понятными и удобочитаемыми для разработчиков веб-интерфейса. Здесь я хочу согласиться с Фабианом.

Что касается опасений Сонасси по поводу слишком большого количества ненужных классов, я предлагаю с нетерпением ждать MVC. В этом случае мы рассматриваем контроллер как командира, который определяет, какой блок и какие данные должны иметь. Действие в контроллере может содержать необходимый код для загрузки данных и помещения их в блок (с помощью магических сеттеров) перед рендерингом.

Дмитрий Василенко
источник
3

Я согласен с Фабианом Блехшмидтом, что это плохая практика, и вы должны уважать разделение проблем.

Чтобы добавить конструктивное предложение:

Это то, для чего предназначены классы Block. В вашем случае вам придется переписать, Mage_Catalog_Block_Product_List чтобы добавить желаемый функционал:

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

Должно быть очевидно, как использовать эти методы в шаблоне.

Примечание. Перезапись не означает редактирование файла ядра. Следуйте инструкциям по настройке, если вы не знаете, как переписать блок.

Фабиан Шменглер
источник