I've tried various tutorials but I can't get this to work.
Basically, I want to have a different footer on my homepage. I've setup two page layouts and have applied them to the cms pages fine.
So in the homepage layout I refer to...
<?php echo $this->getChildHtml('footer_home') ?>
And on all the other pages this...
<?php echo $this->getChildHtml('footer_alt') ?>
Pretty simple!
Then in the page xml I've amended the part which refers to the footer as follows...
<block type="page/html_footer" name="footer_alt" as="footer_alt" template="page/html/footer_alt.phtml">
<block type="page/html_wrapper" name="bottom.container" as="bottomContainer" translate="label">
<label>Page Footer</label>
<action method="setElementClass"><value>bottom-container</value></action>
</block>
<block type="page/switch" name="store_switcher" as="store_switcher" template="page/switch/stores.phtml"/>
<block type="page/template_links" name="footer_links" as="footer_links" template="page/template/links.phtml"/>
</block>
<block type="page/html_footer" name="footer_home" as="footer_home" template="page/html/footer_home.phtml">
<block type="page/html_wrapper" name="bottom.container" as="bottomContainer" translate="label">
<label>Page Footer2</label>
<action method="setElementClass"><value>bottom-container</value></action>
</block>
<block type="page/switch" name="store_switcher" as="store_switcher" template="page/switch/stores.phtml"/>
<block type="page/template_links" name="footer_links" as="footer_links" template="page/template/links.phtml"/>
</block>
I think this is where the problem lies. With the above all pages show the 'footer_alt' footer and I'm not sure why.
I can confirm that 'page/html/footer_alt.phtml' and 'page/html/footer_home.phtml' are setup fine.
I hope that makes sense. Thanks.
All of these answers are way too complex for what is a straightforward solution. Rewriting is overkill. Rewriting Magento core, even if done properly, should always set off alarms and immediately compel that developer to thoroughly read the Magento source. In my experience, every Magento heartache is accompanied by a cryptic but entirely gratifying solution. This is one of those heartaches with a gratifying solution.
It comes as no surprise that Magento arbitrarily decided to ensure that the footer templates do not generate a unique cache key. This means that the footer cannot be different depending on the section of the site loaded; to be clear, it actually can, but only if the block cache is disabled. The block cache should never be disabled, though, so ultimately, this is tantamount to being restricted to a single footer across the entire site.
There are legitimate use cases for wanting a different footer in different parts of the site. For example, in the checkout: the checkout should be immersive and distraction-free. However, the moment any page on the site is hit, the footer from those pages will be cached, and then the checkout will display that same footer.
Solutions described here require either a core rewrite, which is no good, or some other conditional check, which will not reasonably scale beyond a few conditions.
My solution is simple: add a cacheKey to the new template. Target the layout handle for the given page, reference the footer, set the template, and then add the cacheKey. This is just standard Magento layout XML. This layout XML changes the footer on the onepage checkout--and only on the onepage checkout. Furthermore, caching will continue to work for every unique footer defined in this way.
<checkout_onepage_index>
<reference name="footer">
<action method="setTemplate">
<template>linusmoneymaker/page/html/checkout-footer.phtml</template>
</action>
<action method="setCacheKey">
<key>your-own-unique-cache-key-for-linus-moneymaker</key>
</action>
</reference>
</checkout_onepage_index>
This works for the following reason. Here is the source for app/code/core/Mage/Core/Block/Abstract.php, which handles all the block caching:
/**
* Get Key for caching block content
*
* #return string
*/
public function getCacheKey()
{
if ($this->hasData('cache_key')) {
return $this->getData('cache_key');
}
/**
* don't prevent recalculation by saving generated cache key
* because of ability to render single block instance with different data
*/
$key = $this->getCacheKeyInfo();
//ksort($key); // ignore order
$key = array_values($key); // ignore array keys
$key = implode('|', $key);
$key = sha1($key);
return $key;
}
Notice that if a cacheKey is defined, that one will take precedence over the one that will be generated from the getCacheKeyInfo method in app/code/core/Mage/Page/Block/Html/Footer.php, which does not produce a per-template unique cacheKey. By providing a cacheKey from the layout XML, Magento effectively abandons the default, non-unique footer cacheKey in favour of the one provided manually through the layout XML for the given part of the site.
Not only is this the proper way, but it scales infinitely. Every page on the site could realistically define its own footer.
The reason for you problem should be magento's block cache.
Like the header the footer is cached by default and
the cache key does not include the template
to verify its a cache problem try this first:
Check if the block cache is enabled.
Then navigate to your page. The footer on the first page should be on any of the following.
So if your first page view is your alt footer it will be on any other page and vise versa.
if the problem is the cache you should be able to solve this
by rewriting the "Mage_Page_Block_Html_Footer" and
modify getCacheKeyInfo() to include the template like this
public function getCacheKeyInfo()
{
return array(
'PAGE_FOOTER',
Mage::app()->getStore()->getId(),
(int)Mage::app()->getStore()->isCurrentlySecure(),
Mage::getDesign()->getPackageName(),
Mage::getDesign()->getTheme('template'),
Mage::getSingleton('customer/session')->isLoggedIn(),
$this->getTemplate()
);
}
this should solve your problem.
Create 2 static Blocks named "home_page_footer" and "inner_page_footer".
Open footer.phtml and place the following code.
<?php $home = Mage::getSingleton('cms/page')->getIdentifier(); ?>
<?php if ($home):?>
<div style="clear:both;">
<?php echo $this->getLayout()->createBlock('cms/block')->setBlockId('home_page_footer')->toHtml(); ?>
</div>
<?php else: ?>
<div style="clear:both;">
<?php echo $this->getLayout()->createBlock('cms/block')->setBlockId('inner_page_footer')->toHtml(); ?>
</div>
<?php endif; ?>
Hope it will help.
Related
I want to add a second static block to the bottom of every category page in my magento 1.9 store.
Like this site
I want a description on top of the products but also a larger description at the bottom.
I am very familiar with magento and hard coding but it seems I get stuck here. I search the web for ours but no solution.
I could manage it to get a static block at the footer but then on every page it is the same text and I want different text at each category.
You can do this through layout.xml. To add a static block simply add:
<block type="cms/block" name="block_key">
<action method="setBlockId">
<block_id>block_key</block_id>
</action>
</block>
to the content node on the category section. Then you can call it via:
<?php echo $this->getChildHtml('block_key'); ?>
where ever you would like in your template.
To add custom text you can use the magic set method which you will add to the custom design section on the category page.
<reference name="block_key">
<action method="setCustomText">
<text>This is my custom text</text>
</action>
</reference>
Then within your template/block you can get this from using the following :
<?php echo $this->getCustomText(); ?>
Let me know if this works for you.
I would like to add a shopping cart block a cms page, but whenever I try, nothing happens...not even an error.
I've tried following this tutorial, http://www.magento.cc/how-to-use-php-on-a-cms-page.html.
So I created the new folders in app/code/local and then a Test.php file, yet when I try to include
{{block type="YourModule_Custom/test" my_param1="value 1" another_param="value 2"}}
in the cms page, nothing appears.
Here's my code in the Test.php page:
<?php
class YourModule_Custom_Block_Test extends Mage_Core_Block_Abstract
{
protected function _toHtml()
{
echo 'TEST';
$this->getChildHtml('header');
return $html;
}
}
You can do a local.xml update. And place your content as .phtml file
<cms_index_index>
<reference name="content">
<block type="Your_custom/Block" name="home_main" as="home_main" template="cms/default/home.phtml">
</block>
</reference>
</cms_index_index>
Create a file named home.phtml in cms/default/ Then you can use your own block type to use your custom module / functions
Then add your home page content in there.
I don't know what are you trying to achieve. But from your question, I have a strong feeling that, you are trying to set a template of your own through CMS page. If that is the case, let us analyze why your block didn't show any output.
Your block definition is like this
{{block type="YourModule_Custom/test" my_param1="value 1" another_param="value 2"}}
There is no problem with this defintion. But it is good, if you add name to your block. If you set a template along with that, then you don't need any backend code for setting a template for your block. That is your block should look like this
{{block type="YourModule_Custom/test" name="test.block" template="test.phtml"}}
Now when magento encounter this, it will find your block, set described name to that block (for later reference this name will be used. However it is not relevant in this case), set template specified to your block and then render the content in that template.
So you should have a block of type that you specified. You had it right now(you dont need that _toHtml() inside that). Along with that you need a template file test.phtml and it should be in the location app/design/frontend/<your_package>/<your_theme>/template/test.phtml. You dont have that file right now. So create it and add this content inside that file
<p><?php echo "I am here. Can you see me ?"; ?></p>
Now check your CMS page output. You can see that content. Isn't it ?
So right now what you are trying to do is, instead of setting a template along with that block definition, you are trying to set it through your block. Is it wrong ? Obviously, NO. There are some cases, where we need to go with that way. I assume you really need it. So again let us redifine our block in this form.
{{block type="YourModule_Custom/test" name="test.block"}}
Hmm. Here we didn't set a template to this block right now. You can hence set it through your block definition. You used _toHtml() method.
<?php
class YourModule_Custom_Block_Test extends Mage_Core_Block_Abstract
{
protected function _toHtml()
{
echo 'TEST';
$this->getChildHtml('header');
return $html;
}
}
?>
This method is using to set a template and then renders the content. So you are in the right track. But the problem here is, you are not setting any template!! plus your method returns a variable $html which holds nothing. So what should we return through a _toHtml() ? The answer lies in Mage_Core_Block_Template. Let us look on _toHtml() definition
protected function _toHtml()
{
if (!$this->getTemplate()) {
return '';
}
$html = $this->renderView();
return $html;
}
Basically what this does is, it checks whether a template is set , if not return nothing. If it does renders it. That means, it is obvious that we need to set a template. So your block should look like this.
<?php
class YourModule_Custom_Block_Test extends Mage_Core_Block_Template
{
protected function _toHtml()
{
$this->setTemplate('test.phtml');
$html = parent::_toHtml();
return $html;
}
}
Note that your block extends from Mage_Core_Block_Template rather from Mage_Core_Bock_Abstract. This is because setTemplate() method is defined in Mage_Core_Block_Template class. In _toHtml(), we are setting our template and then leave rest to our parent block. Now check whether content in test.phtml is showing in your CMS page. It does right ?
I don't understand exact what do you want. but by your question my understanding is you want to display shopping cart block into any CMS page like Home page, About us page etc.
If my understanding is right then here is one solution for you.
You can insert this code into your cms page from admin.
Admin -> CMS -> Pages -> Select any page on which you want to display block -> Click on design tab from left navigation ->Under Page Layout section insert the below code in "Layout Update XML" field. Click on save.
<reference name="content">
<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"/>
<action method="addItemRender"><type>simple</type><block>checkout/cart_item_renderer</block><template>checkout/cart/item/default.phtml</template></action>
<action method="addItemRender"><type>grouped</type><block>checkout/cart_item_renderer_grouped</block><template>checkout/cart/item/default.phtml</template></action>
<action method="addItemRender"><type>configurable</type><block>checkout/cart_item_renderer_configurable</block><template>checkout/cart/item/default.phtml</template></action>
<block type="core/text_list" name="checkout.cart.top_methods" as="top_methods" translate="label">
<label>Payment Methods Before Checkout Button</label>
<block type="checkout/onepage_link" name="checkout.cart.methods.onepage" template="checkout/onepage/link.phtml"/>
</block>
<block type="page/html_wrapper" name="checkout.cart.form.before" as="form_before" translate="label">
<label>Shopping Cart Form Before</label>
</block>
<block type="core/text_list" name="checkout.cart.methods" as="methods" translate="label">
<label>Payment Methods After Checkout Button</label>
<block type="checkout/onepage_link" name="checkout.cart.methods.onepage" template="checkout/onepage/link.phtml"/>
<block type="checkout/multishipping_link" name="checkout.cart.methods.multishipping" template="checkout/multishipping/link.phtml"/>
</block>
<block type="checkout/cart_coupon" name="checkout.cart.coupon" as="coupon" template="checkout/cart/coupon.phtml"/>
<block type="checkout/cart_shipping" name="checkout.cart.shipping" as="shipping" template="checkout/cart/shipping.phtml"/>
<block type="checkout/cart_crosssell" name="checkout.cart.crosssell" as="crosssell" template="checkout/cart/crosssell.phtml"/>
<block type="checkout/cart_totals" name="checkout.cart.totals" as="totals" template="checkout/cart/totals.phtml"/>
</block>
</reference>
After that you will see shopping cart block on your CMS page. If you don't need any block from them you can remove that blck from the above code.
if you try to call add to cart from cms page then add url like
checkout/cart/add?product=$id&qty=$qty
Example-
<a href="{{store url='checkout/cart/add?product=5&qty=3'}}">
<img src="{{skin url='images/addtocart.jpg'
}}" alt="product5" /></a>
I’m having trouble in moving the mini cart from sidebar to header. I’ve tried all the tutorials available in the internet but it doesn’t work.
I also tried adding this in the header block of layout\page.xml
<block type="checkout/cart_sidebar" name="cart_sidebar" as="topcart" template="checkout/cart/sidebar.phtml"
And then in my page\html\header.phtml, I use the code below to call the cart but nothing happened.
<?php echo $this->getChildHtml('topcart'); ?>
The solution above works in magento 1.6, but not in version 1.7
First you need to create or update your local.xml file IF you do not have a local.xml file you can create one in
app->frontend->[Package Name]->[Theme Name]->layout->local.xml
Once this is created you can copy exactly what I have in this post into that file for a start of how to use one.
DO ALL UPDATES THROUGH A LOCAL.XML file not through catalog.xml or checkout.xml !! This will make upgrades significantly easier later down the road. Additionally, you will be able to quickly see all changes you have made to your site in one file.
The below example will add it to the header reference name which will be available on all pages as indicated by the tag and will only be available in the header.phtml file. Duplicate base/default/checkout/cart/sidebar.phtml and rebane that file as topcart.phtml and place it into your theme at [Your Package]/[Your Theme]/template/checkout/cart/topcart.phtml by doing this you are cloning the sidebar functionality and adding it to the header. Then you can make any edits through the topcart.phtml file without affecting base functionality.
<?xml version="1.0" encoding="UTF-8"?>
<layout>
<default>
<reference name="header">
<block type="checkout/cart_sidebar" name="topcart_mini" as="topcart" template="checkout/cart/topcart.phtml" />
</reference>
</default>
</layout>
Then call it in header.phtml with
<?php echo $this->getChildHtml('topcart'); ?>
This is the proper way to modify Magento, this makes upgrades quite simple. Additionally, it does not edit any core files.
Insteat of copying block xml, you should reference it like
<reference name="block-name">
</reference>
I'm pretty new to Magento, and have been following the base theme so far along, but I am having problems with catalog pagination.
At the moment I'm having problems getting the "page/html_pager" block to display.
So, my catalog.xml has this for both anchor and non-anchor categories:
<reference name="content">
<block type="catalog/category_view" name="category.products" template="catalog/category/view.phtml">
<block type="catalog/product_list" name="product_list" template="catalog/product/list.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>
</block>
</block>
</reference>
My toolbar.phtml has the corresponding code:
<?php echo $this->getPagerHtml() ?>
and my default/template/page/html/pager.phtml just contains some test code along the lines of:
<h1>Test</h1>
At first I thought it might be because there weren't multiple pages, so I added some products and set the both the grid and the list views to show a maximum of 1 per page, and the item count reflects this:
Showing 1 of 11 items
Doing a var_dump on the $this->getPagerHtml() returns an empty string, and using the template path hints indicates it doesn't even seem to load the block - yet it loads it's parent block.
Copying the code directly from the base design package doesn't work, yet switching to that package it does.
So, what am I missing? Or doing wrong? I've run out of ideas as to what it could be.
thanks
Solved:
Adding<action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
After the product_list_toolbar block appeared to fix this issue.
Magento's documentation is a little thin on the ground with this so I'm unsure as to why
<block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
requires it's name set again with an action tag, but it does.
If anyone can explain this, I'd love to understand it.
Any chance that it's being overridden by a different .xml file in layout?
You could always remove all the .xml files in the layout directory and bring them back in one by one and see if the pagination toolbar disappears, whilst making sure cache is turned off.
After that, rename the template directory catalog to ~catalog and let it pick up the base catalog directory and see if it's actually the .phtml files causing the problem.
I asked this question yesterday Static block on home page in Magento, which answered my question about hooking a cms/block to an existing block (content, in that example).
But now I would like to know how to create my own block.
I have this in my .phtml template:
<?php echo $this->getChildHtml('home_flash') ?>
And this in my cms.xml file
<reference name="home_flash">
<block type="cms/block" name="home-page-flash" before="content">
<action method="setBlockId"><block_id>home-page-flash</block_id></action>
</block>
</reference>
But this is not working.
I have also tried to create my own block type, (by copying the breadcrumbs declaration) in the page.xml file:
<block type="page/html_home_block" name="home_block" as="home_block" template="page/template/home_block.phtml"/>
That file exists but isn't being rendered.
However when I reference the block like this:
<block type="page/html_breadcrumbs" name="home_block" as="home_block" template="page/template/home_block.phtml"/>
It renders my home block template, but the original cms/block is not attached to it.
Hope all the different cases show what is happening and highlight the gap in my knowledge well enough for someone to answer, do I have to "register" my new "home_block" type somewhere?
There are many different blocks available that you can use without creating your own. In this case I think core/text_list would be suitable because it doesn't require a template and can have as many child blocks within it as you need.
<?xml version="1.0"?>
<layout version="0.1.0"><!-- All layout files start with this -->
<cms_index_index><!-- Index directive is the same as "home" page -->
<reference name="root"><!-- For more blocks that can be referenced see "default" directive -->
<block type="core/text_list" name="home_flash">
<block type="cms/block" name="home-page-flash">
<action method="setBlockId"><block_id>home-page-flash</block_id></action>
</block>
</block>
</reference>
</cms_index_index>
<!-- More directives might go here -->
</layout>
Other useful block types worth knowing are core/text and core/template which correspond to Mage_Core_Block_Text and Mage_Core_Block_Template respectively. They get used the most.
Your home made block type of page/html_home_block didn't have any PHP class with a matching name, and if you were genuinely creating your own you wouldn't be able to use the page prefix since Magento already does.
To create a block you only need a <block> tag in the layout file.
To create a block type you need to write a PHP class, give it a namespace and declare it as part of a module.
To add to an existing block is the time when you use a <reference> tag.
There are many fine articles at Magento Knowledge Base including some on Theming & Design.