类别页面的自定义布局 - 处理问题

时间:2015-09-17 11:19:00

标签: xml magento layout module block

我有自定义模块,我已经创建了新的布局

<config>
<global>
    <page>
        <layouts>
            <category_special translate="label">
                <label>Limited category</label>
                <template>page/limited_category.phtml</template>
                <layout_handle>special_limited</layout_handle>
            </category_special>
        </layouts>
    </page>
</global>

限制类别出现在下拉列表中,我选择了它。 在local.xml中我写了

<special_limited translate="label">
    <label>Category - Limited</label>
    <reference name="content">
        <block type="catalog/category_special" name="category.products" template="catalog/category/special.phtml">

        </block>
    </reference>
</special_limited>

布局是有效的,页面加载了limited_category.phtml模板,但句柄不是。看起来这个页面上的catalog_category_default

2 个答案:

答案 0 :(得分:0)

The answer

如上面的链接所述 - 类别控制器不调用Mage_Page_Helper_Layout :: applyHandle(),因此它的自定义句柄不适用。要修复它,可能会覆盖Mage_Catalog_CategoryController :: viewAction():

public function viewAction(){
   ....
   $this->addActionLayoutHandles();
   $update->addHandle($category->getLayoutUpdateHandle());
   $update->addHandle('CATEGORY_' . $category->getId());
   if ($settings->getPageLayout()) {
            $this->getLayout()->helper('page/layout')->applyHandle($settings->getPageLayout());
        }
   ...
}

答案 1 :(得分:0)

这是大多数Magento开发人员所拥有的常见音乐解释的完美示例。所以我在这里尝试更多的东西。

实际上,CMS页面呈现(例如:主页)和类别页面是唯一呈现它的页面。表示这两个页面手动生成布局更新句柄,然后加载并呈现它们。 Magento的默认行为与这些页面完全不同。这就是Magento处理正常控制器动作的方式。

public function someAction()
{
    $this->loadLayout();
    $this->renderLayout();
}

$this->loadLayout()是生成布局更新句柄然后加载它们的原因。对于CMS页面和类别页面,您可以看到此类调用不存在。相反,他们将通过他们的控制器手动准备布局。我认为我的观点现在更清楚了。

现在让我们来探讨loadLayout()在这里做些什么。

public function loadLayout($handles = null, $generateBlocks = true, $generateXml = true)
{
    // if handles were specified in arguments load them first
    if (false!==$handles && ''!==$handles) {
        $this->getLayout()->getUpdate()->addHandle($handles ? $handles : 'default');
    }

    // add default layout handles for this action
    $this->addActionLayoutHandles();

    $this->loadLayoutUpdates();

    if (!$generateXml) {
        return $this;
    }
    $this->generateLayoutXml();

    if (!$generateBlocks) {
        return $this;
    }
    $this->generateLayoutBlocks();
    $this->_isLayoutLoaded = true;

    return $this;
}

在此方法中,前两行用于生成布局更新句柄。所以让我们专注于这些方面。这是第一行代码。

if (false!==$handles && ''!==$handles) {
    $this->getLayout()->getUpdate()->addHandle($handles ? $handles : 'default');
}

在正常情况下,这将添加default布局更新句柄。现在让我们看看$this->addActionLayoutHandles()做了什么:

public function addActionLayoutHandles()
{
    $update = $this->getLayout()->getUpdate();

    // load store handle
    $update->addHandle('STORE_'.Mage::app()->getStore()->getCode());

    // load theme handle
    $package = Mage::getSingleton('core/design_package');
    $update->addHandle(
        'THEME_'.$package->getArea().'_'.$package->getPackageName().'_'.$package->getTheme('layout')
    );

    // load action handle
    $update->addHandle(strtolower($this->getFullActionName()));

    return $this;
} 

它实际上添加了3种类型的布局更新句柄。他们是

  1. 存储特定的布局更新句柄。例如:STORE_default

  2. 主题&amp;区域特定布局更新句柄。例如:THEME_frontend_rwd_default

  3. 操作布局更新句柄ex:catalog_category_view用于类别页面。

  4. 因此,如果我们结束,在正常情况下,Magento基本上生成4个布局更新句柄 1 它将不会生成 layout_handle 特定布局更新句柄。

    那么 layout_handles 的应用是什么?

    看起来,它们通常被定义为通过布局更新XML文件更新页面布局的快捷方式。即执行此类操作

    <layout>
        <{some_handle}>
            <update handle="page_one_column" />
        </{some_handle}>
    </layout>
    

    除此之外,这些手柄没有特定用途。因此,您不应该使用这些句柄来进行一些布局自定义。为此,您需要使用Magento默认生成的其他布局更新句柄。在我上面指定的4个布局更新句柄中,动作布局udpate句柄应该是进行修改的最佳位置。

    在这种情况下我们可以做什么

    在这种情况下,您的local.xml应该是

    <layout>
        <catalog_category_view>
            <reference name="content">
                <block type="catalog/category_special" name="category.products" template="catalog/category/special.phtml" />
            </reference>
        </catalog_category_view>
    </layout>
    

    因此,您不需要任何重写。您可以通过单个布局udpate xml文件包含块。

    1:默认情况下,Magento会生成其他布局更新句柄。它使用特殊事件controller_action_layout_load_before来执行此操作。