19

I'm looking for a way to embed a "node add" form on a landing page. I was using Form Block, but it appears to bring many error because I was using a development snapshot version.

1
  • 1
    If you are having specific issues with form block the best place to look may be the issue queue for that module. Commented May 11, 2011 at 9:53

3 Answers 3

29

You can use:

module_load_include('inc', 'node', 'node.pages');
$form = node_add('nodetype');
print drupal_render($form);
4
  • 3
    If you get an error that node_add() is undefined, you'll want to add if (!function_exists('node_add')) { module_load_include('inc', 'node', 'node.pages'); } at the beginning. This information comes from here: (kahthong.com/2012/01/embed-drupal-node-form-anywhere)
    – mbrakken
    Commented Apr 2, 2013 at 8:13
  • There a way to put this in a block? Or does this have to be included in the tpl.php file?
    – user12342
    Commented Nov 26, 2013 at 14:26
  • I cannot use the code for form with Ajax elements (for example: file upload). Possible solution
    – Dimetry
    Commented Jul 11, 2017 at 9:51
  • @Dimetry see my answer for using Ajax elements in an embedded node form.
    – Elin Y.
    Commented Sep 26, 2017 at 5:51
18

Although Daniel Wehner's answer is absolutely correct and works, I wanted to add two common problems I faced with this approach and workarounds how I overcome those problems. First my code, then the explanations:

global $user;

module_load_include('inc', 'node', 'node.pages');

$node = (object) [
  'uid' => $user->uid,
  'name' => (isset($user->name) ? $user->name : ''),
  'type' => 'YOUR_NODE_TYPE',
  'language' => LANGUAGE_NONE,
];
$form = drupal_get_form('YOUR_NODE_TYPE' . '_node_form', $node);

print drupal_render($form)

Why I did it this way, instead of Daniel's simple node_add?

Problem 1: node_add() function changes the page title to Create 'node type', this is hard coded in the function.

Workaround 1: Instead of using node_add function, I've copied the code and removed the drupal_set_title. The above code is the same code as the node_add function, except from this one line.

Problem 2: In the embedded form some ajax functions didn't work. For example if you have a field that can have unlimited values, so that you have an 'Add another item' button, or if you have an upload file field in your form, they don't work.

Workaround 2: In your custom module, implement hook_menu_alter() for ajax call paths, and include node.pages.inc.

function YOURMODULE_menu_alter(&$items) {
  $items['file/ajax']['file path'] = drupal_get_path('module', 'node');
  $items['file/ajax']['file'] = 'node.pages.inc';
  $items['system/ajax']['file path'] = drupal_get_path('module', 'node');
  $items['system/ajax']['file'] = 'node.pages.inc';
}
7
  • Would Inline Entityform be an alternative? I've been playing around with the module but haven't been able to display a node add form on the front-end, only when you edit a node can you provide an entityreference field that displays a node add form.
    – AlxVallejo
    Commented Jul 25, 2014 at 13:45
  • 1
    Inline Entityform is for entity reference fields, which is irrelevant for this question.
    – Elin Y.
    Commented Jul 26, 2014 at 11:28
  • 1
    If you don't want to use hook_menu_alter() for file uploads, etc, you can add the include in a form alter for the node form instead: function YOURMODULE_form_NODETYPE_node_form_alter(&$form, &$form_state) { form_load_include($form_state, 'inc', 'node', 'node.pages'); }
    – joe_flash
    Commented Mar 27, 2015 at 15:33
  • 1
    @Umair My answer is only about adding a node form to a page. It would neither submit the form via AJAX nor would it update the view. However, you can achieve those using AJAX Framework.
    – Elin Y.
    Commented Jun 20, 2017 at 15:00
  • 1
    @kosher Thanks for the note. I've added the closing quote.
    – Elin Y.
    Commented Apr 30, 2020 at 9:04
0

If I use the accepted answer's code...

module_load_include('inc', 'node', 'node.pages');
$form = node_add('nodetype');
print drupal_render($form);

...inside of a page callback function, then print drupal_render.. this results in a completely un-themed (broken-looking) page.

So instead, I just return'ed the $form:

module_load_include('inc', 'node', 'node.pages');
$form = node_add('program_registration');
return $form;

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