3

Im building a module and need to put a comments form on a page which is NOT a node. Is there a way of doing this?

I guess I will need to use:

drupal_get_form('comment_form', array('nid' => $node->nid));

However this seems to have a certain dependency on the nid as it always seems to be attached to a node.

  • You can always make your page a node, why not? – user827 Mar 31 '11 at 15:43
  • More information about your use case would be helpful. What are these pages that aren't nodes? Views? – tim.plunkett Mar 31 '11 at 16:05
  • Well specifically I would like to attach comments to each individual webform submission. I started creating a module but ran into the above problem pretty quickly. However, for different use cases I guess it might be useful to use comments on other admin pages for webmasters to peer review things like changes in taxonomy (for example like here or wiki discussion pages) – WestieUK Apr 1 '11 at 7:46
3

API the module that handle the pages you see at api.drupal.org, has the same problem; the documentation pages you see are not nodes, but the module allows to add comments to them.

The page callback invoked for the documentation pages is api_page_function(), which is associated to the path api/%/%/function/%api_item in its implementation of hook_menu() (see api_menu(), starting at line 125 of the linked file). The page callback uses _api_add_comments(), which contains the following code:

if (module_exists('comment') && user_access('access comments') && variable_get('comment_api', COMMENT_NODE_READ_WRITE) != COMMENT_NODE_DISABLED) {
  $output .= comment_render(node_load($documentation_object->did));
  if (user_access('post comments')) {
    $output .= comment_form_box(array('nid' => $documentation_object->did), t('Post new comment'));
  }
  // ...
}

API creates empty nodes that associate to the documentation pages; the reason of this is that the Comment module still need a node object to return any comment that is associated with that node.

  • I think this is using the right approach although it looks pretty complex. Do you know if this will save to the core comments table, if so would the documentation_object go in nid row? – WestieUK Apr 1 '11 at 10:40
  • They are saved in the comment table; in fact, the page api.drupal.org/admin/content/comment list them, and that page is not altered by api.module. – kiamlaluno Apr 1 '11 at 13:07
1

No. A comment has a required foreign field in the database: "comments.nid". Comments will not do for anything that is not a node.

Even if you somehow manage to store comments without a node Id, things will break hooribly.

  • 1
    Yea I am thinking this might be a problem. I am looking at 3 different ways of doing this now. Another way might be using rules and webform rules to create a new node for each submission. This new node can use any content type so it already has comments working. The node title is "comments page for webform name #*sid*" Now I just want to figure out a way of creating a link between the submission page and the node – WestieUK Apr 1 '11 at 8:16
1

I suggest trying the Reply module.

1

This works for me:

if (module_exists('comment') && user_access('access comments') && variable_get('comment_api', COMMENT_NODE_READ_WRITE) != COMMENT_NODE_DISABLED) {
  $output .= comment_render(node_load($documentation_object->did));
  if (user_access('post comments')) {
    $output .= comment_form_box(array('nid' => $documentation_object->did), t('Post new comment'));
  }
  // ...
}

But I work with the ajax_comments module when trying to save a comment it's got to replay pages.

But all the tags and ajax_comment.js and .css is loaded and the structure for the form is with the node page (any solution for this).

0

It is definitely possible to add comments to none-node pages. I follow ideas in other answers to attach an empty node to my none-node page. All the technical details are here.

Use case:

I migrate an old website to Drupal 7. I have old URLs showing the content of a database table like http://www.example.com/oldpage.php?gid=xxxxx where xxxxx is an interger ID. These IDs are important to me as there are thousands of links from external sites to them. My new Drupal URLs look like http://www.example.com/newpage/xxxxx I can always let the web server rewrite old URLs to the new URLs. If I use node, I no longer have control over the IDs.

Map old ID to new node ID:

I create a new node type called 'empty node'. This can be done using the admin user interface or by Drupal API. Next create a database table called association_table like this:

+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+ 
| drupal_nid | int(11)     | NO   | PRI | NULL    |       |
| gid        | int(8)      | YES  |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+

This maps my old 'gid' to the associated node ID of 'empty node'. An empty node will be created as needed when user visit my newpage URL. At the end of that page I have something like:

$sql = "SELECT drupal_nid from {association_table} WHERE gid=". $gid; // $gid: my old ID
$results = db_query($sql);
if ($results->rowCount()==1) {  
  // already associated with an empty node
  $nid = $results->fetchField(0);
}
else {
  // call helper function to create a new empty node and return its node id
  $nid = mymodule_new_node($title);
  // create new entry in association_table
  $sql = "INSERT INTO {association_table} VALUES(". $nid. ", ". $gid. ")";
  db_query($query); // I keep things simple here, of course use Drupal way to insert.
} 

Now the helper function:

function mymodule_new_node($title) {
  $node = new stdClass();
  $node->type = 'empty_node'; 
  $node->title = $title;
  $node->uid = 1;  // created by admin user
  if (module_exists('comment')) {
    $node->comment = variable_get('comment_api', COMMENT_NODE_OPEN);
  }
  node_save($node);
  return $node->nid;
}

The helper function creates an empty node, set its title to something appropriate, set its owner to admin user, and return its node id. The $title bit is absolutely necessary. The title will appear in many places in Drupal, such as 'admin/content', 'admin/content/comment', and the clickable links in search result.

Append comment form to none-node page:

This is fairly easy to do. At the end of my 'newpage', do

if (module_exists('comment') && user_access('access comments') && variable_get
('comment_api', COMMENT_NODE_OPEN) != COMMENT_NODE_HIDDEN) {
  $comment_form = comment_node_page_additions(node_load($nid));
  $output .= drupal_render($comment_form);
}

With this form, user can add comment to the main comment table.

Handle redirection:

Drupal will refer to these empty nodes using URL /node/????? (e.g. links in 'admin/content'). When users submit the comment form they will too be redirected to /node/?????. I need to redirect /node/????? to /newpage/xxxxx using the mapping in the association_table. This is done by implementing hook_node_view:

function mymodule_node_view($node, $view_mode, $langcode) {
  if ($node->type == 'empty_node' && $view_mode == 'full' && arg(0) == 'node') {
    $sql = "SELECT gid FROM {association_table} WHERE nid=". $node->nid; 
    $gid = db_query($sql)->fetchField(0);
    drupal_goto('newpage/' . $gid);
  }
}

Summary:

This procedure works flawlessly for me on my Drupal 7 production site.

There are some additional tweaks that are required. For example, depending on how the titles of the empty nodes are set, they might appear in search result. This might not be desirable. In my case, I use hook_query_alter to change how search is done on these empty nodes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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