6

問題空間

リクエストのパラメーターに基づいて、特定のリクエストのレイアウト全体を完全に置き換えるために、magento でオブザーバーを使用しようとしています。

私が直面している問題は、Magento がまだ Observer で指定したものとは異なるルート ブロック テンプレートをロードしようとしていることです (具体的には、製品ページの "frontend/base/default/template/page/1column.phtml" です)。バックエンドの [デザイン] タブで構成されたテンプレートによって使用される既定のルート ブロック テンプレート)。指定したレイアウトを使用していないため、テーマに存在しないテンプレートをロードしようとして PHP で停止します。

任意のガイダンスをいただければ幸いです。

注: CMS ページはバックエンドで指定されたとおりに独自のテンプレートをロードするため、この概念をテストするために CMS ページを使用していません。テスト製品を作成し、その製品ページを使用しています。テストは、次の URL を要求することによって行われます。http://mymagentosite.com/test-product?ajax=1

考えられる問題

  • レイアウトを完全に置き換える適切なイベントを聞いていない可能性があります。ドキュメントはまばらなので、レイアウトの質問に対する他のスタック オーバーフローの回答に基づいて推測しました。
  • レイアウト要素のフォルダー構造はブードゥー教のように思えますが、これについてはさまざまな意見があります (例: page.xml と local.xml)。

実装

次のように、オブザーバーと非常に最小限のレイアウトでモジュールを作成しました。

モジュールのフォルダー構造

app
├── code
│   └── local
│       └── MyCompany
│           └── MyModule
│               ├── etc
│               │   └── config.xml
│               └── Model
│                   └── Observer.php
├── design
│   └── frontend
│       └── myTheme
│           └── default
│               ├── layout
│               │   └── local.xml
│               └── template
│                   └── test.phtml
└── etc
    └── modules
        └── MyCompany_MyModule.xml

config.xml

<!-- language: lang-xml -->
<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <MyCompany_MyModule>
            <version>0.1.0.0</version>
        </MyCompany_MyModule>
    </modules>
    <global>
        <events>
            <controller_action_layout_generate_xml_before>
                <observers>
                    <myCompany_myModule_model_observer>
                        <type>singleton</type>
                        <class>MyCompany_MyModule_Model_Observer</class>
                        <method>changeRequestLayout</method>
                    </myCompany_myModule_model_observer>
                </observers>
            </controller_action_layout_generate_xml_before>
        </events>
    </global>
</config>

Observer.php

<!-- language: lang-php -->
<?php

class MyCompany_MyModule_Model_Observer
{
    public function changeRequestLayout($observer)
    {
        if ($observer->getAction()->getRequest()->isAjax()) {
            Mage::getDesign()->setArea('frontend')->setPackageName('myTheme')->setTheme('default');
        }
    }
}

local.xml

<!-- language: lang-xml -->
<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.1.0.0">
    <default>
        <block type="page/html" name="root" output="toHtml" template="test.phtml" />
    </default>
</layout>

test.phtml

<!-- language: lang-html -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Testing, testing...1...2...3...</title>
    <style type="text/css">
        body {
            background-color:#f00;
        }
    </style>
</head>
<body>
    <h1>This is a test of the Magento layout system.  This is only a test.  If this were not a test, real content would follow.</h1>
</body>
</html>

MyCompany_MyModule.xml

<!-- language: lang-xml -->
<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <MyCompany_MyModule>
            <active>true</active>
            <codePool>local</codePool>
        </MyCompany_MyModule>
    </modules>
</config>
4

2 に答える 2

1

controller_front_init_beforeこれは私が構築した実用的なソリューションであり、イベントを介してデザイン パッケージ/テーマを切り替える作業を確実に行います。

もちろん、changeConfigNode()メソッド内のいくつかのリクエスト パラメータをチェックし Mage::app()->getRequest()->getParam('switch')、リクエスト パラメータを追加しswitch/1て変更をトリガーすることもできます。

   <global>
    <events>
        <controller_front_init_before>
            <observers>
                <cartware_change_the_node>
                     <class>cartware_guest2customer/observer</class>
                     <method>changeConfigNode</method>
                </cartware_change_the_node>
            </observers>
        </controller_front_init_before>               
    </events>
   </global>

そしてオブザーバーメソッド:

public function changeConfigNode(){

    /** left for testing
    Mage::log( Mage::app()->getConfig()->getXmlString());
            **/

    Mage::app()->getConfig()->setNode('stores/default/design/package/name', 'enterprise');
    Mage::app()->getConfig()->setNode('stores/default/design/package/theme', 'enterprise');
    Mage::app()->getConfig()->setNode('stores/default/design/package/default_theme', 'enterprise');
    Mage::app()->getConfig()->setNode('stores/default/design/theme/default', 'enterprise');
    Mage::app()->getConfig()->setNode('stores/default/design/theme/layout', 'enterprise');
    Mage::app()->getConfig()->setNode('stores/default/design/theme/template', 'enterprise');



}

追加のチェックはありませんが、役立つかもしれません! 幸運を!

于 2013-07-04T07:13:58.630 に答える
0

本当の問題

Magento の階層化された XML レイアウト システムは、些細なユース ケースであるべきことを達成する際の混乱の原因です。

ベース/デフォルト レイアウト XML は指定したレイアウトと組み合わされるため、ルート レイアウトをオーバーライドするだけでなく、base/default/page.xml で定義された他のすべての派生レイアウトもオーバーライドする必要があります。クライアントが閲覧しているページのタイプに基づいて、Magento が多数のカスタマイズされたレイアウトを定義するため、これは実用的ではありません。

私の解決策

最もクリーンな解決策は、テンプレート/ページ ディレクトリにシンボリック リンクを作成して、次のすべてのレイアウトの test.phtml ファイルを指すようにすることです。これにより、Magento が私のレイアウト テンプレート のみを使用することが保証されます。

注: これを機能させるには、テンプレートのシンボリック リンクを有効にする必要があります (管理者バックエンドで、[システム] > [構成] > [詳細] > [開発者] に移動し、[テンプレートの設定] を展開し、[シンボリック リンクを許可] を [はい] に設定します)。

test.phtml にリンクされているファイル

  • 1column.phtml
  • 2columns-left.phtml
  • 2columns-right.phtml
  • 3columns.phtml
  • 空の.phtml
  • popup.phtml
  • print.phtml
  • リダイレクト.phtml
于 2013-07-17T18:18:00.380 に答える