How to change top links - magento

I'm trying to change the top links list on header, such as addLink, removeLink, etc. So I create an observer which catch event "controller_front_send_response_before", and add this:
$layout = $this->getLayout();
$layout->getBlock('top.links')->addLink('hi','test','the');
But the top links stay the same. It worked if I do it in layout xml file like this:
<default>
<reference name="top.links">
<action method="addLink">
<label>hi</label>
</action>
</reference>
</default>
Please help, I need to do it programmatically, so I can add some conditions.

use this event controller_action_layout_generate_blocks_after

Related

Not able to change checkout/cart.phtml through layout update

I am trying to change checkout/cart.phtml through layout update in my module's layout file i.e. mymodule.xml
<layout>
<checkout_cart_index>
<reference name="checkout.cart">
<action method="setCartTemplate"><value>mymodule/checkout/cart.phtml</value></action>
</reference>
</checkout_cart_index>
</layout>
But It is not working. Any clues?
Ankita, What I'm about to write is the actual way to get what you want. While the official answer by John Hickling will work, it is not how Magento intended the main cart template to be modified.
Magento deliberately chose to use different methods for setting the cart templates, namely, setCartTemplate and setEmptyTemplate. They can be seen in Magento's own app/design/frontend/base/default/layout/checkout.xml. This was done so that two templates can be managed, each to handle their own condition. The first condition is for a cart with items, while the second condition is for a cart without items. By using the common setTemplate method, that distinction will be lost: a cart with items and a cart without items will both display the same template. This is no good.
You were so close. You were correct in trying to use the setCartTemplate method. That is what you should be using. However, you were missing one essential method call that would allow Magento to even consider using it: you forgot to include the chooseTemplate method call. Note Magento's own checkout.xml file:
<block type="checkout/cart" name="checkout.cart">
<action method="setCartTemplate"><value>checkout/cart.phtml</value></action>
<action method="setEmptyTemplate"><value>checkout/cart/noItems.phtml</value></action>
<action method="chooseTemplate"/>
Look at that last method call, chooseTemplate. If you look in app/code/core/Mage/Checkout/Block/Cart.php you will see the following method, within which those familiar setCartTemplate and setEmptyTemplate methods are called, but because they are magic methods, they are not easily searchable in Magento's source, which is problematic for a lot of people:
public function chooseTemplate()
{
$itemsCount = $this->getItemsCount() ? $this->getItemsCount() : $this->getQuote()->getItemsCount();
if ($itemsCount) {
$this->setTemplate($this->getCartTemplate());
} else {
$this->setTemplate($this->getEmptyTemplate());
}
}
You were missing that chooseTemplate method call. This is what your own layout XML file should look like:
<checkout_cart_index>
<reference name="checkout.cart">
<action method="setCartTemplate"><value>mymodule/checkout/cart.phtml</value></action>
<action method="setEmptyTemplate"><value>mymodule/checkout/noItems.phtml</value></action>
<action method="chooseTemplate"/>
</reference>
</checkout_cart_index>
I recommend you update your code if it is still under your control. This is how Magento intended the cart templates to be updated. The common setTemplate method is too destructive for this task. Granularity was Magento's intention, so updates should maintain that granularity. I also recommend you mark this as the correct answer.
The method is setTemplate not setCartTemplate, like so:
<layout>
<checkout_cart_index>
<reference name="checkout.cart">
<action method="setTemplate"><value>mymodule/checkout/cart.phtml</value></action>
</reference>
</checkout_cart_index>
</layout>

How can i add a new tab in left in sales order view,like now are invoices credit memos,releases etc in magento

i want to add a new tab in left in sales->order->view.For this i have created a module but not solved my problem,it is showing an error like wrong tab configuration,i have search on many links also posted in stack overflow,but not yet satisfied.
Thanks
This actually should be quite easy to do. Just look at the app/design/adminhtml/default/default/layout/sales.xml layout file. You can find there the <adminhtml_sales_order_view> node, which defines all blocks used on order's view page.
In order to add a new tab, you would need to put another <action> declaration in the file. Currently tabs are defined like this (Magento EE 1.11):
<adminhtml_sales_order_view>
(...)
<reference name="left">
<block type="adminhtml/sales_order_view_tabs" name="sales_order_tabs">
<action method="addTab"><name>order_info</name><block>order_tab_info</block></action>
<action method="addTab"><name>order_invoices</name><block>adminhtml/sales_order_view_tab_invoices</block></action>
<action method="addTab"><name>order_creditmemos</name><block>adminhtml/sales_order_view_tab_creditmemos</block></action>
<action method="addTab"><name>order_shipments</name><block>adminhtml/sales_order_view_tab_shipments</block></action>
<action method="addTab"><name>order_history</name><block>adminhtml/sales_order_view_tab_history</block></action>
<action method="addTab"><name>order_transactions</name><block>adminhtml/sales_order_view_tab_transactions</block></action>
</block>
</reference>
</adminhtml_sales_order_view>
Be aware, do not change core templates!
In this case you should create new module or alter existing one in local code pool. Define a layout updates in config.xml and then create new layout file in adminhtml default theme, for example:
app/design/adminhtml/default/default/layout/CUSTOM_VENDOR/sales.xml:
<adminhtml_sales_order_view>
<reference name="sales_order_tabs">
<action method="addTab"><name>TAB_NAME</name><block>CUSTOM_BLOCK</block></action>
</reference>
</adminhtml_sales_order_view>
Then you just need to create new block and a template.

Remove top navigation using ifconfig in magento

I'm working on a module in which we have a configuration as "advanemenu/general/enabled"
By using this config I am being able to add items conditionally to my magento frontend.
Ex.
<reference name="head">
<action method="addItem" ifconfig="advancemenu/general/enabled"><type>skin_css</type><name>css/advancemenu.css</name></action>
</reference>
Now similarly I want to remove the top navigation if the config value is enabled.
I tried the following but without any result...
<remove ifconfig="advancemenu/general/enabled" name="catalog.topnav" />
Incase the ifconfig works with <action> then is there any way to remove top navigation using this method.
Please help me if anyone knows how to do this.
(Thnx in Advance)
IfConfig only work with action method. When you call action in a xml layout this parse in a call to funcion in the block instance.
you can see this in:
file: app/code/core/Mage/core/Model/layout.php around line 289
protected function _generateAction($node, $parent)
{
if (isset($node['ifconfig']) && ($configPath = (string)$node['ifconfig'])) {
if (!Mage::getStoreConfigFlag($configPath)) {
return $this;
}
}
but a posible solution for this is add a template only in case of true value. For example
<reference name="head">
<action method="setTemplate" ifconfig="advancemenu/general/enabled">
<template>route/to/template</template>
</action>
</reference>
then, only when you have enable your module, you have template associate to this block, in another case, your block don´t have template, then don´t load.
You can remove any block using the unsetchild method.
For the above case
<reference name="top.menu">
<action method="unsetChild" ifconfig="advancemenu/general/enabled">
<name>catalog.topnav</name>
</action>
</reference>
It will help for the conditional remove statement.

Adding image in Magento via update layout

I'm trying to figure out how to add images, etc. to the left sidebar portion of a 2 column with left sidebar page in Magento using the layout update in the cms ->page->design portion of the admin area.
Is it possible to do this from the update layout xml area? If not, could you explain how to create a module (or whatever else would be required).
Thanks.
If you look in base/default/layout/catalog.xml, you will see an example of using a template with an image placeholder that can be specified in your Update Layout XML area:
<reference name="left">
<block type="core/template" name="left.permanent.callout" template="callouts/left_col.phtml">
<action method="setImgSrc"><src>images/media/col_left_callout.jpg</src></action>
<action method="setImgAlt" translate="alt" module="catalog"><alt>Our customer service is available 24/7. Call us at (555) 555-0123.</alt></action>
<action method="setLinkUrl"><url>checkout/cart</url></action>
</block>
</reference>
So, in your Update Layout XML, you would write something like:
<reference name="left.permanent.callout"> <!-- match this to the block name from above -->
<action method="setImgSrc"><src>images/media/my_file_name.jpg</src></action>
<action method="setImgAlt" translate="alt" module="catalog"><alt>Some text here</alt></action>
<action method="setLinkUrl"><url>your/path</url></action>
</reference>
You can adapt that by taking a copy of the template file left_col.phtml and making changes as you wish.

Magento - use an alternate "price.phtml" (in addition to the existing one)

I am looking for a way to have an alternate template/catalog/product/price.phml used in one specific location, and to continue using the existing price.phtml file in all other locations.
To explain further, I need to display the regular price, and then another special price right below it - but only on the product page (for the main product being displayed). This special price is not a price that can be calculated by the catalog price rules, so I wrote my own module to do the calculation. So, everywhere that I am displaying prices I want to display with the regular ol' template/catalog/product/price.phtml file... but for the product page (the main product - not the related, upsells, etc) I want to use my own custom template/catalog/product/price-custom.phtml template file. Can anybody help?
Normally I just look in the layout xml files (for example catalog.xml) to find these types of things, but price.phtml is kinda special - it isn't that simple. And for the life of me I can't figure out if there is an easy way to swap it out conditionally on the page being viewed. I am aware that I can just update price.phtml to always print out this extra price, and then use css to hide the price everywhere, but I would rather not do that if possible.
(Also you may want to know that I only have simple products.)
This can be done in a layout XML file:
<layout>
<PRODUCT_TYPE_simple>
<reference name="product.clone_prices">
<action method="setTemplate">
<template>catalog/product/price-custom.phtml</template>
</action>
</reference>
</PRODUCT_TYPE_simple>
</layout>
Create a local.xml file, put it in app/frontend/default/YOURTEMPLATE/layout
In the local.xml file, add:
<?xml version="1.0" encoding="UTF-8"?>
<layout>
<!-- Override price template on product view page -->
<PRODUCT_TYPE_simple>
<reference name="product.info.simple">
<action method="setTemplate">
<template>catalog/product/price_product_page.phtml</template>
</action>
</reference>
</PRODUCT_TYPE_simple>
<!-- /Override price template on product view page -->
</layout>
Create a copy of catalog/product/price.phtml and put it in YOURTEMPLATE/templates/product/product_price_page.phtml
This will override the price.phtml in the template, and replace it with product_price_page.phtml
Or in your php block.
See example here :
Mage_Catalog_Block_Product_Abstract
protected $_priceBlockDefaultTemplate = 'catalog/product/price.phtml';
protected $_tierPriceDefaultTemplate = 'catalog/product/view/tierprices.phtml';
I had a similar requirement recently, where a different price template for the product page was the preferred solution.
The price block appears to be something of a special case in Magento (in the RWD theme at least), it's defined in catalog.xml as simply a block type and name within the <default/> handle:
<block type="catalog/product_price_template" name="catalog_product_price_template" />
If you look around at how some core layout files set the price template, you'll find examples like this (from bundle.xml):
<reference name="catalog_product_price_template">
<action method="addPriceBlockType">
<type>bundle</type>
<block>bundle/catalog_product_price</block>
<template>bundle/catalog/product/price.phtml</template>
</action>
</reference>
They call a method called addPriceBlockType which you can find in Mage_Catalog_Block_Product_Abstract
Based on this and after a little experimentation, I found the following solution worked for me:
<catalog_product_view>
<reference name="product.info">
<action method="addPriceBlockType">
<type>simple</type>
<block>catalog/product_price</block>
<template>catalog/product/price_product_page.phtml</template>
</action>
<action method="addPriceBlockType">
<type>configurable</type>
<block>catalog/product_price</block>
<template>catalog/product/price_product_page.phtml</template>
</action>
<!-- Set for each product type as necessary e.g. bundled, virtual etc... -->
</reference>
</catalog_product_view>
The proper way to achieve it :
<PRODUCT_TYPE_simple>
<reference name="product.info.simple">
<action method="addPriceBlockType"><type>simple</type><block>catalog/product_price</block><template>catalog/product/price-product-page.phtml</template></action>
</reference>
</PRODUCT_TYPE_simple>
<PRODUCT_TYPE_configurable>
<reference name="product.info.configurable">
<action method="addPriceBlockType"><type>configurable</type><block>catalog/product_price</block><template>catalog/product/price-product-page.phtml</template></action>
</reference>
</PRODUCT_TYPE_configurable>
...

Resources