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.