Question

I've been scouring the net in pursuit of this one. Magento Commerce comes us dry for me. grepping core code, reading Alan Storm, perusing Inchoo, and even finding related questions on SO turn up no answers for me.

With that said, my problem is with a transactional email template that works when processed from the backend but not from the frontend. Here's a snippet:

<td width="100%" colspan="2" align="left">

    <!-- inject products quote table -->
    {{block type="adminhtml/sales_quotation_email" template="sales/quotation/email_quote_items.phtml" inherits=$template quote=$quote salesrep=$salesrep}}

    <!-- inject cross-sell products table -->
    {{block type="adminhtml/sales_quotation_email" template="sales/quotation/email_quote_cross_sells.phtml" inherits=$template quote=$quote salesrep=$salesrep}}

</td>

In the backend, these blocks are rendered as expected. In the front-end, everything above and below these block directives is rendered, but it appears that the directives die in processing when it comes time to render the template. No errors are thrown.

I followed the advice here, but no luck. Originally I tried to use setDesignConfig on the email template model, but that didn't work. I even tried to set the area as an attribute in the directive, but that also did not work. A colleague suggested that I have two copies of the above templates: one set in design/adminhtml and the other design/frontend. I'd rather not have to worry about extra maintenance. Plus, I fear that I'd encounter the same problem if the block type specified in the directive comes from adminhtml. I don't want that solution.

So what am I doing wrong? What do I not understand?

How does Magento resolve the real path to the template, and is a template forced to reside in the area of its parent block?

Help is needed! Thanks.

Was it helpful?

Solution

SOLVED

I found a related post on Magento Commerce that put me back on track. I started dumping out the design configuration in two controllers: 1 in frontend and one in adminhtml. I noticed immediately that theme information was missing in the frontend request. See some sample output from my frontend controller:

Mage_Core_Model_Design_Package Object (
    [_store:protected] => 
    [_area:protected] => frontend
    [_name:protected] => mypackage
    [_theme:protected] => Array
        (
            [layout] => 
            [template] => 
            [skin] => 
            [locale] => mytheme
        )

    [_rootDir:protected] => 
    [_callbackFileDir:protected] => 
    [_config:protected] => 
    [_shouldFallback:protected] => 1 )

Notice that layout, template, and skin are empty in the theme property. When I dumped the design configuration from an adminhtml controller, these properties were set.

So going back to my frontend controller, I added the following line before I instantiated my email template model:


Mage::getDesign()->setArea('adminhtml');
Mage::getDesign()->setTheme('mytheme');

And poof! It worked! My blocks directives were processed and the fully rendered content was returned as expected.

So although my thinking was correct to set the area, that alone wasn't enough. I also has to configure the theme.

I'm happy with the solution. I hope it helps others. But to fully answer this question, I'm still curious if anyone knows why package information is missing from the design configuration during a frontend request. Does it have to do with the block type in the directive coming from adminhtml? That would make sense, because adminhtml has no need to worry about theme information. I just don't know where those decisions would be made in core code. See update below.

UPDATE:

Learned even more since the original post. My question gave a code sample that built a block of a type that came from adminhtml. The path to the template, I thought, was resolving to the front-end, and that was why no template could be found. That wasn't actually the case. An adminhtml block, because of its class naming convention, will look in design/adminhtml/package/default/module for your template.

However, in my particular Magento installation, I have a design override in local.xml that changes the admin theme so that it admin requests check design/adminhtml/package/mytheme/module for templates. And that is where my phtml templates are stored. So on a front-end request, the controller has no clue about this override, and is only building up the design configuration based on what is set in the store configuration for the particular package and theme.

In summary, my call to setTheme() must utilize that modified config data, like so:

Mage::getDesign()->setTheme(
    (string)    Mage::app()
                ->getConfig()
                ->getNode('stores/admin/design/theme/default')
);

I guess that goes to say, then, that a simple call to setArea() would be sufficient for most installations.

Finally, you will need to revert the design configuration changes after your work is done, otherwise subsequent actions might produce undesired results.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top