Magento: Add child block programmatically - magento

I have this block in layout file:
<block type="core/template_facade" name="product.info.container2" as="container2">
<action method="setDataByKey"><key>alias_in_layout</key><value>container2</value></action>
<action method="setDataByKeyFromRegistry"><key>options_container</key><key_in_registry>product</key_in_registry></action>
<action method="append"><block>product.info.options.wrapper</block></action>
<action method="append"><block>product.info.options.wrapper.bottom</block></action>
</block>
And this block:
$item_block = Mage::getSingleton('core/layout')->createBlock('catalog/product_list','item')->setTemplate('sns/ajaxcart/catalog/product/item.phtml')->setData('product', $product);
How do I have the upper block as $item_block's child programmatically? I know it should be something like:
$upper_block = <create upper block>;
$item_block->setChild('somealias',$upper_block);
However, the upper block seems to be too complicate for me to know how to create it programmatically. Please help!

On the block level you can do it like this:
protected function _prepareLayout()
{
$block = $this->getLayout()->createBlock('catalog/product_list')
$this->setChild('items', $block);
return parent::_prepareLayout();
}

Try this
$upper_block = Mage::getSingleton('core/layout') ->createBlock('core/template_facade', "product.info.container2");
$upper_block->setDataByKey('alias_in_layout', 'container2');
$upper_block->setDataByKeyFromRegistry('options_container', 'product');
$upper_block->append('product.info.options.wrapper');
$upper_block->append('product.info.options.wrapper.bottom');
$item_block = Mage::getSingleton('core/layout')->createBlock('catalog/product_list','item')->setTemplate('sns/ajaxcart/catalog/product/item.phtml')->setData('product', $product);
$item_block->setChild('somealias',$upper_block);

Related

Magento how to define layout handle for all controller

Im looking for solution to define layout handle for whole controller insteat of controller_action. For example i want to define:
<mymodule_index></mymodule_index>
instead of
<mymodule_index_index></mymodule_index_index>
<mymodule_index_someaction></mumodule_index_someaction>
Thanks.
You can add a layout handle by running this :
$update = $this->getLayout()->getUpdate();
$update->addHandle('mymodule_index')
You can then add this piece of code to a protected "_initHandles" function within your controller that you would run for every action.
In my controller I've (re)implemented this method
public function loadLayout($handles = null, $generateBlocks = true, $generateXml = true)
{
return parent::loadLayout(array('default','mymodule_index'),$generateBlocks,$generateXml);
}
which will add an update handle called mymodule_index (not loosing the default one) for every controller's action.
You'll need to call loadLayout() in every controller's action, but that's how magento works...
please try below code....
public function indexAction(){
{
...
$update = $this->getLayout()->getUpdate();
$update->addHandle('mymodule_index');
$this->loadLayoutUpdates();
$this->generateLayoutXml()->generateLayoutBlocks();
$this->renderLayout();
}
public function samelocationAction(){
{
...
$update = $this->getLayout()->getUpdate();
$update->addHandle('mymodule_index');
$this->loadLayoutUpdates();
$this->generateLayoutXml()->generateLayoutBlocks();
$this->renderLayout();
}
I've found solution. In each next update you must provide <update handle="" /> like this:
<companies_catalog>
<label>Companies (All Pages)</label>
<reference name="root">
<action method="setTemplate"><template>page/2columns-left.phtml</template></action>
</reference>
<reference name="left">
<block type="businesscategory/companies_navigation" name="companies.navigation" before="-" template="businesscategory/companies/navigation.phtml" />
</reference>
</companies_catalog>
<companies_catalog_index>
<label>Companies (All Pages)</label>
<update handle="companies_catalog" />
<reference name="content">
<block type="businesscategory/companies_list" name="companies.list" template="businesscategory/companies/list.phtml" />
</reference>
</companies_catalog_index>
<companies_catalog_view>
<label>Company page</label>
<update handle="companies_catalog" />
<reference name="content">
<block type="businesscategory/companies_view" name="company.info" template="businesscategory/companies/view.phtml" />
</reference>
</companies_catalog_view>

where is this method doing in admin controller (Grid Serializer)?

<?php
class Excellence_Manager_Adminhtml_ManagerController extends Mage_Adminhtml_Controller_action
{
public function customerAction(){
$this->loadLayout();
$this->getLayout()->getBlock('customer.grid')
->setCustomers($this->getRequest()->getPost('customers', null));
$this->renderLayout();
}
I am following this grid serializer tute . I just can not understand where is this setCustomers coming from ?
Even in other tutes I saw that setClent(), setDog() etc. But where is get or it's not from the database either. not in the layout either I think. Please help thanks.
<manager_adminhtml_manager_customer>
<block type="core/text_list" name="root" output="toHtml">
<block type="manager/adminhtml_manager_edit_tab_grid" name="customer.grid"/>
<block type="adminhtml/widget_grid_serializer" name="grid_serializer">
<reference name="grid_serializer">
<action method="initSerializerBlock">
<grid_block_name>customer.grid</grid_block_name>
<data_callback>getSelectedCustomers</data_callback>
<hidden_input_name>links[customers]</hidden_input_name>
<reload_param_name>customers</reload_param_name>
</action>
<action method="addColumnInputName">
<input_name>position</input_name>
</action>
</reference>
</block>
</block>
I found it's not from hidden_input_name or reload_param_name.
__set() is run when writing data to inaccessible properties.
__get() is utilized for reading data from inaccessible properties.
Magento implements so called "Magic Methods" to set data in an object.
They implemented __set and __get which are called, when no method for e.g. setCustomers() is found, and use those methods to do setData('customers', "YOUR_VALUE");

Pager toolbar in custom module in magento

I use this tutorial and display products on the basis of multiple categories but now I am getting in issue is that the pager tool bar not working on that.
My block code is :
<reference name="content">
<block name="mymodule" type="mymodule/product_listcategories" template="catalog/product/list.phtml">
<action method="setCategories">
<ids>2,3,4</ids>
</action>
</block>
</reference>
I also add this code with above
<block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
<block type="page/html_pager" name="product_list_toolbar_pager"/>
</block>
<action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
</block>
It display toolbar but the toolbar is not working (limit,orderby).
My block code is
class Mymodule_Block_Product_Listcategories extends Mage_Catalog_Block_Product_List
{
protected function _getProductCollection()
{
$this->_productCollection = Mage::getModel('catalog/product')->getCollection();
$this->_productCollection->addAttributeToSelect('*');
if($this->getCategories()!="")
$this->_productCollection->addCategoriesFilter($this->getCategories());
return $this->_productCollection;
}
}
}
Does anyone know where is the problem? I think I'm missing some code for the pager? Thanks in advance
After search so much i got a solution.I didn't know whether it right or wrong way but it solve my problem.On my block i create intance of
$cpBlock = $this->getLayout()->getBlockSingleton('Mage_Catalog_Block_Product_List_Toolbar');
and access the pager core function like $this->_itemPerPage = $cpBlock->getLimit(); .In the above code itemperpage is the total no of items to be displayed on listing page.This code work if you create custom module and extend you block from list block.Thanks

Specific category layout update, custom product collection - missing toolbar?

In local.xml, I created a layout update so I can display a custom filtered product collection.
This is in local.xml:
<CATEGORY_7>
<block type="catalog/category_view" name="category.products" template="catalog/category/view.phtml">
<block type="catalog/product_list" name="product_list" template="catalog/product/cashcrop.phtml">
<block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
<block type="page/html_pager" name="product_list_toolbar_pager"/>
</block>
<action method="addColumnCountLayoutDepend"><layout>empty</layout><count>6</count></action>
<action method="addColumnCountLayoutDepend"><layout>one_column</layout><count>5</count></action>
<action method="addColumnCountLayoutDepend"><layout>two_columns_left</layout><count>4</count></action>
<action method="addColumnCountLayoutDepend"><layout>two_columns_right</layout><count>4</count></action>
<action method="addColumnCountLayoutDepend"><layout>three_columns</layout><count>3</count></action>
<action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
<action method="setColumnCount"><columns>4</columns></action>
</block>
</block>
</CATEGORY_7>
The template file is a copy of list.phtml, but modified to filter the collection:
<?php
$_productCollection = Mage::getModel('catalog/product')->getCollection();
//$_productCollection=$this->getLoadedProductCollection();
$_productCollection
->addAttributeToSelect('*')
//->addAttributeToFilter('status', 1)
//->addAttributeToFilter('visibility', 4)
->addAttributeToFilter('randament', array('in' => array(101, 102)))
->load()
;
$this->setCollection($_productCollection);
$_helper = $this->helper('catalog/output');
?>
This works, I get 105 products in the collection. The problem is the toolbar - it is not being shown. Has anyone any idea why the toolbar is not shown? (I know this <?php echo $this->getToolbarHtml(); ?> return an empty string, but I don't understand why.
Any help appreciated.
Cheers,
Michael.
You don't need to re-initialize everything. Try this and see if it works:
<CATEGORY_7>
<reference name="product_list">
<action method="setTemplate">
<tpl>catalog/product/cashcrop.phtml</tpl>
</action>
</reference>
</CATEGORY_7>
Also, I would be wary of using auto-increment data in scripts or layout files. I'd be inclined to put this in the layout update for the category in the DB. May not be a concern for your environment, but the 7 is an arbitrary feature from the storage backend as opposed to something that is more meaningful, such as the category name.
Actually, I figured it out myself. Overriding the template is fine, and it's enough if placed in the category's Custom Layout Update section; no need to place it in local.xml.
The trouble is with the _beforeHtml() function in Mage/Catalog/Block/Product/List.php, where the toolbar is being initialized by the blocks' _getProductCollection() function which always returns an empty collection, because it tries to obtain the current category's product collection.
So as a quick and dirty fix, I simply copied the code from _beforeHtml() function, and inserted it directly in my cashcrop.phtml template. The top of the template looks like this now:
<?php
$_productCollection = Mage::getModel('catalog/product')->getCollection();
$_productCollection->addAttributeToSelect('*')
->addAttributeToFilter('randament', array('in' => array(101, 102)))
->addAttributeToFilter('inflorire', array('in' => array(97)))
->addMinimalPrice()
->addFinalPrice()
->addTaxPercents();
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($_productCollection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($_productCollection);
$_helper = $this->helper('catalog/output');
$toolbar = $this->getToolbarBlock();
$collection = $_productCollection;
// use sortable parameters
if ($orders = $this->getAvailableOrders()) {
$toolbar->setAvailableOrders($orders);
}
if ($sort = $this->getSortBy()) {
$toolbar->setDefaultOrder($sort);
}
if ($dir = $this->getDefaultDirection()) {
$toolbar->setDefaultDirection($dir);
}
if ($modes = $this->getModes()) {
$toolbar->setModes($modes);
}
// set collection to toolbar and apply sort
$toolbar->setCollection($_productCollection);
$this->setChild('toolbar', $toolbar);
Mage::dispatchEvent('catalog_block_product_list_collection', array(
'collection' => $_productCollection
));
$_productCollection->load();
?>
I am aware this may not be the ideal solution, but it's working. If anyone else has a better solution, I would love to hear about it.
Cheers,
Michael.

Add a calendar in Magento frontend

How can I add a calendar popup in the Magento frontend for a custom form?
Just add this code in your indexAction():
$this->loadLayout();
$blockCal = $this->getLayout()->createBlock(
'Mage_Core_Block_Html_Calendar',
'html_calendar',
array('template' => 'page/js/calendar.phtml')
);
$this->getLayout()->getBlock('content')->append($blockCal);
$headBlock = $this->getLayout()->getBlock('head');
$headBlock->addJs('calendar/calendar.js');
$headBlock->addJs('calendar/lang/calendar-en.js');
$headBlock->addJs('calendar/calendar-setup.js');
you can also define it in a layout file like this:
<reference name="head">
<action method="addItem"><type>js_css</type><name>calendar/calendar-win2k-1.css</name><params/><!--<if/><condition>can_load_calendar_js</condition>--></action>
<action method="addItem"><type>js</type><name>calendar/calendar.js</name><!--<params/><if/><condition>can_load_calendar_js</condition>--></action>
<action method="addItem"><type>js</type><name>calendar/calendar-setup.js</name><!--<params/><if/><condition>can_load_calendar_js</condition>--></action>
</reference>

Resources