2012-07-28 90 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