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 See update below.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.
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.