Here's my use case: I'm using ctools and contexts to display different page layouts (in the sense of ctools Page Manager pages) depending on different contexts. So blog entries get one kind of page, blog entries in an Organic Group get another, etc. In my setup, webforms can be created on any content type; I'm not using the built-in "webform" content type.

The issue I'm facing is how to load the webform data within that Page Manager layout.

There are two ways I know this can currently be done:

1. Load the entire node body, with all "extras" including $links, attachments, etc. This loads any webform data attached to the body. This is less than ideal, because I want to display those other pieces of the node body in different places, not all in the same place within the page context.

2. Check the "Available as block" option under advanced settings and then insert the block in the Page Manager. This is even less ideal, because I'd have to go in and edit the page layout for every new webform's block.

So there are three ways I can envision this being done instead:

1. Hook into the context system so that Page Manager knows about the webform data as a discrete object. For instance, the options under "Node" in Page Manager include "attached files," "book children" and "node terms." This would be ideal to me, to have the webform data as one of those objects, but not knowing much about the context system I'm not sure how complicated that is.

2. Create a view that takes the node ID as an argument and returns the "Webform form body" views field. This seems doable, but I'm not sure if it's a matter of just the argument, or if there needs to be a relationship like Flag module requires. This is what I'm going to be experimenting with, however.

3. Create a custom panel content in Page Manager and paste in some PHP code that looks for the visible node and returns the webform data. Definitely only going this route if I can't figure out #2.

Would love any feedback or thoughts others may have had on this topic. Will report back if/when I figure out any solutions here.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

rootwork’s picture

Well, poo. The views option worked just great, except that the "Webform form body" is apparently the entire node body complete with the node title and fields, in addition to the webform itself. Why is that? Is there not a field accessible via views that is JUST the webform form?

I'll probably go ahead and do it this way, and hide the duplicate content via CSS, because that still seems less janky to me than hardcoding in PHP to a custom pane.

Is there something I'm missing? Is there a way just to load the form data and not the rest of the node?

rootwork’s picture

Oh, and attached is the view I created that works (in a sense) in case anyone else wants to do it this way.

As this is on Drupal 6 this is Views 2, obviously. Note the node validation checks (about half-way through) various node types, which probably are different (likely many fewer) on your system.

$view = new view;
$view->name = 'webform_data';
$view->description = 'Exposes webform data attached to nodes, for the purposes of context and ctools Page Manager.';
$view->tag = 'panels, ctools, webform, context';
$view->view_php = '';
$view->base_table = 'node';
$view->is_cacheable = FALSE;
$view->api_version = 2;
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
$handler = $view->new_display('default', 'Defaults', 'default');
$handler->override_option('fields', array(
  'webform_form_body' => array(
    'label' => '',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'target' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'html' => 0,
      'strip_tags' => 0,
    ),
    'empty' => '',
    'hide_empty' => 1,
    'empty_zero' => 0,
    'exclude' => 0,
    'id' => 'webform_form_body',
    'table' => 'node',
    'field' => 'webform_form_body',
    'relationship' => 'none',
  ),
));
$handler->override_option('arguments', array(
  'nid' => array(
    'default_action' => 'not found',
    'style_plugin' => 'default_summary',
    'style_options' => array(),
    'wildcard' => 'all',
    'wildcard_substitution' => 'All',
    'title' => '',
    'breadcrumb' => '',
    'default_argument_type' => 'fixed',
    'default_argument' => '',
    'validate_type' => 'node',
    'validate_fail' => 'not found',
    'break_phrase' => 0,
    'not' => 0,
    'id' => 'nid',
    'table' => 'node',
    'field' => 'nid',
    'validate_user_argument_type' => 'uid',
    'validate_user_roles' => array(
      '2' => 0,
      '3' => 0,
      '8' => 0,
      '4' => 0,
      '10' => 0,
      '12' => 0,
      '11' => 0,
      '5' => 0,
      '15' => 0,
      '6' => 0,
    ),
    'relationship' => 'none',
    'default_options_div_prefix' => '',
    'default_argument_fixed' => '',
    'default_argument_user' => 0,
    'default_argument_php' => '',
    'validate_argument_node_type' => array(
      'blog' => 0,
      'panel' => 0,
      'book' => 0,
      'event' => 0,
      'feature' => 0,
      'group' => 0,
      'multimedia' => 0,
      'page' => 0,
      'profile' => 0,
      'resource' => 0,
      'story' => 0,
    ),
    'validate_argument_node_access' => 1,
    'validate_argument_nid_type' => 'nid',
    'validate_argument_vocabulary' => array(
      '4' => 0,
      '11' => 0,
      '18' => 0,
      '19' => 0,
    ),
    'validate_argument_type' => 'tid',
    'validate_argument_transform' => 0,
    'validate_user_restrict_roles' => 0,
    'validate_argument_node_flag_name' => '*relationship*',
    'validate_argument_node_flag_test' => 'flaggable',
    'validate_argument_node_flag_id_type' => 'id',
    'validate_argument_user_flag_name' => '*relationship*',
    'validate_argument_user_flag_test' => 'flaggable',
    'validate_argument_user_flag_id_type' => 'id',
    'validate_argument_is_member' => 'OG_VIEWS_DO_NOT_VALIDATE_MEMBERSHIP',
    'validate_argument_group_node_type' => array(
      'group' => 0,
    ),
    'validate_argument_php' => '',
  ),
));
$handler->override_option('access', array(
  'type' => 'none',
));
$handler->override_option('cache', array(
  'type' => 'none',
));
$handler->override_option('items_per_page', 0);
$handler = $view->new_display('panel_pane', 'Content pane', 'panel_pane_1');
$handler->override_option('pane_title', 'Webform body');
$handler->override_option('pane_description', 'Displays the body of any webform attached to the current node.');
$handler->override_option('pane_category', array(
  'name' => 'View panes',
  'weight' => 0,
));
$handler->override_option('allow', array(
  'use_pager' => FALSE,
  'items_per_page' => FALSE,
  'offset' => FALSE,
  'link_to_view' => FALSE,
  'more_link' => FALSE,
  'path_override' => FALSE,
  'title_override' => FALSE,
  'exposed_form' => FALSE,
  'fields_override' => FALSE,
));
$handler->override_option('argument_input', array(
  'nid' => array(
    'type' => 'context',
    'context' => 'node.nid',
    'context_optional' => 0,
    'panel' => '0',
    'fixed' => '',
    'label' => 'Node: Nid',
  ),
));
$handler->override_option('link_to_view', 0);
$handler->override_option('inherit_panels_path', 0);
quicksketch’s picture

Well, poo. The views option worked just great, except that the "Webform form body" is apparently the entire node body complete with the node title and fields, in addition to the webform itself. Why is that? Is there not a field accessible via views that is JUST the webform form?

That field *should* just be the node form. If it's not, we can modify the field to make it so.

rootwork’s picture

That's a relief! It did seem odd that that would be intentional.

Do you need more information to look into this? Happy to test patches and whatnot.

rootwork’s picture

Title: Dynamically load webform data from node context in ctools Page Manager » "Webform form body" contains entire node object instead of just the form
Category: feature » bug
FileSize
34.56 KB

Here's a screenshot. This was done on a fresh Drupal 6 install, with only webform and views installed.

This is a view displaying the node title, the node body, and then "webform form body" which you can see is the complete node object. This is displaying the built-in webform content type, but for the record, it does the same thing if you allow other content types such as pages to be webform-enabled.

Let me know if there's anything else I can do to assist. I'm changing the issue title for the purpose of addressing this bug.

rootwork’s picture

Version: 6.x-3.9 » 6.x-3.14

Looking at webform_handler_field_form_body.inc inside webform's views folder, indeed it does look like it's grabbing the fully rendered node object (lines 28-39):

function render($values) {
    $node = node_load($values->{$this->aliases['nid']});

    if (node_access('view', $node)) {
      $form_body = node_view($node, FALSE, FALSE);
    }
    else {
      return;
    }

    return $form_body;
  }

node_load gets the node from the NID, and node_view renders the node, with teaser and page-view both set to false. "Webform form body" is thus set to the fully rendered node object.

Figuring out how to render only part of the node object is definitely outside of my grasp, but that file definitely seems to be where the issue is.

quicksketch’s picture

Yes I think you're right. We should be able to get just the part we want (I believe) by pulling it out of $node->content['webform'].

We may also be able to just call webform_node_view() directly instead of node_view(), which would only load the Webform component and not everything else that doesn't need to be displayed.

rootwork’s picture

Cool. I tried a few things based on that info but none of them seemed to work, but I'm not very knowledgeable in this area.

Substituting webform_node_view() for node_view in that file resulted in no content being returned (no webform content and no node content) but maybe it requires other changes to work. Substituting $node->content['webform'] for $node in node_view returns an empty node (wrapping divs, but no node content) but I probably just don't understand how to properly call that. Like I said...not my strong suit.

Will keep checking back and test any patches on this.

quicksketch’s picture

Status: Active » Fixed
FileSize
701 bytes
652 bytes

These patches should fix the problem for both D6 and D7. Instead of using node_view(), we now use webform_node_view() to render just the Webform portion of the node and then print out just that part.

quicksketch’s picture

I've committed the above patches to both branches and they'll be in the 3.15 versions.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.