Reputation: 3319
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!
Upvotes: 2
Views: 5944
Reputation: 14182
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.
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:
core_block_abstract_to_html_before
mentioned in the post linked to in the commentscore_collection_abstract_load_before
event and add a html agreement on the flycheckout/agreements
block and overload the _toHtml()
methodMy recommendation would be to somehow make use of the checkout.onepage.review.info.items.after
block - that solution would be so much nicer.
Upvotes: 7