简体   繁体   中英

Get frontend PHTML template's output inside a model method in Magento

In short: I want to call a frontend block inside a model to get the output of the PHTML template.

I have a test.phtml template which generates content of a specific HTML file for my module. This HTML has to be generated only on administrator request so I call it inside a controller. And that controller calls model:

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

Model looks like this:

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
    }
    //...
}

It calls block, gets the output of the test.phtml template file and writes it in HTML file.

Why I don't generate that HTML inside one of the models methods? Two reasons: - user needs to have easy access to that file - .phtml file is much more readable for user/designer

That's why I want to create a block to get its output. But the problem is that when I try to create that block, I get this error:

CRIT (2): Not valid template file:frontend/ base/default /template/test.phtml

Magento searches for the template inside the "base" theme. If I put that file there ( frontend/base/default/template/test.phtml ), then all works fine. But I'd like to keep that template inside the current theme's directory (where I keep the rest of the module's template files):

frontend/ package/theme /template/test.phtml

How could I achieve this?

EDIT:

I'm sorry, I wanted to simplify the code to make it more readable. Here's where the template file is actually located:

frontend\\default\\modern\\template\\mymodule\\test.phtml

After the button in the admin panel is clicked, controller calls model:

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

Model creates block to get output of the test.phtml template:

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
    }
    //...
}

Until now all works fine. But when the block is created, Magento can't find the template file, and gives me this error:

CRIT (2): Not valid template file:frontend\\ base\\default \\template\\mymodule\\test.phtml

After I added Mage::log in app/code/core/Mage/Core/Model/Design/Package.php, I got this info in the system.log file:

2012-09-06T09:40:55+00:00 DEBUG (7): E:\\webserver\\xampp\\htdocs\\magento\\app\\design\\ frontend\\default\\default \\template\\mymodule\\test.phtml 2012-09-06T09:40:55+00:00 DEBUG (7): E:\\webserver\\xampp\\htdocs\\magento\\app\\design\\frontend\\default\\default\\template\\mymodule\\test.phtml 2012-09-06T09:40:55+00:00 DEBUG (7): E:\\webserver\\xampp\\htdocs\\magento\\app\\design\\frontend\\default\\default\\template\\mymodule\\test.phtml 2012-09-06T09:40:55+00:00 CRIT (2): Not valid template file:frontend\\base\\default\\template\\mymodule\\test.phtml 2012-09-06T09:40:56+00:00 DEBUG (7): E:\\webserver\\xampp\\htdocs\\magento\\app\\design\\adminhtml\\default\\default\\layout\\local.xml 2012-09-06T09:40:56+00:00 DEBUG (7): E:\\webserver\\xampp\\htdocs\\magento\\app\\design\\adminhtml\\default\\default\\layout\\local.xml 2012-09-06T09:40:56+00:00 DEBUG (7): E:\\webserver\\xampp\\htdocs\\magento\\app\\design\\adminhtml\\default\\default\\layout\\local.xml

If I modify the model method like this (comment out reference to frontend):

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
    }
    //...
}

I get this info in the system.log file:

2012-09-06T09:44:46+00:00 DEBUG (7): E:\\webserver\\xampp\\htdocs\\magento\\app\\design\\ adminhtml\\default\\default \\template\\mymodule\\test.phtml 2012-09-06T09:44:46+00:00 DEBUG (7): E:\\webserver\\xampp\\htdocs\\magento\\app\\design\\adminhtml\\default\\default\\template\\mymodule\\test.phtml 2012-09-06T09:44:46+00:00 DEBUG (7): E:\\webserver\\xampp\\htdocs\\magento\\app\\design\\adminhtml\\default\\default\\template\\mymodule\\test.phtml 2012-09-06T09:44:46+00:00 CRIT (2): Not valid template file:adminhtml\\base\\default\\template\\mymodule\\test.phtml 2012-09-06T09:44:47+00:00 DEBUG (7): E:\\webserver\\xampp\\htdocs\\magento\\app\\design\\adminhtml\\default\\default\\layout\\local.xml 2012-09-06T09:44:47+00:00 DEBUG (7): E:\\webserver\\xampp\\htdocs\\magento\\app\\design\\adminhtml\\default\\default\\layout\\local.xml 2012-09-06T09:44:47+00:00 DEBUG (7): E:\\webserver\\xampp\\htdocs\\magento\\app\\design\\adminhtml\\default\\default\\layout\\local.xml

It seems that Magento doesn't care what theme is currently enabled and searches for the template in base theme. Is there any way to "tell" Magento which template should be used?

You've already have the answer, you've just misidentified the problem.

Magento only looks in the base package once it's looked for a file in the current theme. So first Magento will check

frontend/package/theme/template/test.phtml

THEN it will check

frontend/base/default/template/test.phtml

and if it still doesn't find anything, then it logs the error.

If you want to debug where Magento is trying to load the initial file from, add some temporary var_dump or Mage::Log debugging code to the design package file

#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;
}

Also, include the actual code you're using on your system here and people will be better able to help you. There's a discrepancy between what you say you're setting your template path as

helloworld/test.phtml

and what you're actually setting is as (per the Magento errors)

test.phtml

Update : Based on what's in the additional logging, it looks like something is adding spaces to your template path, which means Magento can't find your template in it's initial location

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

Also, I don't think it's the root cause, but don't use DS in template paths. PHP will take care of that fore you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM