Let us consider i am working with registration form and i want to add new field in it say "Company". here I know all the process of creating module and add field in /customer/form/register.phtml file, but i want to do it in different way.
Here is my query, i want to do this with the help of xml file in which i create my new xml file and give reference to customer_form_register block with new .phtml file (without editing /customer/form/register.phtml) with all back end process of creating module same.
Problem
I now understand your question is asking if you can insert additional form fields on the customer register form without editing the customer/form/register.phtml template. Unfortunately, in Magento’s layout I don’t believe there is currently a way to create a reference to a block inside of another reference except from within the same. So, while there is not a very clean way to do this using only layout XML, there is one way you could accomplish it...
A Possible Solution
In order to insert a new child block into the customer_form_register block, we need to override the layout definition for that block. That is not ideal because you replace any other definitions of that block, so you need to be careful to incorporate any other necessary layout updates into your new one as well. One to consider is that this block gets redefined in captcha.xml, so if you need that functionality you need to add in those updates to your new definition as well.
We will then be inserting a new block, customer.form.register.newsletter. This is because that child block name is already being invoked in the register.phtml template like this $this->getChildHtml('customer.form.register.newsletter'), but it does not seem to be used for anything else that I noticed. So once we have defined our new block with this name, it will be inserted into the page below the existing newsletter checkbox:
<customer_account_create>
<reference name="content">
<block type="customer/form_register" name="customer_form_register" template="customer/form/register.phtml">
<block type="page/html_wrapper" name="customer.form.register.fields.before" as="form_fields_before" translate="label">
<label>Form Fields Before</label>
</block>
<!-- This is our new block. -->
<block type="core/template" name="customer.form.register.newsletter" template="customer/form/custom_register.phtml"/>
</block>
</reference>
</customer_account_create>
Alternative
I think you may want to consider something like this extension instead, since it seems to make it easy to add custom registration fields.
Related
I have a contact form template (modal.phtml), which I want to add to all pages on my site, but I need to be able to position it precisely, so I want to insert into the relevant page templates using $this->getChildHtml('contacts-modal'), instead of inserting via layout xml. So in page/2columns-right.phtml, I want to use that call to insert the template stored in contacts/modal.phtml. The layout xml i have below is automatically inserting this template - how do i go about correcting this? Thanks for any pointers, and apologies if this is a very basic thing!
<reference name="content">
<block type="core/template" name="contacts-modal" as="contacts-modal" template="contacts/modal.phtml"/>
</reference>
If you want to insert the template with $this->getChildHtml('contacts-modal') you have to declare it in the layout xml, look into the class Mage_Core_Block_Abstract to see how getChildHtml works.
If you want to add it to other pages that don't have 2columns-right as main template, you have to add the xml reference like you did with 2columns-right, or you can use inside the parent template echo $this->getLayout()->createBlock('core/template')->setTemplate('contacts/modal.phtml')
I currently have this:
<block type="core/text" name="top.address" as="topAddress">
<action method="addText"><text>PO BOX 1124, Rockdale, Sydney, NSW 2216, Australia</text></action>
</block>
But, when I need to update address, I have to do it manually here in the layout file. I want to pull address from store config ( general/store_information/address ) so, I can update everywhere on the site from one location easily.
I guess it can be done directly on the template like this:
<?php echo Mage::getStoreConfig('general/store_information/address') ?>
But I want to try with layout, is it possible?
Thanks.
My answer might be to oudated, but I faced with such problem just now I found an alternative way to solve it:
In layout you can specify core/text block and set its text via helper. You can use any suitable reference.
<reference name="before_body_end">
<block type="core/text" name="some.config">
<action method="addText">
<text helper="module_name/data/getSomeConfig" />
</action>
</block>
</reference>
Declare getSomeConfig function in the helper:
public function getSomeConfig()
{
return Mage::getStoreConfig('your_config_path');
}
In a such way you can even pass some dynamic data into javascript code.
Short answer - no. There is no functionality for it. That's not to say that it couldn't be done. There is an attribute that you can use on an action tag - ifconfig. It looks to see if a system config flag is set, and if it returns true, then it will proceed with the action. You could override or extend Mage/Core/Model/Layout.php to add that functionality.
There are a number of options to this problem, though.
You can use templates, like you mentioned.
If you are wanting to avoid a template, you can create a block that extends Mage_Core_Block_Text and specify the _toHtml method, with the code that you provided.
The best: I would see creating a generic block in a generic module that is used to pull system config requests and output them as text. You could either have it be a custom action/method, or send along an attribute value, which will end up in the data array for the block, which you could then lookup in _toHtml.
For example, I want to put my block on the product page before the description block. How would I find these reference names?
If I understand correctly, based on your question and subsequent comments, you are looking for a way to position blocks before other blocks in the layout?
If so, the layout system provides you with before and after block attributes, for this exact purpose.
The general use is to add a before or after attribute containing the block you would like to position - before or after.
Before Example
<block type="yourmodule/block_type" name="yourblock" before="the_block_name_to_position_before" />
After Example
<block type="yourmodule/block_type" name="yourblock" after="the_block_name_to_position_before" />
Positioned before product description
In your particular scenario, where you would like a block to be positioned before the product description block, you need a little extra xml due to how the product description block is being included into the layout:
<!-- file: app/design/frontend/your_package/your_theme/layout/local.xml -->
<catalog_product_view>
<reference name="product.info">
<block type="yourmodule/block_type" name="yourblock" template="yourmodule/template.phtml" before="product.description">
<action method="addToParentGroup"><group>detailed_info</group></action>
</block>
</reference>
</catalog_product_view>
The important thing to note here though, in terms of you original question, is the use of the before attribute for positioning.
In the Magento Control Panel set your Current Configuration Scope to a specific website. Then, under System -> Configuration -> Advanced -> Developer -> Debug` turn on Template Path Hints and Add Block Names to Hints.
After that, when you reload the page it will tell you what blocks to override to get the desired effect.
Having trouble setting a block template in Magento's layout xml. I'm attempting to set the template of a child block, not the entire page layout (almost all docs out there explain how to set template of the layout).
Background: I'm updating a layout handle in my custom action, using the <update /> tag in my module's layout xml.
Essentially, I want to reuse the layout and blocks of the built in product view action, but provide custom templates for a few blocks. (Not just overrides, these need to be brand new templates that are only triggered on my custom action and are themselves overrideable).
My layout html:
<?xml version="1.0"?>
<layout version="0.1.0">
<mymodule_product_index>
<update handle="catalog_product_view" />
<reference name="content">
<block type="catalog/product_view"
name="product.info" output="toHtml" template="mymodule/product.phtml" />
</reference>
<reference name="product.info.bundle">
<action method="setTemplate"><template>mymodule/customtemplate.phtml</template></action>
</reference>
</mymodule_product_index>
</layout>
The setTemplate on product.info.bundle never works; it doesn't seem to affect layout at all. I've tried wrapping the <reference> in other <reference> nodes from parent blocks with no effect. Is it possible to replace block templates in this way? I feel that my problem stems from the fact I'm using an <update />.
By the way, I know my layout xml is being loaded and there are no errors, the rest of the file is working fine, caching is disabled, have cleared cache anyway, etc.
Your approach is almost correct.
Two things:
1. Set a new template instead of instantiating a new block
Instead of just assigning a different template to the product.info block, you are creating a new instance with the same name, replacing the original instance, and then the new template is set on that. Instead use this:
<mymodule_product_index>
<update handle="catalog_product_view" />
<reference name="product.info">
<action method="setTemplate">
<template>mymodule/product.phtml</template>
</action>
</reference>
</mymodule_product_index>
That should take care of the product view template in a clean way.
2. Handle processing order
If you look at where the view block product.info.bundle for the bundled products is declared, you will see it happens in the bundle.xml file, in a layout update handle called <PRODUCT_TYPE_bundle>.
Your code is referencing the block from the <[route]_[controller]_[action]> layout handle, i.e. <mymodule_product_index>.
The thing to be aware of here is the processing order of layout handles.
Roughly it is:
<default>
<[route]_[controller]_[action]>
<custom_handles>
The <PRODUCT_TYPE_bundle> handle belongs to the third type of layout handles, which means it is processed after the <mymodule_product_index> handle.
In essence, you are referencing the block product.info.bundle before it has been declared.
To fix this you will need to use the <PRODUCT_TYPE_bundle> handle as well. Of course this will effect every bundled product display. Using layout XML only there is no clean way around that.
Here are a few suggestions how to solve that problem.
You could create a separate route in your module to show the bundled products, and then include the <PRODUCT_TYPE_bundle> handle using an update directive for that page, too.
In your custom action controller, you could add another layout update handle that is processed after <PRODUCT_TYPE_bundle>.
You could use an event observer to set the template on the product.info.bundle block if it is instantiated. One possibility would be the event controller_action_layout_generate_blocks_after.
You get the idea, there are many ways to work around this, but they require PHP.
I am using this code in my template file to display a static block in my left sidebar:
<?= $this->getLayout()->createBlock('cms/block')->setBlockId('leftSB1')->toHtml() ?>
I would like to exclude the block from one of my CMS pages. How do I do this?
I think it requires adding code to the 'Layout Update XML' section but I'm not sure what exactly.
Someone else can correct me here, but I'm fairly sure that you're going to have trouble trying to accomplish this given the way you called the block. Normal layout updates allow you to remove blocks, but those are blocks that were also created with the layout (e.g. the Layout object knows about them after you call loadLayout()).
In your case, you create the block on the fly and then immediately use it to echo some HTML. If you want to be able to delete it with layout updates, try moving it into the layout files first, then use the normal layout block removal method:
<reference name="your_parent_block_name">
<remove name="leftSB1"/>
</reference>
Otherwise, you could hide it either in the PHP (By setting some global variable and checking it before outputting the block. Poor form but it might work.) or in CSS. Let me know if any of these work for you.
Thanks,
Joe
Include the block in your layout instead:
<cms_page>
<reference name="left">
<block type="cms/block" name="leftSB1">
<action method="setBlockId"><id>leftSB1</id></action>
</block>
</reference>
</cms_page>
And then $this->getChildHtml('leftSB1') in your sidebar, if you're not including children automatically.
(and then remove it from the particular page as in the previous answer)