Solved

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

Posted on 2013-02-04
17
1,648 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 6
  • 2
17 Comments
 
LVL 12

Expert Comment

by:junipllc
ID: 38851540
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
ID: 38851946
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
ID: 38852369
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
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 2

Author Comment

by:itkadmin
ID: 38854677
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
ID: 38856990
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
ID: 38857828
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
ID: 38858268
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
ID: 38859015
I second HagayMandel's solution to embed a view. It's simple, elegant, and quick to implement.
0
 
LVL 2

Author Comment

by:itkadmin
ID: 38863841
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
ID: 38864532
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
ID: 38867720
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
ID: 38870069
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
ID: 38881403
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
ID: 38883623
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
ID: 38885251
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
ID: 38886725
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
ID: 38888797
Thank you for all the time you've put into this.
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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 …
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …

689 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