2012-07-28 91 views
0

我终于到达了我的第二个Magento模块的“渲染”阶段,但我再次卡住了。该模块现在几乎完成,它有一个控制器和两个块,其中一个由第一个调用(一个是仪表板块,使用第二个块填充子部分)。Magento - 由自定义扩展提供的块未加载

我现在需要做的是将这个新仪表板添加到客户帐户仪表板。我被告知要使用布局文件,并且我已经在Magento Design Guide上阅读了他们。然后我创建了布局文件并在其中添加了我的块的声明。但是,仪表板不会被修改,我的数据也不会显示。如果我手动调用扩展方法(即myserver/customerstats/index),我找回要在客户帐户页面上显示的HTML片段。

起初我以为我的布局文件没有加载,但我现在有证据表明它的处理正确(至少,它的一部分)。这里的布局文件:

<layout version="0.1.0"> 
    <customer_account_index translate="label"> 
     <label>My Custom Dashboard</label> 
     <reference name="customer_account_dashboard"> 
      <!-- The action is processed correctly, the template is overridden --> 
      <action method="setTemplate"><template>customerstats/customer/account/dashboard.phtml</template></action> 
      <block type="customerstats/index" name="customerstats_dashboard" as="customerstats.dashboard" template="customerstats/customerstatsdashboard.phtml" /> 
     </reference> 
    </customer_account_index> 
</layout> 

我加入了setTemplate行动,布局文件,因为其中一项规定是,新的仪表板分为两个部分垂直分割。这意味着我必须修改原始的customer/account/dashboard.phtml并更改页面的结构,并添加两个将根据需要进行样式设置的部分。我不确定这是否是正确的做法,但我无法弄清楚如何在页面的特定部分添加附加内容,而无需触摸.phtml文件。

我修改了新的dashboard.phtml,以确保它已加载,并且我可以在启用该操作时看到显示我的更改的客户帐户页面。但是,我的扩展应该呈现的块不会出现在页面上,并且基于我简单的“陷阱”(简单的“die()”)来证明代码被执行),扩展方法不会甚至似乎被称为。

下面是控制器我试图从块中调用,删除不相关的部分。

class MyCompany_CustomerStats_IndexController extends Mage_Core_Controller_Front_Action { 
    // The loaded block is setting its own template in the _construct() phase 
    $Block = &$this->getLayout()->createBlock('customerstats/customerstatsdashboard'); 

    // Some data is loaded elsewhere and passed to the Block 

    $this->getResponse()->setBody(
     $Block->toHtml() 
    ); 
} 

如果我手动调用它(MYSERVER /customerstats /指数)则控制器可以正常发射和返回完全呈现HTML,但是,在开始提到的,它似乎并没有运行布局时文件发挥作用。

总而言之,这里是我的问题:
- 我在正确的轨道上关于客户帐户仪表板的覆盖?
- 我必须在扩展的布局中指定模板属性吗?我实现的所有块都通过代码加载它们的模板(有选择使用哪一个的逻辑),并且我也没有看到使用xml文件中指定的模板。
- 一旦我将一个块添加到XML文件中,是否必须更改dashboard.phtml文件以将其呈现在某处?我问,因为我看到了原始仪表板模板,并且它包含对getChildHtml('alias name of a block')的各种调用。这使我认为块不必在布局文件中“暴露”,而是在.phtml文件中手动调用块。然而,这是一个猜测,因为我对这个机制没有清楚的认识。 注意:我也尝试在我的新dashboard.phtml中调用getChildHtml('customerstats.dashboard),但没有任何更改。

在此先感谢所有的答案。

更新1 - 2012/07/28
这是未呈现的块代码。

class MyCompany_CustomerStats_Block_UserStatsDashboard extends Mage_Core_Block_Template { 
    const _TEMPLATE = 'customerStats/userstatsdashboard.phtml'; 

    public function _construct() { 
     $this->setTemplate(self::_TEMPLATE); 
    } 
} 

此外,我做了一个与控制器本身的实验。我改变了它如下:

class MyCompany_CustomerStats_IndexController extends Mage_Core_Controller_Front_Action { 
    die('Controller called successfully.'); 
} 

下面是结果: - “控制器成功地称为” 如果我从浏览器中调用“MYSERVER/customerstats /指数”,我得到的消息。 - 如果我加载了我修改的仪表板页面,我可以看到新的布局(这意味着我的仪表板已加载),但不是消息。对我而言,这意味着控制器甚至没有被调用。

内容的Config.xml

<?xml version="1.0"?> 
<config> 
    <modules> 
     <MyCompany_CustomerStats> 
      <version>0.1.0</version> 
     </MyCompany_CustomerStats> 
    </modules> 
    <global> 
    <helpers> 
     <CustomerStats> 
     <class>MyCompany_CustomerStats_Helper</class> 
     </CustomerStats> 
    </helpers> 
    <models> 
     <CustomerStats> 
     <class>MyCompany_CustomerStats_Model</class> 
     </CustomerStats> 
    </models> 
    <blocks> 
     <CustomerStats> 
     <class>MyCompany_CustomerStats_Block</class> 
     </CustomerStats> 
    </blocks> 
    </global> 

    <frontend> 
    <routers> 
     <CustomerStats> 
     <use>standard</use> 
     <args> 
      <module>MyCompany_CustomerStats</module> 
      <frontName>userstats</frontName> 
     </args> 
     </CustomerStats> 
    </routers> 
     <layout> 
     <updates> 
      <CustomerStats> 
        <file>customerstats.xml</file> 
       </CustomerStats> 
      </updates> 
     </layout> 
    </frontend> 
</config> 

更新2 - 2012年7月28日
我做了一个实验,我承认,从一个MVC角度使得完全没有意义的我。我将布局和指定的块类型更改为customerstats/userstatsdashboard。然后我修改了块类MyCompany_CustomerStats_Block_UserStatsDashboard如下:

public function _construct() { 
    echo "Block rendered."; 
} 

出人意料的是,现在的东西出现在新的布局,正是我所期待的!但是这意味着控制器根本没有被调用,这反过来意味着没有可用的数据块。
这真的让我感到困惑,我从来没有见过MVC模型的视图管理自己......那么扩展的控制器的目的是什么?

+0

一个快速的建议,尝试改变reference_name到=“内容” – Sturm 2012-07-28 00:11:26

+0

谢谢paperids,但我会问你,为什么?引用应该是我想与之“交互”的块,而块是“customer_account_dashboard”。事实上,正如我写的,其模板如我所料地发生了变化。这只是我的内容不附加到它,因为某种原因。 – Diego 2012-07-28 00:24:35

回答

3

你块类组为CustomerStats,但你是不是在你的布局使用此。 Block类群组只是绝不global/blocks下独特的文本节点需要“匹配”的任何文件夹结构(仅供参考)。这个字符串的重要性仅在于它与createBlock()的任何调用的第一部分(在斜线之前)相匹配,这意味着您的布局XML应该指定例如type="CustomerStats/whatever"

在上例中,根据您的类别前缀MyCompany_CustomerStats_Block将生成的类名为MyCompany_CustomerStats_Block_Whatever

+0

感谢benmarks。有一件事我不清楚:我需要做的是用一些HTML填充一个模板,而这个HTML又是通过调用Controller方法“MyCompany_CustomerStats_IndexController”生成的。这个控制器然后会加载一个块,它将使用一些数据并生成HTML。因此,应该对控制器进行调用,而不是直接对块进行调用。 – Diego 2012-07-28 16:58:34

+0

另外,在控制器内部调用'createBlock()',它正在准备数据,加载正确的块类并返回HTML。总之,我不确定在我的情况下实际需要多少块布局中指定的块属性。控制器和块都没有考虑到它。事实上,扩展工作完全没有布局文件,我唯一的问题是将渲染的结果嵌入到模板中。 – Diego 2012-07-28 17:04:31

+0

正确。与大多数MVC框架一样,Magento MVC体系结构也有动作控制器修改响应对象。这可以通过故意块渲染直接完成,也可以通过布局XML视图建模进行渲染。 Magento偏离了一点的地方是让视图(块)加载他们自己的数据,这通常是在'_prepareLayout()'方法中完成的。换句话说:Magento控制器*通常*不会加载或处理任何不需要(重新)指示请求的数据。 – benmarks 2012-07-28 17:09:07

1

没有考虑到例外情况,有两种类型的块。 A core/text_list和所有其他类型。当引用core/text_list时,例如content块将自动呈现所有添加的块。

当引用不同于core/text_list的东西时,对于您的情况customer/account_dashboard,您需要从模板中自己获取内容。这可以通过拨打getChildHtml()来完成,就像您已经建议的那样。

虽然我无法使用您提供的代码验证此错误,但是您的模块中找不到customerstats/index块类型,或者它不会扩展Mage_Core_Block_Template。或者您将不存在的类组传递给createBlock工厂方法。

所以你的模块中,应该是这样的:

<blocks> 
     <customerstats> 
      <class><your_namespace>_Customerstats_Block</class> 
     </customerstats> 
    </blocks> 

但我认为你可能有一个手柄那里叫customerdata而不是customerstats。 由于您从控制器调用的块的类型为customerdata/customerstatsdashboard,而且这个块可以正常工作。尽管你的XML中使用了customerstats。如果是这样的话,你可能想尝试和调整的XML:使用模板的块应该像工作时

<block type="customerdata/index" name="customerstats_dashboard" as="customerstats.dashboard" template="customerdata/customerstatsdashboard.phtml" /> 

此外。因此总是扩展Mage_Core_Block_Template。否则getChildHtml将不可用。 <your_namespace>_Customerstats_Block_Index extends Mage_Core_Block_Template

希望这有助于你与你的任务,否则请提供反馈您已经试过这之后。

+0

谢谢蒂姆。如果我手动运行它们,即不通过布局xml文件,则不渲染的块扩展Mage_Core_Block_Template,并且createBlock()和getChildHtml()都会工作。我按照您的建议修改了这些文件(请参阅修改后的问题),但该块仍未加载。 – Diego 2012-07-28 12:37:20

+0

您还可以包含模块的config.xml吗? – 2012-07-28 14:11:32

+0

完成。再次感谢您的帮助。 :) – Diego 2012-07-28 14:16:47