Set template in layout handle for Adminhtml - magento

In the backend of my Magento Webshop I want to set a template for the blocks of System->Config. Therefore I use the layout handle of the Mage_Adminhtml_System_ConfigController which is adminhtml_system_config_index I think. The problem is, nothing happens. Even if want to remove blocks, nothing happens:
<adminhtml_system_config_index>
<reference name="left">
<action method="setTemplate">
<template>myModule/template.phtml</template>
</action>
</reference>
</adminhtml_system_config_index>
OR removing block:
<adminhtml_system_config_index>
<remove name="left" />
</adminhtml_system_config_index>
What am I doing wrong? I even tried system_config_index as layout handle.

You're doing three possible things wrong here.
First Tip: Are you editing the right XML file?
A lot of common layout problems come from the XML file you're editing not being the XML file that's loaded by the system. Switch on developer mode in your site, set display_errors to 1, and then deliberately introduce a non well formed error into your XML files and try to load the page.
<!-- note the trailing greater than sign at the end -->
<adminhtml_system_config_index>
...
</adminhtml_system_config_index> >
If the page loads without error, then you're not loading the XML file you think you are.
Second Tip: Are you using the correct layout handle?
I'm not sure you are. Despite the fact the default system configuration page uses the index action, this action actually forwards the page to the edit action.
#File: app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php
public function indexAction()
{
$this->_forward('edit');
}
Forwarding means there's an internal redispatch, but no http redirect. That means your actual handle is
`adminhtml_system_config_edit`
This is why I use (disclaimer: and built, and sell) Commerce Bug. The Layout tab always displays the current handles, and I can avoid making assumptions that send me down the wrong path.
Third Tip: Are you confusing the block named left with the left hand column?
In general, Magento's container blocks (left, content, right, etc.) are not template blocks. Instead they're container blocks (text/list blocks to be precise) that hold and multiple template blocks.
This is another place I use Commerce Bug, specifically the new Graphviz feature. This will show you the block structure for any particular page. In a factory default system, you'd see something like this for the System Configuration page
As you can see, the left block has no template, so changing its template will have no effect. The block you probably want is left.child1.
Fourth Tip: Is the block you're trying to modify added by the layout XML.
Without getting too deeply into layout rendering (which would take a book), there are some block which are added after the layout generates all its blocks. If this is the case, your block will not be available in layout XML files.
If you look at the editAction method, you can see that the tabs block is added after loadLayout is called (look for adminhtml/system_config_tabs). This means it won't be available in layout xml files.
public function editAction()
{
//...
//the `loadLayout` method call creates blocks based on layout XML files
$this->loadLayout();
$this->_setActiveMenu('system/config');
$this->getLayout()->getBlock('menu')->setAdditionalCacheKeyInfo(array($current));
$this->_addBreadcrumb(Mage::helper('adminhtml')->__('System'), Mage::helper('adminhtml')->__('System'),
$this->getUrl('*/system'));
//this line add the `child1` block to the layout. (child one is the
//name chosen since the block has no explicit name
$this->getLayout()->getBlock('left')
->append($this->getLayout()->createBlock('adminhtml/system_config_tabs')->initTabs());
//...
This means you can't modify the template of this block from a layout XML file. You'll need to use a custom module that listens for an appropriate event and then makes your changes via PHP. I'd try the event controller_action_layout_render_before or controller_action_layout_render_before_adminhtml_system_config_edit with PHP code that looks something like
$block = Mage::getSingleton('core/layout')->getBlock('child1');
if($block)
{
$block->setTemplate('foo.phtml');
}

Related

Can somebody give me an eagle eye perspective on Magento blocks, layout and templates?

Can somebody give me an eagle eye perspective on Magento blocks, layout and templates and how they relate to each other?
I understood that blocks are the basic building-blocks that a page is made of and that they are kind of mini-controllers.
I also understood that layout brings these blocks somehow together.
But there is still some uncertainty about templates and how they relate to blocks and layouts and vice versa.
What are blocks?
There are basically 4 things you need to know:
There are two types of blocks: those that automatically render their
children and those that don't. Knowing which type you're using will
help you in debugging.
Magento blocks are essentially models that contain logic for your view templates. Mind you - this is not business logic, but it is logic
related to the display of the information you're presenting. This is
by definition presentational logic. If you're familiar with Zend
Framework's Zend_Layout you could draw a comparison between custom
view objects and layout helpers.
The template file assigned to a block object can execute code as if it is local to that object. That is, $this corresponds directly to
the block class.
Layout actions are a thing that people use.
Two types of blocks
There are two types of blocks at the end of the day - those that
render automatically and those that don't. Take notes because this is
on the Magento Certification exam!!
Auto-rendered blocks
When defined in a layout, any block of type core/text_list will
automatically render all its children. While core/text will
automatically render itself it really only should contain text and
therefore is not useful for layout purposes (though some clever things
can be achieved with them).
Other blocks
Any other block type will need to be rendered manually. Provide the
block an alias which can then be passed to getChildHtml, returning the
content which you then echo.
Layouts And Templates
As the name suggests, layout files are useful in rendering front pages
of Magento. Layout files are XML files that reside in in app > design
frontend > your interface > your theme > layout. Here, you can see that there are many layout files for any given module. Each Magento
module has its own layout files much like the customer module has the
customer.xml layout file, catalog module have catalog.xml layout file
etc. These layout files contain structural blocks and content blocks.
read the following blogs. it will clear your concepts for magneto.
http://alanstorm.com/category/magento
http://devdocs.magento.com/guides/m1x/magefordev/mage-for-dev-4.html
http://blog.philwinkle.com/the-most-misunderstood-concept-in-magento/
http://code.tutsplus.com/tutorials/custom-layouts-and-templates-with-magento--cms-21419
Blocks are the building modules of a page. They can be treated as "bricks". Now every block comes inside a layout. Layout is used to define the "shape" of the page. Now templates are used to define the behaviour of a particular block. That means each block or "brick" will have different charateristic depend upon the template it is used.
That is, to construct a magento page, you need to define a layout first that will give you an idea of shape of that page. Now you fill the layout with blocks. Each blocks now concentrate on a particular section of the entire layout. That means depending upon the "nature" of block, each small section will behave differently. To define the unique nature of a particular section, blocks uses templates (templates actually holds the webpage building codes, ie html + js + php)
I hope that will give you a short idea.
Try to google this. I am sure there are lot of lot of tutorials, blogs available about this.

Magento get which layout being used on phtml files

Is there a way I could get which layout being used on a certain phtml files?
Here in my case, I want to check what layout being used on catalog/list.phtml, I used that information to make conditional "if" on the product image grid size.
I've tried to google it out. But all the result is just explaining about xml layout things. The closest clue I got is this thread
Magento get layout for given page
which stated the use of this snippet
$left_block = $this->loadLayout()->getLayout()->getBlock('left');
but when I tried it on the phtml files, I got an exception error
UPDATE
joe's answer below has give me some more clue, the exception gone. But the behavior doesn't really what I need. That snippet of code seems to be just check whether the specified block is defined on the XML. What I really need is whether that block exist on a certain page.
In my case, I need to check what layout being used on catalog/product/list.phtml. if it's 3 columns, I'm gonna make the image resized smaller. If it 1 column, I'll make it bigger.
Is there any way I could do that??
If I read the question correctly, then try:
$this->getLayout()->getBlock('root')->getTemplate();
Remove loadLayout():
$left_block = $this->getLayout()->getBlock('left');
By the time you are in the PHTML file, the layout is already loaded.
In PHTML files, $this refers to the Mage_Core_Block_Template class (or a class that extends it). This class doesn't have a loadLayout() method defined, which is why you get an exception; instead, loadLayout() is part of Mage_Core_Controller_Varien_Action.

Magento - conditionals in layout files

Is it possible in Magento to conditionally add blocks into a layout xml file?
Im thinking along the lines of having an admin config option checkbox - if checked then a block needs to be added to the page and vice versa if not checked.
I could think of a way of doing this via code but not the actualy layout file system itself.
The ifconfig paramater can be used to conditionally call an action method
<action method="someBlockMethod" ifconfig="path/to/config"><param1>value</param></action>
The path/to/config path is passed to Mage::getStoreConfigFlag() to return a boolean.
I'd try using this in combination with the insert method
<action method="insert" ifconfig="path/to/config"><param>block_name</param></action>
The block with the name or alias of block_name will need to be already inserted into the layout object by other PHP or XML, so you may need to take additional steps to unset it from its original blocks after inserting it into your new block.
you can try this (i haven't tried it myself):
<action ifconfig='your/extension/active'

Magento xml layouts - before="-" not working in 1.4.2

I have some custom extensions. They're shown in the right sidebar, and I previously had them appearing directly underneath the sidebar cart, which appears at the top, as it has before="-" in the checkout.xml file.
Since upgrading to 1.4.2, my custom extensions now appear at the top of the sidebar. I've added after="cart_sidebar" to the extensions xml layouts, but they still appear above the sidebar cart regardless.
Changing the order of the extensions, they only move amongst themselves, always at the top - for example, if I add after="-" to any of them, they just appear after the other custom extensions, but still at the top above the cart and other default sidebar items.
Anyone any idea why?
UPDATE:
I turned on the "Template Path Hints", and for my custom sidebar blocks, the red text showing the template paths appears further down the sidebar, where the block should be showing, but the actual html of the block is appearing at the top of the sidebar still!
Before trying to find out what's happening in here you should notice following:
All Magento modules and extensions are loaded in such an order that they meet their declaration section requirements (xmls in app/etc/modules/). So that modules that depend on other modules are loaded only after them.
If modules are equal by their needs, then priority goes to 'Mage' namespace, then to custom modules namespaces. Inside namespaces priority is given by alphabetical order.
Module layout configuration is created during module load. So result of "before" and "after" instructions depends on blocks already added by previously loaded modules. I.e. when some block has 'before="-"' instruction - it places block first, but later other blocks from next modules can use their instructions to be attached before this block.
Now let's return to your case. Your problem can have multiple reasons heavily depending on your Magento configuration.
First of all I recommend to
Turn off whole cache - so that you'll see all changes instantly
Turn off all your extensions and test things only with one of them
Turn on default Magento CE theme and skin ("default" package)
Then check following cases:
Maybe your layout scheme is modified and your extension not referencing correct block (same as "cart_sidebar" uses) to put self in.
Maybe some extension deletes original cart_sidebar block and then puts it last in queue of blocks.
Maybe some CSS or JS rules place block only visually before other blocks (check blocks order in original html source)
Maybe some extension is modifying layout composition rules. Try to turn only one of them. Then try to turn only other one and check result.

how to call functions/methods within CMS block or page?

We are trying to make all our blocks and pages static so that designer or anyone else can easily change the content or design of the website, however. There is a feature that uses our own custom module. So, the template that we want to make static is calling methods out of our custom block, for example,
<!--some html code-->
.....
<?php $this->helpMeBePartOfCMS(); ?>
.....
<!--some html code-->
How do i incorporate these method calls inside cms block or page?
Thank you
The CMS system makes it easy to include custom blocks (or widgets in Enterprise), but not so easy to make method calls. This is because the templates are never parsed as PHP, so you cannot just include a PHP tag.
Why don't you define a custom block to accomplish this? If that won't work, please provide a little more detail about what you're actually trying to include, so that we can troubleshoot further.
Hope that helps!
Thanks,
Joe
Since CMS block templates are not parsed as PHP code, there's no way to inject a call as you are describing. However, all classes descending from Mage_Core_Block_Abstract have the ability to call child and parent blocks. Use one of these methods to do what you are looking for from the block directly:
getParentBlock
getChild
getSortedChildren
there is a way that you call these php codes in any phtml file (create a new and save any where in your templates) then call that phtml file in your cms page as a block (which we usually do for calling blocks)

Resources