Solved

How can I toggle (show/hide) comments on a node in Drupal 7

Posted on 2013-02-04
17
1,506 Views
Last Modified: 2013-02-14
I've been thinking about mobile web. Most nodes have a chunk of primary content, then what I'll call secondary content (related content to the current node, but not the main focus) and tertiary content (navigation, footers, headers etc). I would like to focus on primary content and keep the rest as minimal as possible.

The tertiary bit isn’t a problem, mostly theming stuff with media queries. The primary content isn’t too hard to sort out. Drupal seems to do a fine job of separating these things. Where I’m having trouble is the secondary content, particularly comments.

What I would like to do is:      

Don’t automatically show comments

If there are no comments, don’t show anything (drupal does this by default)

If there are comments, show a link, preferably with a comment count “ 14 comments” or something like that

A person selects the link and the comments are exposed.

Ideally this would be happen programmatically, not just hiding the comment block with CSS, don’t want it to load unless requested.

Ajax load would be nice so the page doesn’t reload

Any ideas on how I can do this?
0
Comment
Question by:itkadmin
  • 9
  • 6
  • 2
17 Comments
 
LVL 12

Expert Comment

by:junipllc
Comment Utility
Just from a quick search I came up with these, but I'm not sure if they will work 100% in your situation. I typically start a module search by finding one on Drupal.org, then looking in the lower-right corner of the page for related modules. I've found some real gems that way...and some not-so-good ones. :)

http://drupal.org/project/ajax_comments
http://drupal.org/project/hidden_comment

I've used AJAX Comments before and I know it has a lot of options, so it may be able to satisfy some (or maybe all?) of your requirements. However, if you can't find a module or combination of modules that does what you need, there is always the option of using theming to do what you need.

Depending on the base theme you're using, or really just the theme and its support components, you can create and edit your template files (for example, comment.tpl.php) to programmatically style the way a comment or set of comments is rendered. Best practice, however, is to put any preprocessing into preprocess functions. These are usually found in template.php inside your theme.

The other option is to create a module to do this, which will apply to all themes instead of just one. Much of the code will be similar, and if you haven't coded a module before this would probably be a good one to start on. You may need to create one if things get too complicated for simple theming.

By the way, hiding content using CSS instead of doing it "The Drupal Way" is discouraged, so I definitely applaud you and support you in that cause :)

Those are all of the thoughts I have at the moment, and that should get you started, at least in the path to getting this done. I'd start with a module search, then move to actual coding if that doesn't result with something you can use. AJAX is very easy to implement in Drupal (especially with Chaos Tools (ctools)), so don't rule out doing your own if you're familiar with the concepts.

Disclaimer: the above is all stream of consciousness and I haven't gone back to proof it, so hopefully it makes sense!

Let me (us) know if you have any questions along the way!

Cheers,

Mike
0
 
LVL 2

Author Comment

by:itkadmin
Comment Utility
Hi

Thanks for this.

I've done the module search, nothing that does what I'm looking for. I toyed with the idea of removing comments from the template, using views to make a comment block then use some Jquery to show the block.

problem is - I'm not fond of the views mark-up. The comment module provides sone nice RDF. Also, this solution would be back to hiding with CSS.

I haven't a clue how to start with module building. I'm one of those guys who works in one window and googles everything I want to do in the other window.
0
 
LVL 16

Expert Comment

by:HagayMandel
Comment Utility
Another approach is to generate a new template file for a node, that will contain the node itself, and a view that will encapsulate the comments (as links with comment count etc)
Ajax can be easily applied, via views again,and the whole thing is proper Drupal's way.
0
 
LVL 2

Author Comment

by:itkadmin
Comment Utility
I can give the views method a go. I tried something similar before and couldn't find a way to theme threaded comments. Views didn't apply any different classes to comments that were replies to comments.

I'm not sure what you mean by making a template file for a node that contains the node. Sounds mysterious and cryptic!
0
 
LVL 2

Author Comment

by:itkadmin
Comment Utility
It looks like doing this programmatically is going to be beyond my abilities.

I sort of found a solution, though not the sleekest, it works.

I can use Ctools and a bit of php in the node template like so
<?php 
	 $collapsed_content = render($content['comments']);
	 if ($comment_count > 0 && $comment_count < 2): /*this should handle single comments*/
	 print theme('ctools_collapsible', array('handle' => $comment_count, 'content' => $collapsed_content, 'collapsed' => TRUE)); 
	 elseif ($comment_count > 2): /*this is for multiple comments*/
	 print theme('ctools_collapsible', array('handle' => $comment_count, 'content' => $collapsed_content, 'collapsed' => TRUE)); 
	 endif;
 ?>

Open in new window


You can see it work here http://www.craigclark.ca/content/notebook/2012/november/do (the '9' below the big image on the left)

This collapses things (though just hiding them, not exactly what I was looking for), it doesn't show a comments link if there are no comments on the node. What I would like to do is work with plurals, so I get "1 comment" or "2 comments" etc. What I don't know is how to add some text for "comment" or "comments". I assume "comment" would go on line 4 somewhere after array('handle' => $comment_count, and "comments" would go on line 6 somewhere.

How do I add that in? What I have here returns only a number.

I'm not strong on PHP, figured this much out with info provided in node template file, ctools tutorial and PHP elseif manual.
0
 
LVL 2

Author Comment

by:itkadmin
Comment Utility
Changed a bit, to deal with plurals

Its not quite what I was hoping, I think calling the comments to load on request is beyond what I know how to do.

This works in the template and just shows/hides comments using ctools, for what it is, does it look correct?

<?php 
	 $collapsed_content = render($content['comments']);
	 if ($comment_count > 0 && $comment_count < 2):
	 print theme('ctools_collapsible', array('handle' => "{$comment_count} comment", 'content' => $collapsed_content, 'collapsed' => TRUE)); 
	 elseif ($comment_count > 2):
	 print theme('ctools_collapsible', array('handle' => "{$comment_count} comments", 'content' => $collapsed_content, 'collapsed' => TRUE)); 
	 endif;
?> 

Open in new window

0
 
LVL 16

Expert Comment

by:HagayMandel
Comment Utility
If your'e already messing with node template, simply create a view of comments (where the contextual filter will be node id from the url), and embed it  (see how) in your template file.
0
 
LVL 12

Expert Comment

by:junipllc
Comment Utility
I second HagayMandel's solution to embed a view. It's simple, elegant, and quick to implement.
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 2

Author Comment

by:itkadmin
Comment Utility
I followed the instructions  views_embed_view

I put the following in template.php and everything broke, telling me I had an error at line 41.
What is wrong with line 41?
<?php

/**Add .js for dropdown menu on devices**/
drupal_add_js('sites/all/themes/at_subtheme_craigclark/scripts/show_hide_menu.js');


/**
* Remove the comment filters' tips
*/
function at_subtheme_craigclark_filter_tips($tips, $long = FALSE, $extra = '') {
  return '';
}
/**
* Remove the comment filter's more information tips link
*/
function at_subtheme_craigclark_filter_tips_more_info () {
  return '';
}

function at_subtheme_craigclark_preprocess_page(&$variables){

    if (arg(0)=="user" || arg(0)=="users" ){

        unset ($variables['page']['content']['system_main']['user_picture']);
    }
}

function views_embed_view($name, $display_id = 'default') {
  $args = func_get_args();
  array_shift($args); // remove $name
  if (count($args)) {
    array_shift($args); // remove $display_id
  }

  $view = views_get_view($name);
  if (!$view || !$view->access($display_id)) {
    return;
  }

  return $view->preview($display_id, $args);
}

Open in new window

0
 
LVL 16

Expert Comment

by:HagayMandel
Comment Utility
All you need to do is to USE this function.:)

views_embed_view($name, $display_id = 'default');

where $name = YOUR VIEW MACHINE NAME
$display_id =  YOU DISPLAY ID // The machine name of the display, default is 'default'
0
 
LVL 2

Author Comment

by:itkadmin
Comment Utility
Thank you

I'm not getting errors anymore, which is good. I'm getting a white screen, which is bad. I think I'm doing something wrong in template.php

If you have time, could you please take a look? I've attached template.php, the view and the node template.
view-in-node.zip
0
 
LVL 16

Accepted Solution

by:
HagayMandel earned 500 total points
Comment Utility
Create the view of comments with a contextual filter of content nid with default value grabbed from the url:
$view = new view();
$view->name = 'mycomments';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'comment';
$view->human_name = 'mycomments';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'fields';
/* Relationship: Comment: Content */
$handler->display->display_options['relationships']['nid']['id'] = 'nid';
$handler->display->display_options['relationships']['nid']['table'] = 'comment';
$handler->display->display_options['relationships']['nid']['field'] = 'nid';
$handler->display->display_options['relationships']['nid']['required'] = TRUE;
/* Field: Comment: Title */
$handler->display->display_options['fields']['subject']['id'] = 'subject';
$handler->display->display_options['fields']['subject']['table'] = 'comment';
$handler->display->display_options['fields']['subject']['field'] = 'subject';
$handler->display->display_options['fields']['subject']['label'] = '';
$handler->display->display_options['fields']['subject']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['subject']['alter']['ellipsis'] = FALSE;
/* Sort criterion: Comment: Post date */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'comment';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
/* Contextual filter: Content: Nid */
$handler->display->display_options['arguments']['nid']['id'] = 'nid';
$handler->display->display_options['arguments']['nid']['table'] = 'node';
$handler->display->display_options['arguments']['nid']['field'] = 'nid';
$handler->display->display_options['arguments']['nid']['relationship'] = 'nid';
$handler->display->display_options['arguments']['nid']['default_action'] = 'default';
$handler->display->display_options['arguments']['nid']['default_argument_type'] = 'node';
$handler->display->display_options['arguments']['nid']['summary']['number_of_records'] = '0';
$handler->display->display_options['arguments']['nid']['summary']['format'] = 'default_summary';
$handler->display->display_options['arguments']['nid']['summary_options']['items_per_page'] = '25';
/* Filter criterion: Comment: Approved */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'comment';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status_node']['id'] = 'status_node';
$handler->display->display_options['filters']['status_node']['table'] = 'node';
$handler->display->display_options['filters']['status_node']['field'] = 'status';
$handler->display->display_options['filters']['status_node']['relationship'] = 'nid';
$handler->display->display_options['filters']['status_node']['value'] = 1;
$handler->display->display_options['filters']['status_node']['group'] = 1;
$handler->display->display_options['filters']['status_node']['expose']['operator'] = FALSE;
$translatables['mycomments'] = array(
  t('Master'),
  t('more'),
  t('Apply'),
  t('Reset'),
  t('Sort by'),
  t('Asc'),
  t('Desc'),
  t('Items per page'),
  t('- All -'),
  t('Offset'),
  t('« first'),
  t('‹ previous'),
  t('next ›'),
  t('last »'),
  t('Content'),
  t('All'),
);

Open in new window

Then in the node.tpl.php simply replace:
<?php print render($content['comments']); ?>

Open in new window

with:
<?php print views_embed_view('mycomments', 'default'); ?> 

Open in new window

(in this case the view machine name is mycomments).
0
 
LVL 2

Author Comment

by:itkadmin
Comment Utility
Thanks!

That got the view into the node. I didn't have to do anything to the template.php.

back to HagayMandel's original reccomendation, I can generate the view I want, showing comment counts etc, what I don't know how to do in views is make it so I have a link with the comment count (I can get the comment count no problem) and have it open a displayt of all the comments when selected.

What I'm trying to avoid is having viewers see the comments unless they want to see the comments.
0
 
LVL 16

Expert Comment

by:HagayMandel
Comment Utility
OK conclusions:
Paste in your node.tpl.php this code instead of the 'print render($content['comments'])' section'

<?php
$view = views_get_view_result('mycomments', 'default');
if (count($view)>0) {
	drupal_add_js('misc/collapse.js');
	print '<fieldset class=" collapsible collapsed">
  <legend><span class="fieldset-legend">Total number of comments:</b>' . count($view) . '</span></legend>
  <div class="fieldset-wrapper">';
	for ($i = 0; $i < count($view); $i++){
	$vars = get_object_vars($view[$i]);
  print '<a href = "/comment/'. $vars['cid'] .'/#comment-' . $vars['cid'] . '">' . $vars['comment_subject'] . '</a><br />';
	}
  print '</div></fieldset>';
}
?>

Open in new window

This will create a collapsible field set with a list of linked comments.
You can condition the whole code based on a content type as well.

Hagay
0
 
LVL 2

Author Comment

by:itkadmin
Comment Utility
That mostly works.

Only glitch is that on the node page it collapses, but doesn't expand. http://www.craigclark.ca/test
if you click the "add a new comment" link ( http://www.craigclark.ca/comment/reply/36#comment-form )  then the "total number of comments: 3" collapse works as it should.
0
 
LVL 16

Assisted Solution

by:HagayMandel
HagayMandel earned 500 total points
Comment Utility
Add the render function to the script:

	<?php
	$view = views_get_view_result('mycomments', 'default');
	if (count($view)>0) {
		render($content['comments']); 	
		drupal_add_js('misc/collapse.js');
		print '<fieldset class=" collapsible collapsed">
		<legend><span class="fieldset-legend">Total number of comments:</b>' . count($view) . '</span></legend>
		<div class="fieldset-wrapper">';
		for ($i = 0; $i < count($view); $i++){
		$vars = get_object_vars($view[$i]);
		print '<a href = "/comment/'. $vars['cid'] .'/#comment-' . $vars['cid'] . '">' . $vars['comment_subject'] . '</a><br />';
		}
		print '</div></fieldset>';
	}
?>

Open in new window

Pay attention: You do loose the adding comments this way!
If you want it to show, add:
print '<a href ="/comment/reply/' . $node->nid . '#comment-form">'  . t('Add new comment') . '</a>'; 

Open in new window

0
 
LVL 2

Author Closing Comment

by:itkadmin
Comment Utility
Thank you for all the time you've put into this.
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
using hook_element_info() to add a placeholder to a form label 4 671
Dynamic Selection? 3 77
Hidden bullet images 10 153
Drupal Security Issue 2 158
This article is for those that are having major problems with users upload files such as pictures to their profile. The solution is simple and has to do with correcting the directory paths. With some experimenting and testing i got it fixed. Note…
RTL (right to left) web applications aiming for audiences speaking languages like Hebrew or Arabic, are generally more complicated than the same applications aiming for audiences speaking Latin based languages. The main difference lies of course …
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now