svg image

Making Drupal webforms deployable in an automated environment




Webforms in Drupal are a useful, easy way to achieve forms, especially when displayed inline within a page, such as a contact form on a contact page.


The use of webforms is all well and good, but since they’re content, they’re nodes and thus assigned a node ID in the database. As a result, if you make use of content that has been exported via `node export` and reimport it, it’ll be imported in an different order from the original, as the node IDs will be newly set in the database.


This leaves a programmatic reference to the `nid` inclusion of the webform to now instead reference a different piece of content (or one that does not exist).


The fix is to manually update code following every deployment, leading to it being unreliable [and costly – Ed]; thus I sought a more elegant solution.


The following is the standard code that one would use to hook into the webform module and render the webform, referencing  the active `nid` of the webform in question:

$block = module_invoke('webform', 'block', 'view', 'client-block-NID');

  print $block['content'];


However, this doesn’t scale for deployable, automated environments, which we use liberally.


On my journey to finding a solution, I thought of the URL alias system that most Drupal content is able to use as standard.

If one could rely on that as a way of rendering a webform, rather than a static, database-tied node ID, then it would be deployable, as it would be saved as part of the content itself.


However, the use of `module_invoke` into the webform module won’t take a URI to map as an alias.

So, to solve this problem, if the alias could be referenced and used to retrieve the currently active node ID, then that could be passed into the code previously mentioned above.


To solve this problem, you can set the following in `template.php`:

function HOOK_preprocess_page(&$vars) {

    $alias = 'alias-example';

    $path = drupal_get_normal_path($alias);

    $nid = substr($path, 5);

    $vars['name_for_webform'] = module_invoke('webform',



In `$path`, you’ll retrieve `nid-NID`, so you need to use the PHP `substr` function to trim back to the `nid` value that follows the entire string from that point.


From there, in the theme/node template that applies where you need to include the webform, you can use the following to render it:


You can now ensure that every time a deployment occurs, the webform will render as intended.

5th June 2016
Dash line

More Technical

Who's the driver?


Beginner's not-a-guide to Laravel - 4 things that will save you time


Store and share business documents securely