Last updated January 21, 2013. Created by rashad612 on March 14, 2011.
Edited by uniquename, joetsuihk, Soul88, DeeZone. Log in to edit this page.
Here is an example of how to theme the layout of a node form using the theme engine in Drupal 7. We will theme the article content type provided by default with Drupal 7.
Suppose that the article content type has a taxonomy field field_tags - I want to put the taxonomy field in a separated region called sidebar.
Also the form buttons will be extracted and printed as $buttons variable in a separate region.
Please note that Node form columns module can be used as an alternative method for this process.
First of all let's implement hook_theme(). You can implement it in your theme's template.php or your custom module. In our case we will do it in a custom module. Let's call it MYMODULE.
Our theme output will be through the template file article-node-form.tpl.php.
<?php
/**
* Implements hook_theme().
*/
function MYMODULE_theme($existing, $type, $theme, $path) {
return array(
'article_node_form' => array(
'render element' => 'form',
'template' => 'article-node-form',
// this will set to module/theme path by default:
'path' => drupal_get_path('module', 'MYMODULE'),
),
);
}
?>Then, we should define the preprocess function, for the theme hook article_node_form.
Here it will prepare the variables, sent to the template file.
<?php
/**
* Preprocessor for theme('article_node_form').
*/
function template_preprocess_article_node_form(&$variables) {
// nodeformcols is an alternative for this solution.
if (!module_exists('nodeformcols')) {
$variables['sidebar'] = array(); // Put taxonomy fields in sidebar.
$variables['sidebar'][] = $variables['form']['field_tags'];
hide($variables['form']['field_tags']);
// Extract the form buttons, and put them in independent variable.
$variables['buttons'] = $variables['form']['actions'];
hide($variables['form']['actions']);
}
}
?>After that, create the template page in the module directory.
In our case the template page will be: modules/MYMODULE/article-node-form.tpl.php. And its code :
<?php echo drupal_render_children($form)?>And you can edit the file such as:
<div class="node-add-wrapper clear-block">
<div class="node-column-sidebar">
<?php if($sidebar): ?>
<?php print render($sidebar); ?>
<?php endif; ?>
</div>
<div class="node-column-main">
<?php if($form): ?>
<?php print drupal_render_children($form); ?>
<?php endif; ?>
<?php if($buttons): ?>
<div class="node-buttons">
<?php print render($buttons); ?>
</div>
<?php endif; ?>
</div>
<div class="clear"></div>
</div>Please note that we used drupal_render_children($form); in Drupal 7 to render the rest of the elements of the form. It is essential to call this function as the form submit won't work otherwise.
The output of "drupal_render_children($form);" for the form with all the hidden elements looks like this:
<input type="hidden" name="form_build_id" value="form-9DoBKF-JQBgOvH7V6ygTI_-E9FiD77VGM5tzz6KFB_0" />
<input type="hidden" name="form_token" value="Ilw23wpvQ_NZ-wAV_VeMOgE-tfJ3wf4PBQ_XHIL18cI" />
<input type="hidden" name="form_id" value="my_super_form_id" /> Finally, create your own CSS styling :)
Comments
When implemented in a theme
shouldn't template_preprocess_article_node_form() be THEMENAME_preprocess_article_node_form()? Or should we consider the first definition of a theme function / template file to be where "template_" is used for the preprocess function?
benjamin, Agaric
Yes
Yes. But this example is implemented in custom module, not
template.php. Also in hook_theme you can define your own preprocess functions.Why name it as this???
Hi rashad612,I have a doubt of naming the theme hook,why be it must "article_node_form",not "article_add_node_form","article_node_form_add" and "article_n_form"?
I think there is a function somewhere,like hook_[node-type]_node_form,but I can't find it.
I ever themed the pages by using the template files from customed moudules,and the hook name's rule is free.
Why name it as this here???Help me,I just am confused at this.
Thanks.
form ID
I think it's the form ID for node form.
For reference on this,
For reference on this, http://drupal.org/node/1200216
No woman no cry
Thanks!This worked great for
Thanks!
This worked great for a form i.e when editing or adding my custom content-type node.
How can I achive the same, but when viewing the node. So I can call a preprocess function, and have my own tpl file in the module (not in the theme dir)
Cheers!
I used my own way
<?php
$elements = drupal_get_form('user_login_block');
$rendered = drupal_render($elements);
$elements['#action']='/YOUR-SITE/?q=node/YOUR-NODE-NUMBER?destination=user/'.$user->uid;
echo '<form action="' . $elements['#action'] .
'" method="' . $elements['#method'] .
'" id="' . $elements['#id'] .
'" accept-charset="UTF-8">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
User :
</td>
<td>
<input type="text" name="name" id="edit-name" class="form-text required" />
</td>
</tr>
<tr>
<td>
Password :
</td>
<td>
<input type="password" name="pass" id="edit-pass" class="form-text required" />
</td>
</tr>
<tr>
<input type="hidden" name="form_build_id" id="form-672874fd779fc88bee41ffbd690df686" value="form-672874fd779fc88bee41ffbd690df686" />
<input type="hidden" name="form_id" id="edit-user-login-block" value="user_login_block" />
<td colspan="2"><input type="submit" name="op" id="edit-submit" value="Log in" class="form-submit"/></td>
</tr>
</table>
</form>';
?>
Just Past this code in a node and create a link to that node in page.tpl.php of your theme.
That's it.
This is not good bro :)
This is not good bro :)
No woman no cry
not and not
Not good and not Drupal :)
Iam New to Drupal
Thanks for comments. Please help me to use custom templates for Default 'Login' and 'Request new Password' pages.
Here is how I override
Here is how I override commerce check out page
http://drupal.org/node/1200216
No woman no cry
removing panel with revisions / other settings from $form
very nice topic. thanks for sharing...
however i've been trying without success to remove or hide from the $form, the panel of Revision Information, Path URL Settings, and all other settings that i don't want to show in the Content Type Form, so that when i "print drupal_render_children($form)" it does not show up.
How can i do this? I have to find the variable name, but i can't find it!
thank you
If you would use this you
If you would use this you could try this..
Unset isnt the good idea at this point.. becouse then you wouldnt get any nicelooking path even if youre use pathauto.
unset($vars['form']['path']);
or better hide($vars['form']['path']);
But in your case I would try out simplify node add module :)
http://drupal.org/project/simplify_node_add
And maybe this would also work
$vars[form]['path']['type'] = 'hidden';
);
In this example, we have to
In this example, we have two features (or bugs, as you wish).
1. We can't create souch template in our theme folder. If we do so, it don't work. Only module template always used, also the another template exists in theme folder.
2. The key in returned array in function MYMODULE_theme MUST be exactly equal to 'article_node_form', because this is the form id we theming. There is possible variations, for example, for another content type: 'story_node_form', but NOT the 'node_story_form' or 'form_story_node' - because the core node module produce names for forms their form in hardcoded way.
Still can't figure it out :(
I hate when I fully don't understand things, I can't figure per the instructions what code does in what file name and exactly where they go. Could someone please provide a code structure example as the instructions don't explain clearly. Do I have to make a .module file somewhere?
Custom Module
This documentation shows you how to do it in a custom module. Functions:
MYMODULE_theme()andtemplate_preprocess_article_node_form()are supposed to be written in a module file replacing "MYMODULE" with your module name. The last template code is to be written in tpl file added by the custom module.Please note you need to replace "article" with your node/content type machine name.
A quick overview of "
hook_theme" will be useful.This worked in D7 without a module (fusion_starter theme)
I really didn't want to write a separate module, and I knew how to do this in D6, so after much experimenting, here's what I came up with for a custom content type of "faq" using the fusion_starter theme:
I added these lines to template.php:
<?phpfunction fusion_starter_theme($existing, $type, $theme, $path) {
return array(
'faq_node_form' => array(
'arguments' => array('form' => NULL),
'template' => 'node--add--faq',
'render element' => 'form',
),
);
}
?>
Then I created a template file called node--add--faq.tpl.php (same as the 'template' field in template.php.)
This is node--add--faq.tpl.php:
<?php
?>
<?php hide($form['field_postedby']); ?>
<?php hide($form['field_ans']); ?>
<?php hide($form['field_disp_date']); ?>
<?php hide($form['field_faq_stat']); ?>
<table >
<tr>
<td><?php print drupal_render_children($form['field_topic']); ?></td>
<td><?php print drupal_render_children($form['field_type']); ?></td>
</tr>
</table>
<?php print drupal_render_children($form); ?>
I'm hiding some fields that I don't want users to see using the 'hide' function, because style "display:none" still allowed them to be viewed.
I'm using the table to get two selection lists to be displayed next to each other. There must be a better way to do that, but this was easy and it worked.
The other fields in the content type could be listed individually using the 'drupal_render_children' the way I did in the table, but the last line takes care of all unspecified fields, so that worked for me.
Note: Since the Administrator is using a different theme, they will see all of the fields if they choose to create a FAQ of their own, or if they want to fill in the answer field, etc.
none widgets are wokking after customization
I have
<?phpprint drupal_render_children($form['field_artists']);
?>
field_artists is a file field to upload images
It renders fine. Shows browse button and upload. But when I upload an image it disapears. It sends only 2-3 ajax queries instead of 9-10 as node/%/edit form from default page.
Same with node reference "add new item" button. It searches nodes, and after click to add new, nothing happens.
I use seperate theme.
I declared hook_menu and hook_theme and create tpl file where I call render functions
Do you ever faced this problem before?
Mess with the best - die like the rest
How about this:<?phpprint
How about this:
<?phpprint render($form['field_artists']);
print drupal_render_children($form);
?>
Provide the template.php example for templating node forms
The "write your own module" option worked instantly, thanks for clear howto on that.
But before this, I spent a couple of hours trying to make this work without writing yet another module, including with what this thread had to offer:
http://drupal.org/node/1092122#comment-5705876
Could you consider also providing a functional example for the template.php alternative referred to in the original post and throughout the thread, including exact naming of functions and variables in template.php and node form .tpl.php file, and which Drupal versions it has been tested to work on?
(IMHO, affecting form layout without intention of changing the node form functionality should really be in the theme, not in a module - templating maintenance for my content type being one big reason, encapsulating what I'm working on for potential collaborators another - so if there's a way to get it done in the theme instead of yet another module, would surely appreciate the pointers)
We did it for Drupal 6
Time ago we wrote this solution originally for drupal 6 in theme's template.php
(http://drupal.org/node/859392), when Drupal 7 released, we chose to write it again, but as module.
Please note,
hook_theme()can be written intemplate.php, so you can implement it easily, with minor changes.Ditto
I just struggled for several hours trying to figure out how to do this with template.php, and I couldn't get it to work. Tried the module route, and it worked right off the bat.
I agree that this sort of thing really does belong in the theme, as it is a general theming issue, so a specific template.php example would be nice, if possible.
Found documentation on an external website
See if this what you were looking for.
http://bri-space.com/content/theming-contact-form-drupal-7-contactsiteform
I was hoping this page to be found on the drupal documentation :-/
--
Thank you for reading.