5

I am trying to add a textfield to the bottom of a node (for a specific cck type), that once (an authenticated user) submits, stores the value as a term in a taxonomy vocabulary.

What is the best way to do so?

I have tried adding the form to my subtheme's node.tpl.php file for a custom cck type.

I am having trouble with form validation. I'm able to submit the form properly, but get the red borders around the field that needs to be validated, instead of the message; Until I resubmit and the cached error message then shows. I get why it's happening - code executing prior to node.tpl.php load. See - How do I use form_set_error() the right way?.

If Form Builders are not supposed to be called from within a template file, how else can I add a form to a page? I'm sort of working off this form example tutorial

I started with this - Embed form inside a block - and since added this to my node.tpl - https://gist.github.com/1847060.

I'm still trying to wrap my head around using the forms api, so thanks for any advice.

3
  • I'm also adding this post to the research trail - drupal.org/node/1017790. Hopefully it gives someone else an idea while I wrap my head around it all.
    – Robbase
    Commented Feb 16, 2012 at 20:48
  • Which version of drupal? 6/7?
    – chrisjlee
    Commented Feb 16, 2012 at 22:29
  • Drupal 7, sorry!
    – Robbase
    Commented Feb 17, 2012 at 20:41

4 Answers 4

3

From what I've read and tried it seems like if you want the messages to appear correctly the form needs to be built latest in the template_preprocess_page() function. Doing it in template_preprocess_node() or in the theme template files is too late with Drupal 7. To put this into the code you could declare a variable that holds the form for your node template in your theme's template.php file:

function mytheme_preprocess_page(&$variables) {
  // For node templates.
  $variables['node']->my_form = drupal_get_form('form_name');
  // For page templates.
  // $variables['my_form'] = drupal_get_form('form_name');
}

Then you can render the form in your template file:

<?php print render($my_form); ?>

This way the messages appear when they should not one page call too late.

3
  • Brilliant - this works like a charm! Problem solved, I'm now able to render my custom form in node.tpl.php w/ all the moving parts working (alter, submit, validate).
    – Robbase
    Commented Feb 17, 2012 at 20:45
  • This will work too, though I would generally advise against putting something "functional" like a form in your theme. The reason being that if you want to switch the look of your site you will lose that functionality. You can mitigate this by creating a page_preprocess function in a module so only the "print render($my_form)" is in the template file or by using the steps in the answer below.
    – acouch
    Commented Feb 17, 2012 at 21:23
  • Agreed. Functionality should not be placed in themes. Downvoting.
    – colan
    Commented Nov 25, 2015 at 22:45
5

You want to avoid putting this into your node template. Generally you want to keep "business logic" (any php functions other than print) out of template files. You might be better served by creating this as a block and placing it below or above the node because it is more reuseable. If you don't want to use a block you can use hook_node_view() and add an additional element to $node->content as in the linked example.

5
  • Thanks for responding. I am trying to add a textfield to the bottom of a node (for a specific cck type), that once (an authenticated user) submits, stores the value as a term in a taxonomy vocabulary. So, its like another way of extending the editing features of a node for authenticated users, without giving them access to edit any other parts of the cck fields. I guess I'm "exposing" a field that then stores data elsewhere. Hope this makes sense.
    – Robbase
    Commented Feb 16, 2012 at 20:11
  • I updated the response. It would be good to update the question for clarity.
    – acouch
    Commented Feb 16, 2012 at 21:18
  • I agree with separating business logic from presentation, and with this in mind, you've answered my question. It appears there are several ways (ie. hook_form_alter on cck type, hook_node_view, etc.) to do what I'm attempting, but I initially struggled w/ forms not loading in node.tpl properly, which is all clear. Thanks a bunch! I would up-vote, but says I need 15 rep.
    – Robbase
    Commented Feb 16, 2012 at 21:29
  • I updated the question and removed the question from my response. Best of luck.
    – acouch
    Commented Feb 16, 2012 at 21:48
  • If this is D7, (and I understand the question properly) I say you want to code up a field that can present a textfield for tagging, maybe with AJAX to update the taxonomy. Most importantly, it has to figure out a way to bypass field access, because that's the real stumbling block. Or you might look here: drupal.org/project/community_tags
    – paul-m
    Commented Feb 16, 2012 at 22:24
1
/**
 * Implements hook_node_view()
 */
function MYMODULE_node_view($node, $view_mode, $langcode) {
  // prepare the form
  $form = drupal_get_form('a_very_simple_form');
  // append a new field to the content
  $node->content['a_new_field'] = array(
    '#markup' => drupal_render($form), // and render the form there
    '#weight' => 10,
  );
}

function a_very_simple_form($form, &$form_state) {
  $form['submit_button'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );
  return $form;
}

See hook_node_view() for more information.

0

The Webform module has an "Available as block" option, which can be placed on whichever pages using the Block UI, Context or Panels (if you're into that sort of thing, but I don't recommend it).

I found this over at How to embed a webform in a node in drupal 7. This was also mentioned over at Embedding a webform inside a node content and Add webform to content type.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.