Magento: вызвать пользовательский блок в CMS

Я пытаюсь создать свой собственный модуль для Magento 1.9.1. В моем модуле я пытаюсь вызвать блок в контенте CMS следующим образом:

{{block type="core/template" template="myNamespace/myModulOutput.phtml"}}

myModulOutput.phtml Шаблон содержит коллекцию из моего собственного контроллера:

class myNamespace_myModelname_Block extends Mage_Core_Block_Template
{
public function getCollection()
{
// some code
return $collection;
}
}

Модуль, кажется, активен и обнаруживается в бэкэнде Magento с этой конфигурацией:

<config>
<modules>
<myNamespace_myModulname>
<version>0.1.0</version>
</myNamespace_myModulname>
</modules>
<global>
<blocks>
<myNamespace_myModulname>
<class>myNamespace_myModulname_Block</class>
</myNamespace_myModulname>
</blocks>
</global>
</config>

Класс блока определяется в файле app/code/local/myNamespace/myModulname/Blocks/Index.php,

Это допустимая конфигурация? Я получаю сообщение об ошибке на веб-интерфейсе: Fatal error: Call to a member function getCollection() on a non-object,

РЕДАКТИРОВАТЬ

По объяснению от @ b.enoit.be я попробовал следующую настройку … она запускается 😉

приложение / и т.д. / модули / Mynamespace_Mymodulname.xml:

<?xml version="1.0"?>
<config>
<modules>
<Mynamespace_Mymodulname>
<active>true</active>
<codePool>local</codePool>
<depends/>
</Mynamespace_Mymodulname>
</modules>
</config>

Приложение / код / ​​местные / Mynamespace / Mymodulname / Block / index.php:

    <?php
class Mynamespace_Mymodulname_Block_Index extends Mage_Core_Block_Template
{
public function getTest()
{
// some code
return "mymodul:test";
}
}
?>

Приложение / код / ​​местные / Mynamespace / Mymodulname / и т.д. / config.xml:

<?xml version="1.0"?>
<config>
<modules>
<Mynamespace_Mymodulname>
<version>0.1.0</version>
</Mynamespace_Mymodulname >
</modules>
<global>
<blocks>
<mynamespace_mymodulname>
<class>Mynamespace_Mymodulname_Block</class>
</mynamespace_mymodulname >
</blocks>
</global>
</config>

CMS-Call

{{block type="mynamespace_mymodulname/index" template="mynamespace/myoutput.phtml"}}

приложение / дизайн / интерфейс / MyTheme / по умолчанию / mynamespace / myoutput.phtml:

<?php /** @var $this Mynamespace_Mymodulname_Block_Index */ ?>
<?php echo $this->getTest() ?>

Большое спасибо за столь подробное и содержательное объяснение 🙂

0

Решение

Если те myNamespace_myModulname действительно то, что у вас есть в вашем реальном коде, пожалуйста, сначала посмотрите на @fantasticrice ответ

Затем, если мы рассмотрим ваш код с правильным соглашением об именах (см. Примечание в конце этого поста), для начала это недопустимый класс блоков:

class Mynamespace_Mymodulename_Block extends Mage_Core_Block_Template{ /* ... */ }

Если, как вы говорите позже, ваш файл находится в

app/code/local/Mynamespace/Mymodulename/Block/Index.php

тогда действительный класс блока

class Mynamespace_Mymodulename_Block_Index extends Mage_Core_Block_Template{ /* ... */ }

Потому что имя класса в Magento должно всегда следовать той же архитектуре, что и путь к файлу (за исключением контроллеров, но мы вообще не говорим о контроллерах с кодом, который вы нам здесь дали) =>

class Mynamespace_Mymodulename_Block_Index === Mynamespace/Mymodulename/Block/Index.php

(Посмотрите, как я только что заменил подчеркивание косыми чертами и добавил это к .php расширение?).

Тогда то, что вы на самом деле хотите, это ваше мнение mynamespace/mymoduleoutput.phtml использовать свой собственный блок модуля.
Для этого вам нужно указать право тип для вашего блока.

Тип определяется сочетанием вашего дескриптора, определенного в config.xml, и пути к файлу вашего блока.

1. ручка

Когда вы определяете файл config.xml для модуля, вы должны знать, что некоторая часть «фиксированный» и некоторые части «ручка».
Это означает, что Magento ожидает, что некоторые части будут иметь ограниченное количество возможностей, например frontend or adminhtml or global, blocks, models, helpers, ... there is more here а некоторые — просто имя для псевдонима вашего модуля и для вызова или обработки, как мы называем это в Magento.

Здесь вы говорите в своем config.xml, что для <global> config (означает как для внешнего, так и для внутреннего интерфейса (= admin)) — фиксированный — Вы хотите добавить в список существующих <blocks>фиксированный — Magento блоков вашего модуля, на которые будут ссылаться — справиться<mynamespace_mymodulename> который затем сопоставится с файлами, в которых все классы начнутся с Mynamespace_Mymodulename_Block,

Это первая часть тип Вы хотите для своего собственного блока модуля.
mynamespace_mymodulename было бы эквивалентно для Magento Mynamespace_Mymodulename_Block

2. Правильный блок

Затем вам просто нужно указать правильный путь от корневой папки ваших блоков до Magento, который будет точно таким же, как и у вашей архитектуры папок / файлов, еще раз: так что в вашем случае просто index,
Итак, как вы теперь понимаете, Magento будет искать класс Mynamespace_Mymodulename_Block_Index (дескриптор + ‘_’ + указанный блок) в файле Mynamespace/Mymodulename/Block/Index.php как видно ранее.
Но если ваш файл был под app/code/local/Mynamespace/Mymodulename/Block/Path/To/File.php вам придется path_to_file => класс Mynamespace_Mymodulename_Block_Path_To_File, файл Mynamespace/Mymodulename/Block/Path/To/File.php

Теперь, когда у нас есть вторая часть нашего тип нам просто нужно собрать их с косой чертой: mynamespace_mymodulename/index

Таким образом, вы должны изменить свой звонок в вашем CMS на:

{{block type="mynamespace_mymodulename/index" template="mynamespace/mymoduleoutput.phtml"}}

И, надеюсь, с этим, это будет работать.

ПРИМЕЧАНИЕ 1/3: Как указано @fantasticrice, Я бы также предложил вам следовать правилам именования классов:

Zend Framework стандартизирует соглашение об именах классов, согласно которому
имена классов напрямую отображаются в каталоги, в которых они находятся
сохраняются. (…)

Имена классов могут содержать только буквенно-цифровые символы. Числа
разрешено в именах классов, но в большинстве случаев не рекомендуется.
Подчеркивание допускается только вместо разделителя пути;
имя файла «Zend / Db / Table.php» должно соответствовать имени класса
«Zend_Db_Table».

Если имя класса состоит из более чем одного слова, первая буква
каждого нового слова должно быть написано с заглавной буквы. Последовательные заглавные буквы
не допускаются, например класс «Zend_PDF» не допускается, пока
«Zend_Pdf» является приемлемым.

Эти соглашения определяют механизм псевдо-пространства имен для Zend
Фреймворк. Zend Framework примет функцию пространства имен PHP, когда она
становится доступным и возможно для наших разработчиков использовать в своих
Приложения.

Смотрите имена классов в стандартной и дополнительной библиотеках для примеров.
этого соглашения имени класса.

Источник : http://framework.zend.com/manual/1.12/en/coding-standard.naming-conventions.html

ПРИМЕЧАНИЕ 2/3: опять же, в соответствии с соглашением, только класс будет иметь структуру имени файла / папки с заглавной буквы. Таким образом, в ваших папках и файлах шаблонов вообще не должно быть заглавных букв.

ПРИМЕЧАНИЕ 3/3: В Magento, опять же, по соглашению мы не используем прописные буквы в ручках.


Приложение / код / ​​местные / Mynamespace / Mymodulename / и т.д. / config.xml

<?xml version="1.0"?>
<config>
<modules>
<Mynamespace_Mymodulename>
<version>0.1.0</version>
</Mynamespace_Mymodulename>
</modules>
<global>
<blocks>
<mynamespace_mymodulename>
<class>Mynamespace_Mymodulename_Block</class>
</mynamespace_mymodulename>
</blocks>
</global>
</config>

Приложение / код / ​​местные / Mynamespace / Mymodulename / Block / index.php

<?php
class Mynamespace_Mymodulename_Block_Index extends Mage_Core_Block_Template
{
public function getCollection()
{
// some code
return $collection;
}
}

CMS контент

{{block type="mynamespace_mymodulename/index" template="mynamespace/mymoduleoutput.phtml"}}

приложение / и т.д. / модули / Mynamespace_Mymodulename.xml

<?xml version="1.0"?>
<config>
<modules>
<Mynamespace_Mymodulename>
<active>true</active>
<codePool>local</codePool>
<depends/>
</Mynamespace_Mymodulename>
</modules>
</config>

приложение / дизайн / интерфейс / базы / по умолчанию / шаблон / mynamespace / mymoduleoutput.phtml

<?php /** @var $this Mynamespace_Mymodulename_Block_Index */ ?>
<?php foreach($this->getCollection() as $item): ?>
<?php //do something ?>
<?php endforeach; ?>
3

Другие решения

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

  1. Ваши текущие имена классов не соответствуют Соглашения об именовании в автозагрузчике Magento, который вы заметите использовать ucwords() на каждом элементе пути. Ваше имя класса должно быть примерно таким: Mynamespace_Mymodulename_Block_Myblockname, который будет отображаться в файл app/code/.../Mynamespace/Mymodulename/Block/Myblockname.php, Ваш конфиг XML должен быть обновлен, чтобы соответствовать.

  2. В вашей директиве CMS в настоящее время не используется новый тип блока, поскольку он установлен на type="core/template" когда это должно быть type="Mynamespace_Mymodulename/Myblockname" если вы хотите использовать пользовательскую логику вашего блока в вашем шаблоне. Код вашего шаблона не отображается, но, вероятно, именно поэтому getCollection() в вашем шаблоне не работает.

Если вы покажете больше своей работы, мы сможем помочь вам больше.

1

По вопросам рекламы [email protected]