Previously in Magento, the wishlist link was added using the following (in wishlist.xml):
<action method="addWishlistLink"></action>
And you could override that and remove it using the following (in your local.xml):
<remove name="wishlist_link"/>
However, in the newest Magento, 1.4.2, they've changed how the wishlist link is added to the following:
<action method="addLinkBlock"><blockName>wishlist_link</blockName></action>
Anyone know how to remove the wishlist link now they’ve changed how it’s added?
It appears there's no publicly available way to reliably remove the wishlist link block from the layout. (you can skip to the end for a workaround)
The addLinkBlock assumes the presence of the block that's been passed, so using remove in the way you describe results in a fatal error being thrown
Fatal error: Call to a member function getPosition() on a non-object in /Users/alanstorm/Sites/magento1point4.2.dev/app/code/core/Mage/Page/Block/Template/Links.php on line 112
Here's the core code that causes that error
app/code/core/Mage/Page/Block/Template/Links.php
public function addLinkBlock($blockName)
{
$block = $this->getLayout()->getBlock($blockName);
$this->_links[$this->_getNewPosition((int)$block->getPosition())] = $block;
return $this;
}
This method assumes its going to be able to pull out a block by whatever name gets passed, so we can't just remove the wishlist_link block as we could in previous versions.
The only mechanism for removing a link appears to be the following method on the same block class
app/code/core/Mage/Page/Block/Template/Links.php
public function removeLinkByUrl($url)
{
foreach ($this->_links as $k => $v) {
if ($v->getUrl() == $url) {
unset($this->_links[$k]);
}
}
return $this;
}
However, this is done using string comparison, and there's no reliable way (that I know of) to generate a URL Object from a layout file, cast it as a string, and pass it into the method (this would be required, as there are numerous configuration settings that can change what the final string URL will be). That makes this method not helpful for our needs.
So, what we can do it modify the existing wishlist_link block to use a blank or non-existant template. This way the block still renders, but it renders as an empty string. The end result is we avoid the fatal error mentioned above, but still manage to remove the link from our selected pages.
The following would remove the link from all the pages using the default handle.
<!-- file: local.xml -->
<layout>
<default>
<reference name="wishlist_link">
<action method="setTemplate"><template>blank-link.phtml</template></action>
</reference>
</default>
</layout>
In your local.xml file,
<?xml version="1.0"?>
<layout version="0.1.0">
<default>
<reference name="root">
<reference name="top.links">
<!-- Remove wishlist link in magento 1.4.x and newer -->
<remove name="wishlist_link"/>
</reference>
</reference>
</default>
</layout>
You can remove the wishlist link from the admin panel System > Configuration > Wishlist > Enabled = "No"
Add the following to your local.xml file.
<reference name="top.links">
<remove name="wishlist_link"/>
</reference>
This works! I have removed Wishlink from Toplinks and wanted to add it back into another block but that doesn't seem possible when you remove it in this way. Sadly.
I know I'm years late here, but for all of those people who are still looking for answers to this.
I have a way to work around this issue that is only a bit of extra work but it's not hacky and it gives you FULL control of your top.links block.
Simply unset the top.links block and re-create it, it will be empty (no more wishlist_link block) and all you have to do is add whichever links you want inside of it! (Do all of this in your theme/layout/local.xml file of course).
<layout version="0.1.0">
<default>
<!-- HEADER -->
<reference name="header">
<!-- Unsetting the already existing top links block -->
<action method="unsetChild">
<name>topLinks</name>
</action>
<!-- Re-creating a new top links block -->
<block type="page/template_links" name="top.links" as="topLinks">
<!-- EXAMPLE: Account Dashboard Link -->
<action method="addLink" translate="label title" module="catalog">
<label>Account Dashboard</label>
<url helper="customer/getAccountUrl"/>
<title>Account Dashboard</title>
</action>
<!-- You can add any other links that you want -->
</block>
</reference>
</default>
</layout>
Also remember that for some links like Sign In and Log Out you will need to reference your top.links block inside the appropriate <customer_logged_out> and <customer_logged_in> handles instead of inside of <default> as a guide for this you can look at Magento's customer.xml file.
IMPORTANT: If there are any modules included in your project that add links to the top.links block, those links won't show up because local.xml is processed last, so just keep that in mind when using this method :)
I am a Certified Magento Front End Developer with over 3 years of experience and I have overcome LOTS of layout XML headaches to the point where we became best friends.
Related
I have some troubles in /checkout/cart page with taking out two blocks:
- compare products block
- voting block
I cant remove them from right sidebar
at current layout xml
/layout/checkout.xml
There is only MY ONE adding template to right sidedar
<reference name="right">
my adding template code here
</reference>
also I have just removed all adding templates to right sidebar from
/layout/page.xml
and as a result I see these two blocks (compare and voting) at right bar anyway (
Let me know where can They be removed by me from ?
Thanks
I hope you're using local.xml to do your customizations.
In local.xml
<default>
<!--other codes-->
<remove name="catalog.compare.sidebar" />
<remove name="right.poll" />
<!--other codes-->
</default>
if need to remove from checkout - cart page only and retain on other pages then use <checkout_cart_index> handler instead of and use "unSetChild". Remember <remove> will completely remove the block.
I found out where was problem )
Magento layouts include one of this
/layout/poll.xml
and There I saw these lines
<!-- Mage_Poll -->
<reference name="right">
<block type="poll/activePoll" name="right.poll">
<action method="setPollTemplate"><template>poll/active.phtml</template><type>poll</type></action>
<action method="setPollTemplate"><template>poll/result.phtml</template><type>results</type></action>
</block>
</reference>
</default>
after commented it They disappeared )
I would like all my CMS pages (but not all pages) to use a custom template file, however when I use the setTemplate action in my local.xml file it's not changing the template. The block is rendering correctly but without the correct layout.
The XML I'm using right now is:
<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.1.0">
<cms_page_view>
<reference name="root">
<action method="setTemplate"><template>page/cms-page.phtml</template></action>
</reference>
<reference name="right">
<block type="catalog/navigation" name="default_page_view" template="navigation/game-menu.phtml"/>
</reference>
</cms_page_view>
</layout>
What am I doing wrong?
You aren't doing anything wrong - your directive is being overridden by the entity data. For the reason why, see Mage_Cms_Helper_Page::_renderPage():
protected function _renderPage(/*...*/)
{
//snip...
$action->getLayout()->getUpdate()
->addHandle('default')
->addHandle('cms_page');
$action->addActionLayoutHandles();
if ($page->getRootTemplate()) {
$handle = ($page->getCustomRootTemplate()
&& $page->getCustomRootTemplate() != 'empty'
&& $inRange) ? $page->getCustomRootTemplate() : $page->getRootTemplate();
$action->getLayout()->helper('page/layout')->applyHandle($handle);
}
//snip...
}
So, your directive is being processed under the full action name handle cms_page_view, which is added via the $action->addActionLayoutHandles(); call. Whereas CMS pages are practically always saved via the admin with a root_template value, this value will always override file-based directives.
While it would be possible to update the data, it would be at risk of being overwritten when In order to provide an alternate template which will be preserved when the page is edited via the admin, it's necessary to specify some configuration values and some corresponding layout XML. In your custom module's config XML (or in app/etc/local.xml if this is a non-distributed change):
<global>
<page>
<layouts>
<cms_page_custom>
<label>Empty</label>
<template>page/cms-page.phtml</template>
<layout_handle>cms_page_custom</layout_handle>
</cms_page_custom>
</layouts>
</page>
</global>
This will provide the option to the select input during CMS page administration. To complete this work, in your custom layout XML:
<cms_page_custom>
<reference name="root">
<action method="setTemplate"><template>page/cms-page.phtml</template></action>
<!-- Mark root page block that template is applied -->
<action method="setIsHandle"><applied>1</applied></action>
<action method="setLayoutCode"><name>empty</name></action>
</reference>
</cms_page_custom>
I am currently trying to get a better understanding of how blocks work in Magento. I have looked at some of the files to get a better idea and it has helped a little, but they are a too to complex for my limited skills at the moment and I still do not have proper understanding of what is going on and how to implement them into my site. I realise they are essential to understand for working with Magento so I thought I would set up a list of things to try and achieve:
display a block (done)
display a block and child block
display a block within a magento layout
position a block on the page of a magento layout
learn the most commonly used 'type' attributes and when to use them
So far I have put together
_index_index
Namespace/Module/etc/config.xml
<frontend>
....
<layout>
<updates>
<learningblocks>
<file>Namespace/Module/childblocks.xml</file>
<file>Namespace/Module/blocks.xml</file>
</learningblocks>
</updates>
</layout>
</frontend>
Namespace/Module/controllers/IndexController.php
class Namespace_Module_IndexController
extends Mage_Core_Controller_Front_Action
{
public function indexAction()
{
$this->loadLayout('learningblocks')->renderLayout();
}
public function blocksAction()
{
$this->loadLayout('blocknode')->renderLayout();
}
}
frontend/base/default/layout/namespace/module/blocks.xml
<layout>
<blocknode>
<block type="core/text" name="blocktest" output="toHtml" >
<action method="setText">
<args>some text to display on screen</args>
</action>
</block>
</blocknode>
</layout>
The above worked as expected and displayed the string 'some text to display on screen' on a white page. But thats all i've been able to do, I cannot get child blocks to render onto the screen and I cannot display anything within a theme, let alone try and move it about within that theme
Below is one of my attempts that I cant seem to get to work. Why is this not working?
frontend/base/default/layout/namespace/module/childblocks.xml
<layout>
<abcde>
<block type="core/template" name="childblocks" output="toHtml" template="namespace/module/childblocks.phtml">
<block type="core/text" name="anyname">
<action method="setText">
<args>Some text to add to this page</args>
</action>
</block>
</block>
</abcde>
<learningblocks_index_index>
<update handle="abcde" />
</learningblocks_index_index>
</layout>
frontend/base/default/template/namespace/module/childblocks.phtml
<p>from the childblock.phtml page</p><?php $this->getChildHtml(); ?>
NB: I have changed the namespaces and module names to be more generic, in the hope it is easier to read (they wern't very well chosen names).
I know this is not a complete answer, but it may help those who have struggled with the same problem. I have not gone into great depth as I assume if your searching for an answer you will have already read THIS ARTICLE and that covers it all, I assume you have the same issue as I did i.e. a misunderstanding of what you had learnt from this tutorial.
On reading this answer please be aware I am very new to Magento and there could be some inaccuracies in here, if there are I am sure someone will correct me and edit accordingly.
Firstly this is wrong
public function indexAction()
{
$this->loadLayout('learningblocks')->renderLayout();
}
It should be this
public function indexAction()
{
$this->loadLayout()->renderLayout();
}
and then you will have to map learningblocks node in layout xml to that action module_controller_action. Doing this will display the block in the page within your theme.
So to render a child block
Add something like this in you layout.xml
<module_controller_action>
<reference name="content">
<block type="module/blockname" name="unique_name" output="toHtml" template="path/toyou/template.phtml" >
<block type="module/blockname" name="another_unique_name" output="toHtml" template="path/toyou/template.phtml" />
</block>
</reference>
</module_controller_action>
then in your template file echo out
$this->getChildHtml('another_unique_name')
If you want to remove blocks from your page use the remove node such as
<remove name="right"/>
<remove name="left"/>
This page will offer a list of attributes that can be used to be honest I found that looking through the magento files helped more than that page though
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>
...
I started working with Magento this week and I'm trying to create a new theme. Following the "Designing for Magento" article of the wiki, I tried to remove the Popular Tags block from the index view, adding this line to local.xml on magento\app\design\frontend\default\mytheme\layout:
<remove name="tags_popular"/>
I don't why, but the tags are still there while if I do the following the language switcher disappears:
<remove name="store_language"/>
I also tried this to no effect:
<reference name="left">
<action method="unsetChild"><name>tags_popular</name></action>
</reference>
I even deleted tag.xml and the tags are still there!
I know that I can get rid of them disabling the Mage_tag in the backend, buy I want to understand why this is not working.
Thanks!
Just add this in your theme->page.xml default block
<remove name="tags_popular"/>
you can remove block any of magneto. then you can remove after it's block name.
here you see tag_popular it's block name remove plus it's block name
Remove default magento block
Have a look into tag.xml where you will find this code, which you have to comment out:
<default>
<!-- Mage_Tag -->
<reference name="left">
<block type="tag/popular" name="tags_popular" template="tag/popular.phtm">
<action method="setTemplate"><template>tag/popular.phtml</template></action>
</block>
</reference>
</default>
How silly, the popular tags were shown in the main page because they came in the default code of the content page (menu: CMS > Pages), so I just had to erase that :P