I'm running 1.9.x and have 3 different payment methods, amazon payments, paypal express, sage pay and a continue shopping button. On the cart page I am attempting to reorder how these appear in the checkout-types UL.
I currently have the below which I believe is default
<ul class="checkout-types">
<li><?php if($this->getContinueShoppingUrl()): ?>
<button type="button" title="<?php echo $this->__('Continue Shopping') ?>" class="button btn-continue btn-inline" onclick="setLocation('<?php echo $this->getContinueShoppingUrl() ?>')"><span><span><?php echo $this->__('Continue Shopping') ?></span></span></button>
<?php endif; ?></li>
<?php foreach ($this->getMethods('top_methods') as $method): ?>
<?php if ($methodHtml = $this->getMethodHtml($method)): ?>
<li><?php echo $methodHtml; ?></li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
My aim is to have the pay now button which goes into the one page checkout button appear after the continue shopping button and then amazon and paypal. I have spent hours looking through the code and can't seem to find a way to change the sort order on the $method array.
The getMethods($name) method will actually fall for sorting to the configuration in the layout files.
As an example for top_methods which is an alias in the layout, it will look for all the updates on that handle from XML files in the system, in case of PayPal it will be, Considering that RWD is the package you are using :
app/design/frontend/rwd/default/layout/paypal.xml
And this is the xml block part for it:
<block type="paypal/express_shortcut" name="checkout.cart.methods.paypal_express.top" before="checkout.cart.methods.onepage.top" template="paypal/express/shortcut.phtml">
<action method="setIsQuoteAllowed"><value>1</value></action>
<action method="setShowOrPosition"><value>after</value></action>
</block>
In this default theme configuration, the paypal express checkout is placed before the block checkout.cart.methods.onepage.top which is configured to be the last block in top_methods with the after="-" :
<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.top" template="checkout/onepage/link.phtml" after="-" />
</block>
So in conclusion, what you need to do is to go through the XML layout files for the payment methods you are using, and set the before and after depending on the sort you need. if you have cache enabled, you will need to flush it and you should get the result intended.
An example would be:
Change display order of checkout buttons in Magento
adding the following to the checkout layout sorted the issue
before="checkout.cart.methods.amazonpayments_pay.top"
Related
I'm fairly new to magento, using CE 1.9.
I know how to remove / add tabs on the product page via local.xml
However I'm trying to hide/show a tab based on the value of an attribute of the product.
I have created a custom tab successfully. Additionally the customTab.phtml file I created I was able to get an if statement to work successfully... sort of...
Here is my code inside the phtml file:
<?php
$staticBlockId = 'block_product_tab2';
$product = Mage::registry('current_product'); ?>
<?php if($product->getRepairservice()): ?>
<div class="std"><?php echo $this->getLayout()->createBlock('cms/block')->setBlockId($staticBlockId)->toHtml(); ?></div>
<?php endif; ?>
This will successfully hide or show "content" of the tab based on the boolean value of the attribute. However it still is showing the tab, it's just empty.
So I'm thinking I need to go to where it's created in local.xml but I'm not sure how to structure the if statement or get access to the attribute. Any help would be appreciated.
I think the most clear way of doing this is by creating your own layout handle, see: http://inchoo.net/magento/custom-layout-update-handles/. There you've to check if you're on a product page and then check your getRepairservice(), for example:
// Inside the controllerActionLayoutLoadBefore() function of Inchoo's example
$layout = $observer->getEvent()->getLayout();
$product = Mage::registry('current_product');
if($product && $product->getRepairservice())
{
$layout->getUpdate()->addHandle('REPAIR_SERVICE')
}
After that you can add your tab nicely with XML.
<REPAIR_SERVICE>
<reference name="product.info">
<block type="catalog/product_view_description" name="product.new.tab" as="new.tab" template="catalog/product/view/mynewcustomtab.phtml">
<action method="addToParentGroup"><group>detailed_info</group></action>
<action method="setTitle" translate="value"><value>Custom Tab</value></action>
</block>
</reference>
</REPAIR_SERVICE>
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.
I have a Magento site and I disabled the pop up on the compare file so now it loads in a blank page. What I need is to make the "Compare Products" load in the same page but still keep everything as is (design, menus etc).
Thank you
Go to the your custom theme folder
open this file
your_custom_theme\template\catalog/product/compare/sidebar.phtml
Replace with this button
<button type="button" title="<?php echo $this->__('Compare') ?>" class="button" onclick="setLocation('<?php echo $this->htmlEscape($_helper->getListUrl()) ?>')"><span><span><?php echo $this->__('Compare') ?></span></span></button>
From this button
<button type="button" title="<?php echo $this->__('Compare') ?>" class="button" onclick="popWin('<?php echo $_helper->getListUrl() ?>','compare','top:0,left:0,width=820,height=600,resizable=yes,scrollbars=yes')"><span><span><?php echo $this->__('Compare') ?></span></span></button>
Find this and update on your catalog.xml( find this catalog_product_compare_index and change the template name) layout file
<catalog_product_compare_index>
<reference name="root">
<action method="setTemplate"><template>page/1column.phtml</template></action>
</reference></catalog_product_compare_index>
May be it will help you (Note: Don't make changes on the default theme )
Copy the sidebar.phtml from the bellow location
'app\design\frontend\base\default\template\catalog\product\compare'
Put it in your new created theme ( theme name according your choice ) ya existing theme in same directroy strature
'app\design\frontend\default\your_theme_name\template\catalog\product\compare'
change the button as i said my previous answer
Than go to your admin
system --> design --> Add design change --> Custom Design --> select your_theme_name (from the dropdown) save
Find catalog_product_compare_index from catlog.xml file from your your_theme_name
'app\design\frontend\default\your_theme_name\layout\'
and change the bellow line code
<reference name="root">
<action method="setTemplate"><template>page/popup.phtml</template></action>
</reference>
to
<reference name="root">
<action method="setTemplate"><template>page/1column.phtml</template></action>
</reference>
All Done
Your answer is good but you made a little mistake in the last step.
You said to find catalog_product_compare_index from catalog.xml in the following location:
'app\design\frontend\default\your_theme_name\layout\'
The correct location is:
'app\design\frontend\your_theme_name\default\layout\'
If a beginner reads this he wouldn't understand the difference and wouldn't find the file.
I'm a beginner and I was stuck here for a moment.
I am looking to track down the file (and it's location) that generates the "Proceed to Checkout" button in the Magento cart.
Try adding a product to the cart, and then proceeding to the cart. The "Proceed to Checkout" button is on the right hand side of the cart.
I am using a hacked-about variation of the blank theme, if that makes any difference.
Thanks in advance for your help.
The code that produces the Proceed to Checkout link is in templates/checkout/onepage/link.phtml
By default the block for it is in checkout.xml;
<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>
app/design/frontend/your_package/your_theme/template/checkout/onepage/link.phtml
The "Proceed to Checkout" button that leads to the onepage checkout, is generated with this template : checkout/onepage/link.phtml.
You should be able to know what buttons are added with which templates by looking at the checkout_cart_index handle of the checkout.xml layout file. The block named checkout.cart.methods contains all the buttons, and the two base checkout buttons should be added to it directly in the same file.
Go to System -> Configuration -> Developer change a Current Configuration Scope to some of your websites or stores than go to Debug section - and change Template Path Hints setting to "Yes". Now, on frontend, you'll see an full path to your template file on a filesystem for every block that rendered, so now you can see where your template (that renders a link) exists.
Open this path in your root directory
/app/design/frontend/base/default/template/checkout/onepage/link.phtml
find this code
<?php if ($this->isPossibleOnepageCheckout()):?>
<button type="button" title="<?php echo Mage::helper('core')->quoteEscape($this->__('Proceed to Checkout')) ?>" class="button btn-proceed-checkout btn-checkout<?php if ($this->isDisabled()):?> no-checkout<?php endif; ?>"<?php if ($this->isDisabled()):?> disabled="disabled"<?php endif; ?> onclick="window.location='<?php echo $this->getCheckoutUrl() ?>';"><span><span><?php echo $this->__('Proceed to Checkout') ?></span></span></button>
<?php endif?>
I'm building an extension to add a specific block right before the 'Place Order' button in Magento's Onepage checkout. I'm having some trouble finding the right incantations to simply append a block to this section, much less get it before/after another handle. The object is to engage this override without any template changes.
In my extension's XML, I have:
<checkout_onepage_review>
<reference name="root">
<block type="myextension/blockname" name="myextension.block" template="myextension/block.phtml" before="checkout.onepage.review.button" />
</reference>
</checkout_onepage_review>
myextension/block.phtml is, for now, just a simple block of text. I know the general syntax is correct, as I'm able to add my <block> to checkout_cart_index and see it just fine.
Am I missing something basic?
Thanks!
Background
Not all blocks output their children blocks automatically. Only blocks of the core/text_list type and templates where echo $this->getChildHtml() (no arguments) s called.
Children of template blocks are rendered by a call to echo $this->getChildHtml('child_alias').
It makes sense if you think about it - children of template blocks need to be positioned somewhere in the context of the template HTML.
Referring to your question, there is no functional difference between the layout handles checkout_onepage_review and checkout_cart_index besides them referring to different pages.
Adding content to the checkout review
The checkout review block contains two core/text_list children to whom you can add children using layout XML that will automatically be displayed.
<checkout_onepage_review>
<reference name="checkout.onepage.review.info.items.before">
<block type="core/text" name="review.test.1">
<action method="setText">
<text>Test Block Before</text>
</action>
</block>
</reference>
<reference name="checkout.onepage.review.info.items.after">
<block type="core/text" name="review.test.2">
<action method="setText">
<text>Test Block After</text>
</action>
</block>
</reference>
</checkout_onepage_review>
The only problem is that the checkout.onepage.review.info.items.after block is rendered before the agreements block, so in your case it might not be good enough.
The agreements are rendered with this code:
<?php foreach ($this->getAgreements() as $_a): ?>
<li>
<div class="agreement-content"<?php echo ($_a->getContentHeight() ? ' style="height:' . $_a->getContentHeight() . '"' : '')?>>
<?php if ($_a->getIsHtml()):?>
<?php echo $_a->getContent() ?>
<?php else:?>
<?php echo nl2br($this->htmlEscape($_a->getContent())) ?>
<?php endif; ?>
</div>
<p class="agree">
<input type="checkbox" id="agreement-<?php echo $_a->getId()?>" name="agreement[<?php echo $_a->getId()?>]" value="1" title="<?php echo $this->htmlEscape($_a->getCheckboxText()) ?>" class="checkbox" /><label for="agreement-<?php echo $_a->getId()?>"><?php echo $_a->getIsHtml() ? $_a->getCheckboxText() : $this->htmlEscape($_a->getCheckboxText()) ?></label>
</p>
</li>
<?php endforeach ?>
If you want to add a block after the agreements, right before the "Place Order" button, without changing the template, and without rewriting the agreements block, you can try to add an additional item to the end of the checkout/agreements collection, having is_html set to true, and your output as the content.
This turns out to be problematic, though, because the agreements model, resource, and collection don't offer a custom event prefix.
What this boils down to, if the provided checkout.onepage.review.info.items.after block doesn't work, are the following options. Each one is ugly in it's own way, so the choice of the smallest evil is yours:
Observe the core_block_abstract_to_html_before mentioned in the post linked to in the comments
Observe the core_collection_abstract_load_before event and add a html agreement on the fly
Rewrite the checkout/agreements block and overload the _toHtml() method
My recommendation would be to somehow make use of the checkout.onepage.review.info.items.after block - that solution would be so much nicer.