Hi,

I have created custom content types in Drupal 7. For the sake of discussion, let's say I have a content type called "cdr". I have succeeded in creating a custom template file called "node--cdr.tpl.php", which lets me decide how the information will be displayed. Now, I would also like to theme the edit and create forms...

I have tried creating a slew of template files for this ("node--cdr--edit.tpl.php", "node--cdr-edit.tpl.php", "node--edit--cdr.tpl.php", "node_edit--cdr.tpl.php", "node--cdr--form.tpl.php", "node--cdr-form.tpl.php", "node--form--cdr.tpl.php", "node_form--cdr.tpl.php"), all to no avail.

Seeing as how the Drupal 7 documentation is pretty sparse at this point, I was wondering if anybody knew the proper file name? Thanks for the help.

Comments

WorldFallz’s picture

Not sure about d7, but in previous versions there are no default template suggestions for forms, you need to create them manually. See http://drupal.org/node/223440 and http://drupaldojo.com/session/fine-tuning-ui-theming-forms-drupal-60 for how this was done for d6.

Anonymous’s picture

Thanks for the fast reply. I'll have a look at that, see if I can get it to work in d7 and get back to you.

Anonymous’s picture

Couldn't get it to work on d7, whereas I got it to work in 10 minutes on d6, so it's back to d6 for now. Thanks for the help!

WorldFallz’s picture

hmm.... if i get it working in d7 i'll post back. but at least you've got something for now.

basil.shine’s picture

You can make this work by implemeting this hook_theme to your module. it's almost the same as it was in drupal 6.
But there also problem that $variables['form'] is empty. I want to ask someone to help with that.

/**
 * Implements hook_theme().
 */
function hook_theme($existing, $type, $theme, $path) {
  return array(
    'node-type_node_form' => array(
      'variables' => array(
          'form' => NULL,
      ),
      'template' => 'node_type-node-form',
    ),
  );
}
Raphael Apard’s picture

Use "arguments" instead of "variables" and add 'render element' => 'form'.

/**
* Implements hook_theme().
*/
function mythemeormodulename_theme() {
  return array(
    'node-type_node_form' => array(
      'arguments' => array(
          'form' => NULL,
      ),
      'template' => 'node_type-node-form',
      'render element' => 'form',
    ),
  );
}

in your template node_type-node-form.tpl.php use drupal_render_children() instead of drupal_render().

Raphael

Anonymous’s picture

I've switched over to D6 for this project, but I'll get back to you when I'm back top D7.

Csabbencs’s picture

This topic should really be picked up by a drupal developer.

WdKi: your code snippet does not work in D7, though it is the right way how you do it in D6.

I've spent some hours googling the net looking for the way I could theme the form (edit tab) of my custom content type.
No success.
I've checked some sites and watched some video workshops where they mention - what we already know - that the template file for theming your content type in view mode should be named as "node--custom_content_type.tpl.php". Then, without explicitly showing a working example, they make you feel that the file for edit mode should be named as "node--custom_content_type--edit.tpl.php" and you don't need hook_theme() in template.php.

The official documentation on converting D6 themes to D7 says: "Suggestions which have additional arguments like page--user--edit.tpl.php remain the same;"
"page--user--edit.tpl.php" actually works!
I really think "node--custom_content_type--edit.tpl.php" should do so. Please guys, tell us why not and give a solution!

manhhainet’s picture

i tried node--custom_content_type--edit.tpl.php, but it not run

Csabbencs’s picture

Finally found a solution:
- you need function hook_theme()
- you need to create a module and put the function in there like

/**
* Implements hook_theme().
*/
function mymodulename_theme() {
  return array(
    'node-type_node_form' => array(
      'arguments' => array(
          'form' => NULL,
      ),
      'template' => 'node_type-node-form',
      'render element' => 'form',
    ),
  );
}

If you put the function in template.php like

function mythemename_theme() {
 ...
}

it won't work!

WdKi: I revert. Your solution is almost OK, in D6 both ways do the trick, we couldn't suspect that in D7 only the 'module' way does.

.zLaW’s picture

Howdy,

I made a custom content type containing two taxonomy term reference fields with checkboxes. My goal was to theme the two checkbox fields to show up beside each other using float: left divs. The content type (machine name) is "elisa" and the two fields are "field_elisa_type" and "field_elisa_var".

I'm using a subtheme of Adaptive Theme for D7 called lab_book, if it matters. Just a stock copy of the starter subtheme, actually.

I added the following to my template.php file:

function lab_book_theme() {
  return array(
    'elisa_node_form' => array(
        'arguments' => array('form' => NULL),
        'template' => 'elisa',
        'render element' => 'form',
    ),
  );
}

Then I made a "elisa.tpl.php" file, sitting in the root folder of my subtheme that contains the following code:

<div>
 Custom content type override in Drupal 7
</div>

<!--Print the title input field-->
<div>   
 <?php print drupal_render($form['title']); ?>
</div>

<!--Print the body input field-->

<div>
 <?php print drupal_render($form['body']); ?>
</div>

<div style="clear: both;"></div>

<!--Print the two taxonomy checkbox fields floated left-->

<div style="float: left; padding-left: 20px;">
<?php print drupal_render_children($form['field_elisa_type']); ?>
</div>

<div style="float: left; padding-left: 20px;">
<?php print drupal_render_children($form['field_elisa_var']); ?>
</div>

<div style="clear: both;"></div>

<!--Print the rest of the form-->
<div>
 <?php print drupal_render_children($form); ?>
</div>

Works as wished for, rendering titel/body/floated checkboxes and finally the rest of the form and buttons.

Notice that the title and body fields are printed with "drupal_render" and the other fields (including the rest of the form at the end) are printed with "drupal_render_children". Why? I am not sure but it only works this way. Any insights would be appreciated.

Hope that this helps someone.

.zLaW

Anonymous’s picture

Couldn't get either Csabbencs' or .zLaw's solutions to work.

Here's what did work.

  1. Create a module to call hook_theme() from.
  2. Put in the following code :
    <?php
    function moduleName_theme() {
    	return array(
    		'nodeType_node_form' => array(
    			'template' => 'nodeType-node-form',
    				'render element' => 'form',
    		),
    	);
    }
    ?> 
    	
  3. Create a file called : "nodeType-node-form.tpl.php" and place it in your templates directory.
  4. To render the form from within the template file, use :
    <?php print drupal_render_children($form); ?>

Seems weird that this needs to be done from a module... One would expect it to work from the template.php file, as this was the file that managed theme related-processes traditionally. Anyone have any ideas on this?

Choy

ishmael-sanchez’s picture

One thing that tripped me up and could be messing up other people is the path of the template file. If you are copy and pasting code from this thread and your theme has a templates folder you have to update the template path.

function YOURTHEME_theme() {
  return array(
    'YOURNODETYPE_node_form' => array(
      'arguments' => array(
          'form' => NULL,
      ),
      'template' => 'templates/YOURNODETYPE-node-form', // set the path here if not in root theme directory
      'render element' => 'form',
    ),
  );
}

Nolza’s picture

thank you for this, the above worked for me.

sstacks’s picture

In D7, Choy's method allowed me to theme the add node form for a custom content type.

Best,
Shane

sstacks’s picture

This might also be helpful, once you are actually building out the form in NODETYPE-node-form.tpl.php

Render individual form elements:
print render($form['field_date']);
(note: in this case, the element name is "field_date", you will of course need to change that part.

Render all form elements, or else the remaining form elements that have not already been called on the page:
print drupal_render_children($form);

Best,
Shane

arrjaycee’s picture

Hi,

The code above worked for me in D7. I had to put my template file in the module's directory. I'm not sure why drupal was looking for the template file in the module directory and not in the theme's directory.

Thanks

aangel’s picture

Likely because modules can have template files so Drupal looks there first if you've placed the hook_theme() function in a module (as opposed to in template.php).

Elin Yordanov’s picture

tpl files must be named with using of hyphens instead underscores.

Wrong: node--custom_content_type--edit.tpl.php
Right: node--custom-content-type--edit.tpl.php

Though, i am not sure if that works. I just wanted to point to the naming of files.

Old usernames: pc-wurm, Елин Й.

kingjohnnet’s picture

Make sure the checkbox is not selected in the ADMINISTRATION THEME section at the bottom of the Appearance page
http://localhost/home#overlay=admin/appearance

wesnoel’s picture

I really can't get this to work. Is there no real documentation on this?
I have googled so much and this is the only thread I can find.

I tried adding the last version of that code above in my template.php file as below.

function goofball_theme() {
	
  return array(
    'daily-gooball_node_form' => array(
      'arguments' => array(
          'form' => NULL,
      ),
      'template' => 'templates/daily-goffball-node-form', // set the path here if not in root theme directory
      'render element' => 'form',
    ),
  );
}

What else do I need to do? Am I missing something?

I know this is an older post, but can somebody explain this to my like I am a 36 year old non developer?

I would really appreciate it.

Cheers,

Wes/

julien.reulos’s picture

None of above examples were working for me either.
But...there is actually a official documentation, that indicates how to do it, with a module or with template. The module version works for me.

Theming Node Forms in Drupal 7: http://drupal.org/node/1092122

Others useful pages:
http://drupal.org/node/983864
http://drupal.org/node/1200216
http://drupal.org/node/1251718
http://www.digett.com/blog/05/26/2011/how-theme-comment-form-drupal-7

callumrexter’s picture

Have you checked your spelling, in the code above you have "goofball", "gooball" and "goffball" - maybe the problem?

wemmies’s picture

I added:

if (!empty($vars['node']) && arg(2) == 'edit') {
    $vars['theme_hook_suggestions'][] = 'page__node__' . $vars['node']->type .'__edit';
  }

to the function themeName_preprocess_page(&$vars) {}

This allowed me to use: page--node--[contentType]--edit.tpl.php

also don't forget to clear your drupal cache to get the new tpl to show

mamanerd’s picture

Here's what works for me:

  1. Add the following code to your theme's template.php file, replacing MYTHEMENAME with the name of your theme and CONTENTTYPE with the machine-readable name of your content type. Make sure both are lowercase in your actual code.
    <?php
    function MYTHEMENAME_theme() {
      return array(
        'CONTENTTYPE_node_form' => array(
          'arguments' => array(
              'form' => NULL,
          ),
          'template' => 'templates/CONTENTTYPE-node-form', // set the path here if not in root theme directory
          'render element' => 'form',
        ),
      );
    }
    ?>
    
  2. Create a blank file called "CONTENTTYPE-node-form.tpl.php" (replacing CONTENTTYPE with the machine-readable name of your content type, all lowercase) and place it in your MYTHEMENAME/templates directory. So it should be MYTHEMENAME/templates/CONTENTTYPE-node-form.tpl.php.
  3. Clear your caches to make sure the template file is picked up by the registry.
  4. Place the following code in the new .tpl.php file that you just created. This will render the entire standard node edit form. To print specific node form fields, see Step #5.
    <?php 
    print drupal_render_children($form); 
    ?>
  5. If you have the Devel module installed, you can then call dpm($form) in your new .tpl.php file to navigate through the form object and see what fields are available to print. For example:
  6. <?php
    print drupal_render_children($form['something1']['something2']);
    ?>
julescone’s picture

Thanks Mamanerd for the detailed notes on how to do this.

I had tried implementing this earlier and I couldn't get it to work, but i just revisited it and I noticed that I have missed a replacement of CONTENTTYPE in the 'CONTENTTYPE_node_form' => array( line.

Fixed that up, and we are good to start hacking!

Cheers, Jules

neilhanvey’s picture

Many thanks for writing it out in such a clear way. I modified it a bit and managed to do it a slightly different way.

I used the following to place all my individual form elements and it's all working really well

print drupal_render($form['title']);
print drupal_render($form['body']);
print drupal_render($form['actions']['submit']);
print drupal_render($form['actions']['preview']);
print drupal_render($form['actions']['delete']);
etc

One thing i can't figure out how to do is to output the menu settings, revision information, comment settings, etc.
Any ideas or pointers? I do have the Devel module installed but I'm not really sure what i should be looking for in the object view.

I did call dpm($form) but it just seemed to output a lot of unformatted code to the page like below so i'm not sure something is right in my setup somewhere!

"-element" onMouseOver="krumo.over(this);" onMouseOut="krumo.out(this);"> <a class="krumo-name">#node_edit_form</a> (<em class="krumo-type">Boolean</em>) <strong class="krumo-boolean">TRUE</strong> </div> </li> <li class="krumo-child"> <div class="krumo-element krumo-expand" onClick="krumo.toggle(this);" onMouseOver="krumo.over(this);" onMouseOut="krumo.out(this);"> <a class="krumo-name">#attributes</a> (<em class="krumo-type">Array, <strong class="krumo-array-length">1 element</strong></em>) </div> <div class="krumo-nest""

rennevat’s picture

Add

print drupal_render_children($form);

at the bottom of your template to render all the fields you haven't previously rendered, including menu settings, revision, etc.

Bill Choy’s picture

Thanks Mamanerd, it worked. But the form elements where all unsorted.

For some reason drupal_render_children() doesn't call element_children($element, TRUE) to sort the elements. So I had to presort the form.
PS: Had to save the rendered child into a variable, so the page flowed in the printed version

  uasort($form['group_article_right_column'], 'element_sort');
  $right_column = drupal_render_children($form['group_article_right_column']);

Hiking up the Drupal learning developer curve

andyanderso’s picture

First of all thanks to all of you for this topic. It has worked for me to use the template.php method for theming one content type form. I actually want to theme more than one of my content type forms so here is what worked for me per this thread: http://drupal.org/node/480698#comment-1659314

function uac_theme() {
return array(
    'advisory_node_form' => array(
      'arguments' => array(
          'form' => NULL,
      ),
      'template' => 'templates/advisory-node-form', // set the path here if not in root theme directory
      'render element' => 'form',
    ),
    
    'forecast_node_form' => array(
      'arguments' => array(
          'form' => NULL,
      ),
      'template' => 'templates/forecast-node-form', // set the path here if not in root theme directory
      'render element' => 'form',
    ),
    
  );
}
codemuppet’s picture

Some of the confusion in this thread may be coming from the use of the seven theme in Drupal 7's overlay. Changes in your own themes template.php file are not going to show if the theme popping up in the admin overlay is different.

jaxx0rr’s picture

people->permisions->view administration theme (UNCHECK for auth users)

then all u have to write in the template.php file located at (bluemasters is my theme)
\sites\all\themes\bluemasters\template.php

function bluemasters_form_alter(&$form, &$form_state, $form_id) {
drupal_set_message("This is the form id : $form_id");
}

now when u click add article you should see the message
and ofc u can change stuff but thats another story...