In Magento Layout XML files, what does as= represent in block declarations - magento

Take my example :
<block type="core/template" name="my.name" as="myName" template="path/to/template.phtml"/>
What purpose does the "as=myName" declaration serve.
What abstract class defines these default attributes for layout handling?

here i can give brief understanding regarding magento block xml tag
name = Name of the block. It should be unique in the page.
**as = Alias **. Smaller form of name. It should be unique in it's parent block.
template = The template file (View) this block is attached to.
You can call methods from block type inside this by using $this.. e.g. $this->getName()
name vs. as example:
<reference name="left">
<block type="block/blocktype1" name="first_block" template="template1.phtml">
<block type="abc/abc" name="ty1" as="common" template="abc.phtml"/>
</block>
<block type="block/blocktype1" name="second_block" template="template2.phtml">
<block type="xyz/xyz" name="ty2" as="common" template="xyz.phtml"/>
</block>
</reference>
So, you can now call block name ty1 from first_block AND ty2 from second_block as $this->getChildHtml('common');, but see both the blocks called will be different as per their calling parent.
for detail class go throw this
Understanding Magento Block and Block Type
hope this will sure help you.

When you use as, you can call $this->getChildHtml("as_value") on the phtml template.
The name must be unique, and can be used for < reference > blocks, < remove >, etc.
For example (catalog.xml):
<block type="catalog/product_view" name="product.info" template="catalog/product/view.phtml">
<block type="catalog/product_view_media" name="product.info.media" as="media" template="catalog/product/view/media.phtml"/>

Related

Updating custom block in CMS page

I'm having a bit of trouble understanding how to update a custom block that I include in a CMS page.
I am using the standard shortcode in the CMS page, which works fine:
{{block type="catalog/product_list" category_id="16"
template="catalog/product/slider_list.phtml"}}
I am trying to set the column count of this custom custom block, for which I've found that I need something like the following piece of code:
<block type="catalog/product_list" name="catalog.product.slider_list"
template="catalog/product/slider_list.phtml">
<action method="setColumnCount"><columns>4</columns></action>
</block>
I'm not exactly sure under which <reference /> block I should place the code... I looked in catalog.xml, and if I try to place it between <reference name="root" />, I do not get the correct behavior.
Thank you.
Edit: use of incorrect terminology; I was calling the block static, where in fact it is a custom block.
if you want to call it on home page where the reference name should be like in your local.xml or any of the xml of your extension. just add it like below
<cms_index_index>
<reference name="content">
// your custom block
<block type="catalog/product_list" name="catalog.product.slider_list"
template="catalog/product/slider_list.phtml">
<action method="setColumnCount"><columns>4</columns></action>
</block>
</reference>
</cms_index_index>
hope this will sure help you.

How can I display a magento block in more than one location?

I'm trying to display the cross sell block in it's normal location as well as at the bottom of the page. There is more than one phtml template file involved so $this->getChildHtml does not work in the second location since the block is setup to only be on the cart.phtml file as of now.
In summary, how can I display the same block in more than one template file? I wan't to place these changes in my local.xml and do not want to modify core Magento template files.
The core layout directive for this block is set up as a child of the checkout.cart block:
<checkout_cart_index translate="label">
<!-- ... -->
<reference name="content">
<block type="checkout/cart" name="checkout.cart">
<!-- ... -->
<block type="checkout/cart_crosssell" name="checkout.cart.crosssell" as="crosssell" template="checkout/cart/crosssell.phtml"/>
</block>
</reference>
</checkout_cart_index>
To add it to the footer, you might need to only establish another parent-child relationship in your local.xml:
<checkout_cart_index>
<reference name="footer">
<action method="insert"><!-- or "append" to add to the end -->
<child>checkout.cart.crosssell</child>
</action>
</reference>
</checkout_cart_index>
This approach relies on the stock page/html/footer.phtml template which contains an empty getChildHtml() call, which causes it to render all child blocks.
Note that the footer block class Mage_Page_Block_Html_Footer has a never-expiring block_html cache lifetime, and it does not evaluate child contents for its cache entry. You may need to disable the cache for this block or rewrite the block class to account for the varied content of the crosssell block.

Magento: Update block position with before/after attribute from local.xml layout reference

I need to append the before attribute to a block via a layout update reference call.
This is my local.xml file:
<?xml version="1.0"?>
<layout version="0.1.0">
<default>
<reference name="content">
<block type="page/html_wrapper" name="content.footer" as="contentFooter" translate="label" after="-">
<label>Content Footer</label>
<action method="setElementId"><value>content-footer</value></action>
<action method="setElementClass"><value>clear</value></action>
</block>
</reference>
</default>
<catalog_category_default>
<reference name="breadcrumbs.container">
<action method="unsetChild"><name>category.title</name></action>
</reference>
<reference name="content">
<block type="catalog/category_view" name="category.title" template="catalog/category/title.phtml" before="content.footer"/>
</reference>
</catalog_category_default>
</layout>
My problem is, on the content block I create a content.footer block that you can assign widgets to in admin. I use after="-" on the content.footer block so in my mind, should put it ALWAYS at the bottom of the content block but this is not the case.
When you view a catalog category and it inserts the category.products block in to the content block, it displays underneath the content.footer block. The only way to make it work is if I redefine it in my local.xml and include all the child blocks in category.products, and set before before="content.footer".
So I thought why can't I use a reference to category.products in the catalog_category_default layout and set the block's before attribute, I tried the following:
<reference name="category.products">
<action method="setBefore"><value>content.footer</value></action>
</reference>
Which had no affect.
I also noticed the setAttribute() function in Mage_Core_Block_Abstract which saw it's just a wrapper for setData() but thought I would try it anyway, still nothing:
<reference name="category.products">
<action method="setAttribute"><key>before</key><value>content.footer</value></action>
</reference>
Is it possible to do what I want? Does before/after only apply to blocks in the same reference?
Layout updates are processed in order of layout update handles. Your block is being added last to content but only for the default LUH. Other handles (catalog_product_view, catalog_category_layered, etc) are processed after this handle.
If you truly need a content footer everywhere and want to make sure that it is the last thing inside of the content div, you should add your block to the root node in the default handle and customize the root templates (directly under page/, e.g. page/1column.phtml) by adding a getChildHtml('your.block') call after the getChildHtml('content') call. This will ensure that your block is always immediately at the end of the content blocks.

Magento: Referencing a custom block does not work

I'm trying to reference a block from an other custom module to add a child block via layout file but it does not work.
The first layout file contains
<catalog_product_view>
<reference name="content">
<block type="core/template" name="tabcontainer" as="tabcontainer"
template="store/tabcontainer.phtml" >
<block type="catalog/product_list_related" name="kitparts"
template="store/product/kitparts.phtml"/>
</block>
</reference>
</catalog_product_view>
and in the second one I try to reference the tabcontainer block
<catalog_product_view>
<reference name="tabcontainer">
<block type="productshippinginfo/productshipping" name="productshippinginfo"
template="productshippinginfo/productshipping.phtml" after="kitparts"/>
</reference>
</catalog_product_view>
but the productshippinginfo block is not displayed while it is definitely included in the layout (using Alan Storm's layoutviewer plugin). If I reference content it is displayed.
What is wrong? Isn't it possible to add a child to a custom block from a custom extension?
Thanks for your help!
(I'm using Magento 1.6.1.0)
[edit]
in tabcontainer.phtml I'm calling <?php echo $this->getChildHtml(); ?>
First of all: Thank you Vinai!
Adding a dependency to control the loading order of my plugins it works!
in File: app/etc/modules/Company_ContentModule.xml
<Company_ContentModule>
<active>true</active>
<codePool>local</codePool>
<depends>
<Company_ContainerModule />
</depends>
</Company_ContentModule>
So the content module is loaded after the container module.
You are close. You just need to add this to you store/tabcontainer.phtml file:
getChildHtml('productshippinginfo'); ?>
The reason blocks that are children of "content" render without a template change is that the "content" block is a core/text_list block. If you look in Mage_Core_Block_Text_List, you will see that in its rendering method (_toHtml()) it renders its children.
You could also add an empty getChildHtml() call to your tabcontainer template to achieve a similar effect as a core/text_list - in fact, if you use getChildHtml('',false,true); you'll get the sorted children (set with before="" and after="" params).
EDIT: adjusted the getChildHtml() call syntax based on OP's comment correct findings that the first param must be an empty string a/o/t a boolean.
In the second layout I think you need to provide the nesting:
<catalog_product_view>
<reference name="content">
<reference name="tabcontainer">
<block type="productshippinginfo/productshipping" name="productshippinginfo"
template="productshippinginfo/productshipping.phtml" after="kitparts"/>
</reference>
</reference>
</catalog_product_view>
In order that maganto picks that up
And because you are doing
<?php echo $this->getChildHtml(); ?>
You do not need to specifically call it by name unless you want it to appear in a particular place in your HTML output.
In order to test if your block is appearing in the page at all add output="toHtml" in you block tag.
<block type="productshippinginfo/productshipping" name="productshippinginfo"
template="productshippinginfo/productshipping.phtml" after="kitparts" output="toHtml"/>

Magento Product Collection Limit via XML

I've got a bestsellers module which I've written and it works great, however I want to be able to change the collection size it returns via the XML, rather than the php/phtml.
Something like this:
<block type="catalog/product_list" name="bestsellers" limit="3"
template="custom/bestsellers.phtml" />
or something like:
<block type="catalog/product_list" name="bestsellers"
template="custom/bestsellers.phtml">
<action method="setLimit">3</action>
</block>
Is this possible?
I'm currently changing the limit via the phtml with:
->setPageSize(3)
->setCurPage(1);
But that is hard coded and nasty, I need to be able to use my phtml file as template for many cases of the bestsellers module being called from anywhere with the XML + limit in the XML.
Thanks in advance if anyone can shed light on this!
The block Mage_Catalog_Block_Product_List inherits from the Varien_Object class which contains the methods getData() and setData(), as well as the magic methods get*() and set*(). These methods allow us to store (you guessed it) keyed-data within an object.
The <action /> tags in the XML allows us to perform method calls on the block instances. You're nearly there with your second example, but the syntax is:
<block type="catalog/product_list" name="bestsellers">
<action method="setLimit"><value>3</value></action>
</block>
Which is equivalent to:
<block type="catalog/product_list" name="bestsellers">
<action method="setData"><key>limit</key><value>3</value></action>
</block>
Which is roughly equivalent to:
$block = new Mage_Catalog_Block_Product_List();
$block->setLimit(3);
With the data set in the object we can now access through the getData() or get*() methods by calling $this->getLimit() or $this->getData('limit') making our block code:
->setPageSize($this->getLimit())
->setCurPage(1);
You should probably perform a check for the existence of the limit data first and provide a default value if none is provided in the XML.
Note: The name of the children in the <action /> tag don't matter. It's the order of the arguments that's important. We could just as well have called <action method="setLimit"><foo>3</foo></action> and it still would have worked.

Resources