【问题标题】:Get frontend PHTML template's output inside a model method in Magento在 Magento 的模型方法中获取前端 PHTML 模板的输出
【发布时间】:2012-08-30 17:36:32
【问题描述】:

简而言之:我想在模型中调用前端块来获取 PHTML 模板的输出。

我有一个 test.phtml 模板,它为我的模块生成特定 HTML 文件的内容。此 HTML 必须仅在管理员请求时生成,因此我在控制器中调用它。该控制器调用模型:

public function generateAction()
{
    Mage::getSingleton('helloworld/sample')->doSomething();
}

模型如下所示:

class My_Helloworld_Model_Sample Mage_Core_Model_Abstract
{
    public function doSomething()
    {
        $templatePath = 'helloworld/test.phtml';
        $output = Mage::app()->getLayout()
            ->createBlock("core/template")
            ->setData('area','frontend')
            ->setTemplate($templatePath)
            ->toHtml();
        //write $output in HTML file
    }
    //...
}

调用block,获取test.phtml模板文件的输出,写入HTML文件。

为什么我不在其中一种模型方法中生成该 HTML?两个原因: - 用户需要能够轻松访问该文件 - .phtml 文件对于用户/设计师来说更具可读性

这就是为什么我想创建一个块来获取它的输出。但问题是,当我尝试创建该块时,出现此错误:

CRIT (2):无效的模板 文件:前端/base/default/template/test.phtml

Magento 在“base”主题中搜索模板。如果我把那个文件放在那里(frontend/base/default/template/test.phtml),那么一切正常。但我想将该模板保留在当前主题的目录中(我保留模块的其余模板文件):

前端/包/主题/template/test.phtml

我怎样才能做到这一点?

编辑:

抱歉,我想简化代码以使其更具可读性。这里是模板文件的实际位置:

前端\默认\现代\模板\mymodule\test.phtml

点击管理面板中的按钮后,控制器调用模型:

public function generateAction()
{
    //Get model and call the method to generate HTML
    Mage::getSingleton('mymodule/sample')->doSomething();
}

模型创建块以获取 test.phtml 模板的输出:

class My_Mymodule_Model_Sample Mage_Core_Model_Abstract
{
    public function doSomething()
    {
        $templatePath = 'mymodule' . DS . 'test.phtml';
        $output = Mage::app()->getLayout()
            ->createBlock("core/template")
            ->setData('area','frontend')
            ->setTemplate($templatePath)
            ->toHtml();
        //write $output in HTML file
    }
    //...
}

到目前为止一切正常。但是创建块时,Magento 找不到模板文件,并给我这个错误:

CRIT (2):无效的模板 文件:前端\ base\default \template\mymodule\test.phtml

在 app/code/core/Mage/Core/Model/Design/Package.php 中添加 Mage::log 后,我在 system.log 文件中获得了此信息:

2012-09-06T09:40:55+00:00 调试 (7): E:\webserver\xampp\htdocs\magento\app\design\ frontend\default\default \template\mymodule\test.phtml 2012-09-06T09:40:55+00:00 调试 (7): E:\webserver\xampp\htdocs\magento\app\design\frontend\default\default\template\mymodule\test.phtml 2012-09-06T09:40:55+00:00 调试 (7): E:\webserver\xampp\htdocs\magento\app\design\frontend\default\default\template\mymodule\test.phtml 2012-09-06T09:40:55+00:00 CRIT (2): 无效模板 文件:前端\base\default\template\mymodule\test.phtml 2012-09-06T09:40:56+00:00 调试 (7): E:\webserver\xampp\htdocs\magento\app\design\adminhtml\default\default\layout\local.xml 2012-09-06T09:40:56+00:00 调试 (7): E:\webserver\xampp\htdocs\magento\app\design\adminhtml\default\default\layout\local.xml 2012-09-06T09:40:56+00:00 调试 (7): E:\webserver\xampp\htdocs\magento\app\design\adminhtml\default\default\layout\local.xml

如果我像这样修改模型方法(注释掉对前端的引用):

class My_Mymodule_Model_Sample Mage_Core_Model_Abstract
{
    public function doSomething()
    {
        $templatePath = 'mymodule' . DS . 'test.phtml';
        $output = Mage::app()->getLayout()
            ->createBlock("core/template")
            //->setData('area','frontend') // <--removed
            ->setTemplate($templatePath)
            ->toHtml();
        //write $output in HTML file
    }
    //...
}

我在 system.log 文件中获得此信息:

2012-09-06T09:44:46+00:00 调试 (7): E:\webserver\xampp\htdocs\magento\app\design\ adminhtml\default\default \template\mymodule\test.phtml 2012-09-06T09:44:46+00:00 调试 (7): E:\webserver\xampp\htdocs\magento\app\design\adminhtml\default\default\template\mymodule\test.phtml 2012-09-06T09:44:46+00:00 调试 (7): E:\webserver\xampp\htdocs\magento\app\design\adminhtml\default\default\template\mymodule\test.phtml 2012-09-06T09:44:46+00:00 CRIT (2): 无效模板 文件:adminhtml\base\default\template\mymodule\test.phtml 2012-09-06T09:44:47+00:00 调试 (7): E:\webserver\xampp\htdocs\magento\app\design\adminhtml\default\default\layout\local.xml 2012-09-06T09:44:47+00:00 调试 (7): E:\webserver\xampp\htdocs\magento\app\design\adminhtml\default\default\layout\local.xml 2012-09-06T09:44:47+00:00 调试 (7): E:\webserver\xampp\htdocs\magento\app\design\adminhtml\default\default\layout\local.xml

Magento 似乎并不关心当前启用的主题,而是在基本主题中搜索模板。有什么方法可以“告诉”Magento 应该使用哪个模板?

【问题讨论】:

    标签: templates magento model module block


    【解决方案1】:

    你已经有了答案,只是你错误地识别了问题。

    Magento 只在base 包中查找当前主题中的文件。所以首先 Magento 会检查

    frontend/package/theme/template/test.phtml
    

    然后它会检查

    frontend/base/default/template/test.phtml
    

    如果它仍然没有找到任何东西,那么它会记录错误。

    如果您想调试 Magento 尝试从中加载初始文件的位置,请将一些临时的 var_dump 或 Mage::Log 调试代码添加到设计包文件中

    #File: app/code/core/Mage/Core/Model/Design/Package.php
    public function validateFile($file, array $params)
    {
        $fileName = $this->_renderFilename($file, $params);
        $testFile = (empty($params['_relative']) ? '' : Mage::getBaseDir('design') . DS) . $fileName;
        if (!file_exists($testFile)) {
            var_dump($testFile);
            Mage::Log($testFile);
            return false;
        }
        return $fileName;
    }
    

    此外,请在此处包含您在系统上使用的实际代码,这样人们将能够更好地为您提供帮助。您所说的将模板路径设置为之间存在差异

    helloworld/test.phtml
    

    你实际设置的是(根据 Magento 错误)

    test.phtml
    

    更新:根据附加日志中的内容,看起来有些东西正在向您的模板路径添加空格,这意味着 Magento 无法在其初始位置找到您的模板

    E:\webserver\xampp\htdocs\magento\app\design\ frontend\default\default \template\mymodule\test.phtml
    ex.
    design\ frontend
    \default \template
    

    另外,我不认为这是根本原因,但不要在模板路径中使用DS。 PHP 会为您解决这个问题。

    【讨论】:

    • 感谢您的回答。似乎 Magento 并不关心当前启用了什么主题,而是在“基本”主题中搜索模板。有什么方法可以“告诉”Magento 应该使用哪个模板(以及模板所在的位置)?
    • @zlitix — 除非您处理的是经过大量修改的系统,否则我认为这是不可能的。再次检查您的名称和路径,并将我建议的日志记录/调试添加到您的设计包中。
    • 在我当前的示例中,路径很好。如果我将模板放在 Magento 期望的位置:frontend\base\default\template\mymodule\test.phtml,那么一切正常。我只是想知道它是否可以改进。 :) 但如果不能,那么当前的解决方案就可以了。非常感谢您的帮助。
    • 我也想知道如何使用此解决方案生成一些 CSS 文件以显示模块的外观。在这种情况下,可以通过管理面板自定义外观。因此,如果我可以动态生成 CSS 文件,而不是使用带有硬编码数十个类的静态 CSS 文件来处理数十种可能的情况,那将非常有用。 您可能知道更好的方法吗? 可以比我的怪异和违反直觉的代码更快更简单地完成吗?
    • Alan 的回答为我指明了正确的方向,尽管在渲染模板之前我仍然必须在下面添加 sn-p:Mage::getDesign()-&gt;setArea('frontend')-&gt;setPackageName((string) Mage::getConfig()-&gt;getNode('stores/default/design/package/name')); 这是因为管理员前端控制器设置了将设计上的 packageName 设置为它的预调度例程中的“默认”,如果您使用的包名称与“默认”不同,就像我的情况一样,它将不起作用(Mage_Adminhtml_Controller_Action 第 148 行)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多