简体   繁体   English

Magento:在CMS中调用自定义块

[英]Magento: call a custom block in CMS

I'm trying to create my own module for Magento 1.9.1. 我正在尝试为Magento 1.9.1创建自己的模块。 In my module, I am trying to call a block in CMS content like this: 在我的模块中,我试图像这样在CMS内容中调用一个块:

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

The myModulOutput.phtml template contains a collection from my own controller: myModulOutput.phtml模板包含来自我自己的控制器的集合:

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

The module seems to be active and shows up in Magento backend with this configuration: 该模块似乎处于活动状态,并通过以下配置显示在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>

The block class is defined in the file app/code/local/myNamespace/myModulname/Blocks/Index.php . 块类在app/code/local/myNamespace/myModulname/Blocks/Index.php文件中定义。

Is this a valid configuration? 这是有效的配置吗? I am getting an error on the frontend: Fatal error: Call to a member function getCollection() on a non-object . 我在前端收到一个错误: Fatal error: Call to a member function getCollection() on a non-object

EDIT 编辑

SOLVED 解决了

By explanation from @b.enoit.be I tried the following setting ... it's run ;-) 通过@ b.enoit.be的解释,我尝试了以下设置...它正在运行;-)

app/etc/modules/Mynamespace_Mymodulname.xml: 应用程序的/ etc /模块/ 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: 应用程序/代码/本地/ myNameSpace对象/ Mymodulname /座/ 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: 应用程序/代码/本地/ 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-Call CMS呼叫

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

app/design/frontend/myTheme/default/mynamespace/myoutput.phtml: 应用程序/设计/前端/ mytheme的/默认/ myNameSpace对象/ myoutput.phtml:

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

Many thanks for so detailed and meaningful explanation :-) 非常感谢您如此详尽而有意义的解释:-)

If those myNamespace_myModulname are really what you have in your actual code, please first have a look at @fantasticrice answer 如果这些myNamespace_myModulname确实是您实际代码中的名称,请首先查看@fantasticrice答案

Then, if we consider your code with the right naming convention (see note in the end of this post), to start up with, this is not a valid block class : 然后,如果我们以正确的命名约定考虑您的代码(请参见本文结尾处的注释),那么这不是有效的块类:

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

If, like you say it later on, your file is located in 如您稍后所说,如果您的文件位于

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

then the valid block class is 那么有效的块类是

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

Because class name in Magento should always follow the exact same architecture as your path to file (except for controllers, but we are not talking about controllers at all with the code you gave us here) => 因为Magento中的类名应始终遵循与文件路径完全相同的体系结构 (除了控制器,但是我们根本不会在此处提供的代码中谈论控制器)=>

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

(see how I just replaced underscore with slashes and postfixed this with a .php extension ?). (请参阅我如何用下划线替换下划线,并使用.php扩展.php后缀吗?)。

Then what you actually want is your your view mynamespace/mymoduleoutput.phtml to use your own module block. 然后,您真正想要的是您的视图mynamespace/mymoduleoutput.phtml以使用您自己的模块块。
For this, you have to specify the right type for your block. 为此,您必须为块指定正确的类型

The type is defined by a combinaison of your handle defined in config.xml and from the path to your block file. 该类型由config.xml中定义的句柄以及从块文件的路径的组合定义。

1. The handle 1.手柄

When you define a config.xml for a module, you have to be aware that some part are "fixed" and some parts are "handles" . 在为模块定义config.xml时,必须注意某些部分是“固定的”,而某些部分是“句柄”的
Meaning that some parts are expected by Magento to be in a limited number of possibilities eg frontend or adminhtml or global , blocks, models, helpers, ... there is more here and some are just name to alias your module and to call it or handle as we call that under Magento. 这意味着Magento期望某些部分具有有限的可能性,例如, frontend or adminhtml or globalblocks, models, helpers, ... there is more here还有一些只是为模块起别名并命名为按照我们在Magento下的说法进行处理。

Here you say in your config.xml that for the <global> config (means for both frontend and backend (= admin)) -- fixed -- you want to add to the list of existing <blocks> -- fixed -- of Magento the blocks of your module that would be referenced by the -- handle -- <mynamespace_mymodulename> which will then map to files in which the classes will all begin with Mynamespace_Mymodulename_Block . 在这里,您在config.xml中说,对于<global>配置(意味着前端和后端(= admin)均表示)-已修复 -您想添加到现有<blocks>列表中-已修复 Magento的你的模块将被引用的块- 手柄 - <mynamespace_mymodulename>然后将映射到其中的类都将开始文件Mynamespace_Mymodulename_Block

That is the first part of the type you want for your own module block. 这是您想要的模块块类型的第一部分。
mynamespace_mymodulename would be equivalent for Magento to Mynamespace_Mymodulename_Block mynamespace_mymodulename将等同于Magento的到Mynamespace_Mymodulename_Block

2. The right block 2.正确的方块

Then you just have to indicate the right path from the root folder of your Blocks to Magento, which will be the exact same as your folders/files architecture, once again : so in your case, just index . 然后,您只需指定从Blocks的根文件夹到Magento的正确路径即可,这与您的文件夹/文件架构完全相同:再次,对于您的情况,只需index
So as you may now understand, Magento will lookup to a class Mynamespace_Mymodulename_Block_Index (handle + '_' + specified block) in the file Mynamespace/Mymodulename/Block/Index.php as seen earlier. 如您现在所了解,Magento将在文件Mynamespace/Mymodulename/Block/Index.php Mynamespace_Mymodulename_Block_Index查找类Mynamespace_Mymodulename_Block_Index (句柄+'_'+指定的块)。
But if your file was under app/code/local/Mynamespace/Mymodulename/Block/Path/To/File.php you would have path_to_file => class Mynamespace_Mymodulename_Block_Path_To_File , file Mynamespace/Mymodulename/Block/Path/To/File.php 但是,如果您的文件位于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

Now that we have the second part of our type we just have to assemble them with a slash : mynamespace_mymodulename/index 现在我们有了类型的第二部分,我们只需要用斜杠将它们组合起来即可: mynamespace_mymodulename/index

So you have to change your call in your cms to : 因此,您必须将cms中的呼叫更改为:

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

And hopefully, with this, it would work. 并希望以此解决问题。

NOTE 1/3 : As pointed out by @fantasticrice , I would also suggest you to follow the naming convention of class: 注意1/3:正如@fantasticrice指出的那样 ,我还建议您遵循class的命名约定:

Zend Framework standardizes on a class naming convention whereby the names of the classes directly map to the directories in which they are stored. Zend Framework遵循类命名约定的标准,由此类的名称直接映射到存储它们的目录。 (...) (......)

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". 文件名“ Zend / Db / Table.php”必须映射到类名“ 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, eg a class "Zend_PDF" is not allowed while "Zend_Pdf" is acceptable. 不允许连续使用大写字母,例如,不允许使用“ Zend_PDF”类,而可以使用“ Zend_Pdf”。

These conventions define a pseudo-namespace mechanism for Zend Framework. 这些约定为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. Zend Framework将在可用时采用PHP名称空间功能,并且对于我们的开发人员在其应用程序中使用是可行的。

See the class names in the standard and extras libraries for examples of this classname convention. 有关此类名约定的示例,请参见标准库和Extras库中的类名。

Source : http://framework.zend.com/manual/1.12/en/coding-standard.naming-conventions.html 来源: http : //framework.zend.com/manual/1.12/en/coding-standard.naming-conventions.html

NOTE 2/3 : that per convention again, only class are going to have a capitalised file name / folder structure. 注2/3:再次按照惯例,只有类将具有大写的文件名/文件夹结构。 So, your template folders and files should not have capital in it at all. 因此,模板文件夹和文件中根本没有大写字母。

NOTE 3/3 : In Magento, again, per convention we do not use capitals in handles. 注意3/3:同样,在Magento中,按照惯例,我们在句柄中不使用大写字母。


TL;DR TL; DR

app/code/local/Mynamespace/Mymodulename/etc/config.xml 应用程序/代码/本地/ 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 应用程序/代码/本地/ myNameSpace对象/ Mymodulename /座/ index.php文件

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

CMS content CMS内容

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

app/etc/modules/Mynamespace_Mymodulename.xml 应用程序的/ etc /模块/ 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 应用程序/设计/前端/基/默认/模板/ myNameSpace对象/ mymoduleoutput.phtml

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

There are a couple issues here that I notice, so I will just try to address the ones that can be seen by what you have posted in your question, although what you are trying to accomplish is not totally clear, and you would probably benefit most from reading a guide about Magento's layout, blocks, and templates : 我注意到这里有几个问题,所以我将尽力解决那些可以通过您在问题中发表的内容看到的问题,尽管您要完成的任务还不是很清楚,您可能会从中受益最大通过阅读有关Magento的布局,块和模板的指南

  1. Your current class names do not follow the Magento autoloader naming conventions , which you'll notice use ucwords() on each path element. 您当前的类名称未遵循Magento自动加载器的命名约定 ,您会注意到在每个path元素上使用ucwords() Your class name should be something like: Mynamespace_Mymodulename_Block_Myblockname , which would map to the file app/code/.../Mynamespace/Mymodulename/Block/Myblockname.php . 您的类名称应类似于: Mynamespace_Mymodulename_Block_Myblockname ,它将映射到文件app/code/.../Mynamespace/Mymodulename/Block/Myblockname.php Your config XML should be updated to match. 您的配置XML应该进行更新以匹配。

  2. Your CMS directive currently doesn't make use of your new block type since it is set to type="core/template" when it should be type="Mynamespace_Mymodulename/Myblockname" if you wish to make use of your block's custom logic in your template. 您的CMS指令当前未使用新的块类型,因为如果您希望在自己的块中使用块的自定义逻辑,则将其设置为type="core/template"时应将其设置为type="Mynamespace_Mymodulename/Myblockname"模板。 Your template's code is not shown, but this is likely why calling getCollection() in your template isn't working. 模板的代码未显示,但这可能是为什么在模板中调用getCollection()无法正常工作的原因。

If you show more of your work, we might be able to help more. 如果您的工作更多,我们可能会提供更多帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM