Я пытаюсь создать свой собственный модуль для 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() ?>
Большое спасибо за столь подробное и содержательное объяснение 🙂
Если те 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, и пути к файлу вашего блока.
Когда вы определяете файл 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
Затем вам просто нужно указать правильный путь от корневой папки ваших блоков до 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; ?>
Я заметил, что здесь есть пара проблем, поэтому я просто попытаюсь решить те, которые можно увидеть по тому, что вы опубликовали в своем вопросе, хотя то, что вы пытаетесь решить, не совсем ясно, и вы, вероятно, выиграете больше всего. от чтения руководство по макету, блокам и шаблонам Magento:
Ваши текущие имена классов не соответствуют Соглашения об именовании в автозагрузчике Magento, который вы заметите использовать ucwords()
на каждом элементе пути. Ваше имя класса должно быть примерно таким: Mynamespace_Mymodulename_Block_Myblockname
, который будет отображаться в файл app/code/.../Mynamespace/Mymodulename/Block/Myblockname.php
, Ваш конфиг XML должен быть обновлен, чтобы соответствовать.
В вашей директиве CMS в настоящее время не используется новый тип блока, поскольку он установлен на type="core/template"
когда это должно быть type="Mynamespace_Mymodulename/Myblockname"
если вы хотите использовать пользовательскую логику вашего блока в вашем шаблоне. Код вашего шаблона не отображается, но, вероятно, именно поэтому getCollection()
в вашем шаблоне не работает.
Если вы покажете больше своей работы, мы сможем помочь вам больше.