Magento:在 CMS 中调用自定义块
Magento: call a custom block in 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>
块 class 在文件 app/code/local/myNamespace/myModulname/Blocks/Index.php
中定义。
这是一个有效的配置吗?我在前端收到错误消息:Fatal error: Call to a member function getCollection() on a non-object
.
编辑
已解决
根据@b.enoit.be 的解释,我尝试了以下设置...它是 运行 ;-)
app/etc/modules/Mynamespace_Mymodulname.xml:
<?xml version="1.0"?>
<config>
<modules>
<Mynamespace_Mymodulname>
<active>true</active>
<codePool>local</codePool>
<depends/>
</Mynamespace_Mymodulname>
</modules>
</config>
app/code/local/Mynamespace/Mymodulname/Block/Index.php:
<?php
class Mynamespace_Mymodulname_Block_Index extends Mage_Core_Block_Template
{
public function getTest()
{
// some code
return "mymodul:test";
}
}
?>
app/code/local/Mynamespace/Mymodulname/etc/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-调用
{{block type="mynamespace_mymodulname/index" template="mynamespace/myoutput.phtml"}}
app/design/frontend/myTheme/default/mynamespace/myoutput.phtml:
<?php /** @var $this Mynamespace_Mymodulname_Block_Index */ ?>
<?php echo $this->getTest() ?>
非常感谢如此详细而有意义的解释:-)
我注意到这里有几个问题,所以我将尝试解决您在问题中发布的内容可以看到的问题,尽管您想要完成的事情并不完全清楚,并且您可能会从阅读 guide about Magento’s layout, blocks, and templates:
中获益最多
您当前的 class 名称不遵循 Magento autoloader naming conventions,您会注意到在每个路径元素上使用 ucwords()
。您的 class 名称应该类似于:Mynamespace_Mymodulename_Block_Myblockname
,它将映射到文件 app/code/.../Mynamespace/Mymodulename/Block/Myblockname.php
。您的配置 XML 应该更新以匹配。
你的 CMS 指令目前没有使用你的新块类型,因为它被设置为 type="core/template"
,而如果你想使用它应该是 type="Mynamespace_Mymodulename/Myblockname"
你的块在你的模板中的自定义逻辑。您的模板代码未显示,但这可能是在您的模板中调用 getCollection()
无效的原因。
如果您展示更多您的作品,我们可能会提供更多帮助。
如果那些 myNamespace_myModulname
确实是您实际代码中的内容,请先查看
然后,如果我们认为您的代码具有正确的命名约定(请参阅此 post 末尾的注释),首先,这不是一个有效的块 class :
class Mynamespace_Mymodulename_Block extends Mage_Core_Block_Template{ /* ... */ }
如果像您稍后所说的那样,您的文件位于
app/code/local/Mynamespace/Mymodulename/Block/Index.php
那么有效区块class是
class Mynamespace_Mymodulename_Block_Index extends Mage_Core_Block_Template{ /* ... */ }
因为 Magento 中的 class 名称应该始终 遵循与文件路径完全相同的体系结构 (控制器除外,但我们根本不是在谈论控制器使用您在此处提供给我们的代码)=>
class Mynamespace_Mymodulename_Block_Index === Mynamespace/Mymodulename/Block/Index.php
(看看我是如何用斜杠替换下划线并 post 用 .php
扩展名解决这个问题的?)。
那么你真正想要的是你的视图mynamespace/mymoduleoutput.phtml
使用你自己的模块。
为此,您必须为您的块指定正确的类型。
类型由 config.xml 中定义的句柄和块文件路径的组合定义。
1。句柄
当你为一个模块定义一个config.xml时,你必须知道有些部分是"fixed"有些部分是"handles".
这意味着 Magento 期望某些部分具有有限数量的可能性,例如frontend or adminhtml or global
、blocks, models, helpers, ... there is more here
和一些只是名称来为您的模块添加别名并调用它或处理我们在 Magento 下的调用。
这里你在 config.xml 中说 <global>
配置(意味着前端和后端(= admin))-- fixed - - 你想添加到 Magento 的现有 <blocks>
-- fixed -- -- 将引用的模块块的列表handle -- <mynamespace_mymodulename>
然后将映射到 classes 都以 Mynamespace_Mymodulename_Block
.[= 开头的文件42=]
这是您想要的 type 模块的第一部分。
mynamespace_mymodulename
等同于 Magento 的 Mynamespace_Mymodulename_Block
2。右方块
然后你只需要指出从你的块的根文件夹到 Magento 的正确路径,这将与你的 folders/files 架构完全相同,再一次:所以在你的情况下,只是 index
.
因此,正如您现在可能理解的那样,Magento 将在文件 Mynamespace/Mymodulename/Block/Index.php
中查找 class Mynamespace_Mymodulename_Block_Index
(句柄 + '_' + 指定块)。
但是,如果您的文件在 app/code/local/Mynamespace/Mymodulename/Block/Path/To/File.php
下,您将拥有 path_to_file
=> class Mynamespace_Mymodulename_Block_Path_To_File
、文件 Mynamespace/Mymodulename/Block/Path/To/File.php
现在我们有了 type 的第二部分,我们只需要 assemble 加上斜线即可:mynamespace_mymodulename/index
因此您必须将您在 cms 中的调用更改为:
{{block type="mynamespace_mymodulename/index" template="mynamespace/mymoduleoutput.phtml"}}
希望它能奏效。
NOTE 1/3 : 正如@fantasticrice所指出的,我也建议你遵循[=的命名约定144=]:
Zend Framework standardizes on a class naming convention whereby the
names of the classes directly map to the directories in which they are
stored. (...)
Class names may only contain alphanumeric characters. Numbers are
permitted in class names but are discouraged in most cases.
Underscores are only permitted in place of the path separator; the
filename "Zend/Db/Table.php" must map to the class name
"Zend_Db_Table".
If a class name is comprised of more than one word, the first letter
of each new word must be capitalized. Successive capitalized letters
are not allowed, e.g. a class "Zend_PDF" is not allowed while
"Zend_Pdf" is acceptable.
These conventions define a pseudo-namespace mechanism for Zend
Framework. Zend Framework will adopt the PHP namespace feature when it
becomes available and is feasible for our developers to use in their
applications.
See the class names in the standard and extras libraries for examples
of this classname convention.
来源:http://framework.zend.com/manual/1.12/en/coding-standard.naming-conventions.html
注意 2/3 : 再次按照约定,只有 class 将具有大写的文件名/文件夹结构。所以,你的模板文件夹和文件根本不应该有大写字母。
注意 3/3 : 在 Magento 中,同样,按照惯例,我们不在句柄中使用大写字母。
TL;DR
app/code/local/Mynamespace/Mymodulename/etc/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>
app/code/local/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"}}
app/etc/modules/Mynamespace_Mymodulename.xml
<?xml version="1.0"?>
<config>
<modules>
<Mynamespace_Mymodulename>
<active>true</active>
<codePool>local</codePool>
<depends/>
</Mynamespace_Mymodulename>
</modules>
</config>
app/design/frontend/base/default/template/mynamespace/mymoduleoutput.phtml
<?php /** @var $this Mynamespace_Mymodulename_Block_Index */ ?>
<?php foreach($this->getCollection() as $item): ?>
<?php //do something ?>
<?php endforeach; ?>
我正在尝试为 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>
块 class 在文件 app/code/local/myNamespace/myModulname/Blocks/Index.php
中定义。
这是一个有效的配置吗?我在前端收到错误消息:Fatal error: Call to a member function getCollection() on a non-object
.
编辑
已解决
根据@b.enoit.be 的解释,我尝试了以下设置...它是 运行 ;-)
app/etc/modules/Mynamespace_Mymodulname.xml:
<?xml version="1.0"?>
<config>
<modules>
<Mynamespace_Mymodulname>
<active>true</active>
<codePool>local</codePool>
<depends/>
</Mynamespace_Mymodulname>
</modules>
</config>
app/code/local/Mynamespace/Mymodulname/Block/Index.php:
<?php
class Mynamespace_Mymodulname_Block_Index extends Mage_Core_Block_Template
{
public function getTest()
{
// some code
return "mymodul:test";
}
}
?>
app/code/local/Mynamespace/Mymodulname/etc/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-调用
{{block type="mynamespace_mymodulname/index" template="mynamespace/myoutput.phtml"}}
app/design/frontend/myTheme/default/mynamespace/myoutput.phtml:
<?php /** @var $this Mynamespace_Mymodulname_Block_Index */ ?>
<?php echo $this->getTest() ?>
非常感谢如此详细而有意义的解释:-)
我注意到这里有几个问题,所以我将尝试解决您在问题中发布的内容可以看到的问题,尽管您想要完成的事情并不完全清楚,并且您可能会从阅读 guide about Magento’s layout, blocks, and templates:
中获益最多您当前的 class 名称不遵循 Magento autoloader naming conventions,您会注意到在每个路径元素上使用
ucwords()
。您的 class 名称应该类似于:Mynamespace_Mymodulename_Block_Myblockname
,它将映射到文件app/code/.../Mynamespace/Mymodulename/Block/Myblockname.php
。您的配置 XML 应该更新以匹配。你的 CMS 指令目前没有使用你的新块类型,因为它被设置为
type="core/template"
,而如果你想使用它应该是type="Mynamespace_Mymodulename/Myblockname"
你的块在你的模板中的自定义逻辑。您的模板代码未显示,但这可能是在您的模板中调用getCollection()
无效的原因。
如果您展示更多您的作品,我们可能会提供更多帮助。
如果那些 myNamespace_myModulname
确实是您实际代码中的内容,请先查看
然后,如果我们认为您的代码具有正确的命名约定(请参阅此 post 末尾的注释),首先,这不是一个有效的块 class :
class Mynamespace_Mymodulename_Block extends Mage_Core_Block_Template{ /* ... */ }
如果像您稍后所说的那样,您的文件位于
app/code/local/Mynamespace/Mymodulename/Block/Index.php
那么有效区块class是
class Mynamespace_Mymodulename_Block_Index extends Mage_Core_Block_Template{ /* ... */ }
因为 Magento 中的 class 名称应该始终 遵循与文件路径完全相同的体系结构 (控制器除外,但我们根本不是在谈论控制器使用您在此处提供给我们的代码)=>
class Mynamespace_Mymodulename_Block_Index === Mynamespace/Mymodulename/Block/Index.php
(看看我是如何用斜杠替换下划线并 post 用 .php
扩展名解决这个问题的?)。
那么你真正想要的是你的视图mynamespace/mymoduleoutput.phtml
使用你自己的模块。
为此,您必须为您的块指定正确的类型。
类型由 config.xml 中定义的句柄和块文件路径的组合定义。
1。句柄
当你为一个模块定义一个config.xml时,你必须知道有些部分是"fixed"有些部分是"handles".
这意味着 Magento 期望某些部分具有有限数量的可能性,例如frontend or adminhtml or global
、blocks, models, helpers, ... there is more here
和一些只是名称来为您的模块添加别名并调用它或处理我们在 Magento 下的调用。
这里你在 config.xml 中说 这是您想要的 type 模块的第一部分。 然后你只需要指出从你的块的根文件夹到 Magento 的正确路径,这将与你的 folders/files 架构完全相同,再一次:所以在你的情况下,只是 现在我们有了 type 的第二部分,我们只需要 assemble 加上斜线即可: 因此您必须将您在 cms 中的调用更改为: 希望它能奏效。 NOTE 1/3 : 正如@fantasticrice所指出的,我也建议你遵循[=的命名约定144=]: Zend Framework standardizes on a class naming convention whereby the
names of the classes directly map to the directories in which they are
stored. (...) Class names may only contain alphanumeric characters. Numbers are
permitted in class names but are discouraged in most cases.
Underscores are only permitted in place of the path separator; the
filename "Zend/Db/Table.php" must map to the class name
"Zend_Db_Table". If a class name is comprised of more than one word, the first letter
of each new word must be capitalized. Successive capitalized letters
are not allowed, e.g. a class "Zend_PDF" is not allowed while
"Zend_Pdf" is acceptable. These conventions define a pseudo-namespace mechanism for Zend
Framework. Zend Framework will adopt the PHP namespace feature when it
becomes available and is feasible for our developers to use in their
applications. See the class names in the standard and extras libraries for examples
of this classname convention. 来源:http://framework.zend.com/manual/1.12/en/coding-standard.naming-conventions.html 注意 2/3 : 再次按照约定,只有 class 将具有大写的文件名/文件夹结构。所以,你的模板文件夹和文件根本不应该有大写字母。 注意 3/3 : 在 Magento 中,同样,按照惯例,我们不在句柄中使用大写字母。 app/code/local/Mynamespace/Mymodulename/etc/config.xml app/code/local/Mynamespace/Mymodulename/Block/Index.php CMS 内容 app/etc/modules/Mynamespace_Mymodulename.xml app/design/frontend/base/default/template/mynamespace/mymoduleoutput.phtml<global>
配置(意味着前端和后端(= admin))-- fixed - - 你想添加到 Magento 的现有 <blocks>
-- fixed -- -- 将引用的模块块的列表handle -- <mynamespace_mymodulename>
然后将映射到 classes 都以 Mynamespace_Mymodulename_Block
.[= 开头的文件42=]
mynamespace_mymodulename
等同于 Magento 的 Mynamespace_Mymodulename_Block
2。右方块
index
.
因此,正如您现在可能理解的那样,Magento 将在文件 Mynamespace/Mymodulename/Block/Index.php
中查找 class Mynamespace_Mymodulename_Block_Index
(句柄 + '_' + 指定块)。
但是,如果您的文件在 app/code/local/Mynamespace/Mymodulename/Block/Path/To/File.php
下,您将拥有 path_to_file
=> class Mynamespace_Mymodulename_Block_Path_To_File
、文件 Mynamespace/Mymodulename/Block/Path/To/File.php
mynamespace_mymodulename/index
{{block type="mynamespace_mymodulename/index" template="mynamespace/mymoduleoutput.phtml"}}
TL;DR
<?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>
<?php
class Mynamespace_Mymodulename_Block_Index extends Mage_Core_Block_Template
{
public function getCollection()
{
// some code
return $collection;
}
}
{{block type="mynamespace_mymodulename/index" template="mynamespace/mymoduleoutput.phtml"}}
<?xml version="1.0"?>
<config>
<modules>
<Mynamespace_Mymodulename>
<active>true</active>
<codePool>local</codePool>
<depends/>
</Mynamespace_Mymodulename>
</modules>
</config>
<?php /** @var $this Mynamespace_Mymodulename_Block_Index */ ?>
<?php foreach($this->getCollection() as $item): ?>
<?php //do something ?>
<?php endforeach; ?>