Set Block Status from xml and show if its enabled - magento

Created CMS > Block and display it on product page as tabs following this tutorial
app/design/frontend/[theme]/default/layout/catalog.xml
<block type="catalog/product_view_attributes" name="product.sizes" as="sizes" template="catalog/product/view/sizes.phtml">
<action method="addToParentGroup"><group>detailed_info</group></action>
<action method="setTitle" translate="value"><value>Size Guide</value></action>
</block>
From the above code, block title is set from admin and it will be shown as product tab even if its disabled from admin end.
How can we show block only if its enabled from admin and check using
some IF condition in xml ?
Also is it possible to show the title given from admin end rather than setting it from XML file ?

Declare an observer of controller_action_layout_load_before event in config.xml.
<controller_action_layout_load_before>
<observers>
<namespace_module_model_observer>
<class>Namespace_Module_Model_Observer</class>
<method>setHandle</method>
</namespace_module_model_observer>
</observers>
</controller_action_layout_load_before>
Define observer.
class Namespace_Module_Model_Observer
{
public function setHandle(Varien_Event_Observer $observer)
{
if (!Mage::getModel('cms/block')->load('cms_block_identifier')->getIsActive()) {
Mage::app()->getLayout()->getUpdate()->addHandle('your_handle_name');
}
}
}
Add handle to layout xml file.
<?xml version="1.0"?>
<layout version="0.1.0">
<your_handle_name>
<reference name="product.info">
<remove name="product.sizes" />
</reference>
</your_handle_name>
</layout>

Related

Is there any way to modify this tracking.phtml on magento admin?

When we choose one of the option below, the field 'title' automatically filled with selected value from carrier options.
I want to do the same for 'number' field, it would be filled with something when I choose my custom carrier. Is there any way to modify this tracking form? If yes, how?
Thank's in advance
Add following observer in your module's config.xml
<events>
<adminhtml_block_html_before>
<observers>
<add_script_on_shipment>
<class>yourmodule/observer</class>
<method>addScript</method>
</add_script_on_shipment>
</observers>
</adminhtml_block_html_before>
</events>
Put following code in Observer.php
public function addScript($observer) {
$block = $observer->getEvent()->getBlock();
if (($block instanceof Mage_Adminhtml_Block_Sales_Order_Shipment_View_Tracking) && $block->getType() != 'core/template' /*&& is your carrier active*/) {
$shipment = $block->getShipment();
$_child = clone $block;
$_child->setType('core/template');
$block->setChild('calling_block', $_child);
$block->setTemplate('yourmodule/custom_script.phtml');
}
}
add following code with required modifications in custom_script.phtml
<?php echo $this->getChildHtml('calling_block');?>
<script type="text/javascript">
/*your custom javascript code to bind onchange event*/
</script>
Look in the file app/design/adminhtml/default/default/layout/sales.xml, tracking.phtml is used several times. If this change is for a module then create a layout file 'yourmodule.xml' and enable it from your config file. Otherwise name it 'local.xml'. It's contents will have to be an update something like this:
<?xml version="1.0"?>
<layout>
<adminhtml_sales_order_shipment_new>
<reference name="shipment_tracking">
<action method="setTemplate">
<template>your/new/tracking.phtml</template>
</action>
</reference>
</adminhtml_sales_order_shipment_new>
</layout>
Also if you want to minimize number of copypasted layout statements you can use
<update handle="handle_name" /> inside different controller action handles. For example:
<my_handle_name>
<reference name="shipment_tracking">
<action method="setTemplate">
<template>your/new/tracking.phtml</template>
</action>
</reference>
</my_handle_name>
<adminhtml_sales_order_shipment_new>
<update handle="my_handle_name"/>
</adminhtml_sales_order_shipment_new>

Magento second header

I have a Magento store with two separate headers. Let's say out of 20 pages 15 use header.phtml and 5 use headerGreen.phtml. I've already created my custom layout module however I can't seem to get the new header to appear on select pages. The new headerGreen.phtml file has been created as well. The issue lies when I try to call the new header in the newly created layout page.
<?php echo $this->getChildHtml('headerGreen') ?>
I dont think I've added it correctly to the local.xml and was hoping someone could help.
<default>
<reference name="header">
<block type="core/template" name="header" template="page/headerGreen.phtml" />
</reference>
</default>
The function getChildHtml is expecting you to send a name of a child in the layout as first parameter
app/code/core/Mage/Core/Block/Abstract.php defines it :
/**
* Retrieve child block HTML
*
* #param string $name
* #param boolean $useCache
* #param boolean $sorted
* #return string
*/
public function getChildHtml($name = '', $useCache = true, $sorted = false)
{
// the code is does not really matter here
}
So based on your layout you should actually do
<?php echo $this->getChildHtml('header') ?>
Because header is the name attribute in this xml node of your layout :
<block type="core/template" name="header" template="page/headerGreen.phtml" />
As said in the comments, your layout is also looking strange because you are actually telling that your new header is going to be a child of the current header.
Two thinks you can do :
Use the powerfulness of the action nodes :
<default>
<reference name="header">
<action method="setTemplate">
<template>page/headerGreen.phtml</template>
</action>
</reference>
</default>
Or redefine the whole header block
<default>
<reference name="root">
<block type="core/template" name="header" as="header" template="page/headerGreen.phtml" />
</reference>
</default>

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>

Set template for block if there are blocks with the same name

I'm trying to change template for 'form' block in such layout:
<adminhtml_sales_order_create_index>
...
<reference name="root">
<block type="adminhtml/sales_order_create" name="content">
<block type="adminhtml/sales_order_create_form" template="sales/order/create/form.phtml" name="form">
...
<block type="adminhtml/sales_order_create_shipping_method" template="sales/order/create/abstract.phtml" name="shipping_method">
<block type="adminhtml/sales_order_create_shipping_method_form" template="sales/order/create/shipping/method/form.phtml" name="form" />
</block>
<block type="adminhtml/sales_order_create_billing_method" template="sales/order/create/abstract.phtml" name="billing_method">
<block type="adminhtml/sales_order_create_billing_method_form" template="sales/order/create/billing/method/form.phtml" name="form" />
</block>
<block type="adminhtml/sales_order_create_newsletter" template="sales/order/create/abstract.phtml" name="newsletter">
<block type="adminhtml/sales_order_create_newsletter_form" template="sales/order/create/newsletter/form.phtml" name="form" />
</block>
...
I do
<adminhtml_sales_order_create_index>
<reference name="form">
<action method="setTemplate">
<template>my_module/sales/order/create/form.phtml</template>
</action>
</reference>
</adminhtml_sales_order_create_index>
But this does not work. I think because block with name form exist in several places more after. I just want to change it in block type="adminhtml/sales_order_create_form". How can I do this?
#input
Rewrite of block is not the best appoach. It is better to observe 'core_block_abstract_to_html_before' event and change template there I think. Like:
if ($observer->getBlock() instanceof Mage_Adminhtml_Block_Sales_Order_Create_Form) {
$observer->getBlock()->setTemplate('my_module/newtemplate.phtml');
}
This works and is better because you will not get modules conflict if somebody else will rewrite this block. But I thought that may be possible on layout level..
Whilst not the prettiest solution I too do not know of a way of setting a template on a non unique form reference.
Warning this is pretty gross, and I am really not sure of the side affects and for some reason calling setTemplate in the constructor is not enough I guess this is being called at a earlier or later stage than the parents
class My_Module_Block_Adminhtml_Sales_Order_Create_Form extends Mage_Adminhtml_Block_Sales_Order_Create_Form
{
public function _toHtml()
{
$this->setTemplate('my_module/sales/order/create/form.phtml');
return parent::_toHtml();
}
}
Add the write to your Module
<blocks>
<adminhtml>
<rewrite>
<sales_order_create_form>My_Module_Block_Adminhtml_Sales_Order_Create_Form</sales_order_create_form>
</rewrite>
</adminhtml>
</blocks>
I really hope there is a better solution than this.
your right, thats the reason why its not working.
i can't think of a clean way because of this bad naming.
However there are several options that are not clean but will work:
1 option: copy the whole sales.xml into your own admin layout folder and change the template there directly.
2 option: "rewriting" "Mage_Adminhtml_Block_Sales_Order_Create_Form" and set the template from the code
3 option: subscribe to "adminhtml_block_html_before" and listen for the right block and change the template then.
However if you write a community module non of these options are really good.
if it is your own project i would go for option 1
hope that helps
For overwriting the form name form.phtml file from the billing_method you should do the following:
In the config.xml:
<core_block_abstract_to_html_before>
<observers>
<mymodule_core_block_abstract_to_html_before>
<class>MyModule_Model_MyPath</class>
<method>setTemplateFile</method>
</mymodule_core_block_abstract_to_html_before>
</observers>
</core_block_abstract_to_html_before>
and in your observer:
public function setTemplateFile(Varien_Event_Observer $observer)
{
if ($observer->getBlock() instanceof Mage_Adminhtml_Block_Sales_Order_Create_Billing_Method_Form) {
$observer->getBlock()->setTemplate('mymodule/sales/order/create/billing/method/form.phtml');
}
}

Magento: Add content block at the end of the structual block "content"

I'm trying to add a content block to Magento, which should be visible on every side below the main content. I want to archive this with a custom extension, so I can copy this extension and it workes without touching core design files.
My extension includes the following layout update:
<default>
<reference name="content">
<block type="mymod/blockname" name="myblockname" after="-" template="mymod/block.phtml"/>
</reference>
</default>
My problem is, that the attribute after="-" is not working. The block always showes up at the top of the content block. Seems before and after have no consequence.
If I move the block to i.e. footer, the attributes before and after are working fine.
How can I place my block at the bottom of block "content"
As far as I can see the problem is that you specify your block in the "default" layout handle while most of the content in the "content" block is added by other layout handles which are applied later. That's why the added dependencies in your XML registration file (mentioned by Fabian) are not helping.
Please consider these two options depending on your needs:
1. If you really want to include your block on all frontend pages
In your XML layout file (local.xml or a custom one), add a new layout handle:
<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.1.0">
<!-- your other adjustments for default, category_product_view and so on go here -->
<add_my_block>
<reference name="content">
<block type="mymod/blockname" name="myblockname" after="-" template="mymod/block.phtml"/>
</reference>
</add_my_block>
</layout>
Now you create an event observer to inject your layout handle into your layout:
<?php
class YourCompany_YourExtension_Model_Observer
{
/**
* Adds a block at the end of the content block.
*
* Uses the event 'controller_action_layout_load_before'.
*
* #param Varien_Event_Observer $observer
* #return YourCompany_YourExtension_Model_Observer
*/
public function addBlockAtEndOfMainContent(Varien_Event_Observer $observer)
{
$layout = $observer->getEvent()->getLayout()->getUpdate();
$layout->addHandle('add_my_block');
return $this;
}
}
Then you register the event observer in your XML extension configuration file (config.xml):
<?xml version="1.0" encoding="UTF-8" ?>
<config>
<modules>
<YourCompany_YourExtension>
<version>0.0.1</version>
</YourCompany_YourExtension>
</modules>
<frontend>
<events>
<controller_action_layout_load_before>
<observers>
<mymod_add_block_at_end_of_main_content>
<type>singleton</type>
<class>mymod/observer</class>
<method>addBlockAtEndOfMainContent</method>
</mymod_add_block_at_end_of_main_content>
</observers>
</controller_action_layout_load_before>
</events>
<!-- declaring your layout xml etc. -->
</frontend>
<global>
<!-- declaring your block classes etc. -->
<models>
<mymod>
<class>YourCompany_YourExtension_Model</class>
</mymod>
</models>
</global>
</config>
Now your block should end up below the other blocks. I tested this successfully for the homepage, customer login page and category view page. If you have to exclude your block on a few pages, you can check in your event observer if the block should be excluded on that certain page.
2. If you want to include your block only on some pages
Add a layout handle to your XML layout file just as we did before but instead of creating and registering an event observer, just tell your XML layout file to use the custom layout handle in some areas:
<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.1.0">
<catalog_category_default>
<update handle="add_my_block" />
</catalog_category_default>
<catalog_category_layered>
<update handle="add_my_block" />
</catalog_category_layered>
<cms_page>
<update handle="add_my_block" />
</cms_page>
<!-- and so on -->
<add_my_block>
<reference name="content">
<block type="mymod/blockname" name="myblockname" after="-" template="mymod/block.phtml"/>
</reference>
</add_my_block>
</layout>

Resources