3

I have a content type with threading comments. The max number of comments per page is set to 300 (that is the absolute max). If there is more than 300 comments - they get paged.

How do I show all comments of the node without the pager (300+ comments)?

This is a desired function knowing the negative impact on UX.

I couldn't find any theme functions/ hooks that can be used for setting a new max for comment pagers. Please, do not suggest to render comments via Views.

4
  • You should consider keeping the max and use an endless scroll to get rid of the pager.
    – Eyal
    Apr 6, 2016 at 17:23
  • @Eyal thank you. Do you know of a viable method of implementing endless scroll without use of Views?
    – oksana-c
    Apr 6, 2016 at 18:40
  • Sadly I'm not familiar with the implementation of endless scroll widgets.
    – Eyal
    Apr 6, 2016 at 19:22
  • @Eyal read my answer and learn :-)
    – No Sssweat
    Apr 7, 2016 at 4:28

3 Answers 3

4

It's stored in a variable per content type, you can override it like so:

variable_set('comment_default_per_page_CONTENT_TYPE', 500);

Where CONTENT_TYPE is the machine name of the content type.

If you want to change the options in the UI, you can do it through a form alter:

function MYMODULE_form_node_type_form_alter(&$form, &$form_state, $form_id) {
  if ($form['#node_type'] == 'foo') {
    $new_options = drupal_map_assoc(array(10, 30, 50, 70, 90, 150, 200, 250, 300, 500, 1000));
    $form['comment']['comment_default_per_page']['#options'] = $new_options;
  }
}
3
  • thank you @Clive , the option of overriding Content Type form seems to be the optimal solution as it will allow end users to control this setting. I corrected the code a bit $form['#node_type'] == 'foo' => $form['#node_type']->type == 'foo'.
    – oksana-c
    Apr 6, 2016 at 18:37
  • I tried variable_set('comment_default_per_page_CONTENT_TYPE', 500); by using it in the hook_preprocess_node() but a variable set like this gets overridden again when the Content Type settings form is saved. Did I misunderstand its usage?
    – oksana-c
    Apr 6, 2016 at 18:38
  • 1
    I've got an idea of another option, when @Clive mentioned variable_set. Global override of a variable can be placed in settings.php file like this $conf['comment_default_per_page_CONTENT_TYPE'] = 1000;. This will ensure that the variable does not get overridden at any point. Still the best solution is to use hook_form_BASE_FORM_ID_alter() as per @Clive 's suggestion.
    – oksana-c
    Apr 6, 2016 at 18:38
1

Paging on comments is provided in Drupal Core without any contribute modules.

If you go to your content type configuration screen:

D7 Path: admin/structure/types/manage/[node-type-name]

You will see there's a Comment field-set/tab(d7) with some options. The option you want to check out is the comments per page setting. Select the number you'll like for when a page should break and save your settings. Once you're comment have pass that threshold you will see a pager for your comments. See in attached screen also

Now for the comment counts there a variable available to you in Drupal 7 in the node template. The name of that variable is $comment_count.

enter image description here

1
  • this information is already understood but I thank you for your time
    – oksana-c
    Apr 6, 2016 at 18:45
1

How do I show all comments of the node without the pager (300+ comments)?

This is a desired function knowing the negative impact on UX.

I highly advice not to display/load 300 comments at the same time, not only it will make your page slower, but also it will increase your server costs. Will all users read all 300 comments? I doubt it, maybe a few might.

use an endless scroll to get rid of the pager.

Sadly I'm not familiar with the implementation of endless scroll widgets. – Eyal

This is the right approach. All you need is a little jQuery magic using AJAX load() method

First, set comments per page to 10.

Second, you need to modify the comments-wrapper.tpl.php file. This is bartik's:

<div id="comments" class="<?php print $classes; ?>"<?php print $attributes; ?>>


  <?php if ($content['comments'] && $node->type != 'forum'): ?>
    <?php print render($title_prefix); ?>
    <h2 class="title"><?php print t('Comments'); ?></h2>
    <?php print render($title_suffix); ?>
  <?php endif; ?>



<div class="ajax-wrap"> // added this wrapper

  <?php print render($content['comments']); ?>

  <div class="loadmore"></div> // added this div to load the next page stuff here   

</div> // closes ajax-wrap

  <?php if ($content['comment_form']): ?>
    <h2 class="title comment-form"><?php print t('Add new comment'); ?></h2>
    <?php print render($content['comment_form']); ?>
  <?php endif; ?>
</div>

Added the ajax-wrap div since there was no wrapper that only wrapped the comments and the pager as we don't want the "add comment box/form". We will load the next page comments inside loadmore div.

Third, we are going to use jQuery Visible to check if the loadmore div is visible on your browser window. If it's visible, we are going to load the next page comments using AJAX load() method

(function ($) {
!function(t){var i=t(window);t.fn.visible=function(t,e,o){if(!(this.length<1)){var r=this.length>1?this.eq(0):this,n=r.get(0),f=i.width(),h=i.height(),o=o?o:"both",l=e===!0?n.offsetWidth*n.offsetHeight:!0;if("function"==typeof n.getBoundingClientRect){var g=n.getBoundingClientRect(),u=g.top>=0&&g.top<h,s=g.bottom>0&&g.bottom<=h,c=g.left>=0&&g.left<f,a=g.right>0&&g.right<=f,v=t?u||s:u&&s,b=t?c||a:c&&a;if("both"===o)return l&&v&&b;if("vertical"===o)return l&&v;if("horizontal"===o)return l&&b}else{var d=i.scrollTop(),p=d+h,w=i.scrollLeft(),m=w+f,y=r.offset(),z=y.top,B=z+r.height(),C=y.left,R=C+r.width(),j=t===!0?B:z,q=t===!0?z:B,H=t===!0?R:C,L=t===!0?C:R;if("both"===o)return!!l&&p>=q&&j>=d&&m>=L&&H>=w;if("vertical"===o)return!!l&&p>=q&&j>=d;if("horizontal"===o)return!!l&&m>=L&&H>=w}}}}(jQuery);

// The above lines of code is the minified version of jQuery Visible.js see  https://www.customd.com/articles/13/checking-if-an-element-is-visible-on-screen-using-jquery

   (function Forever(){ // we create a function called Forever

      var graburl = $('.pager-next a').attr('href');   // we create a variable called graburl which gets the url inside the href of the pager-next div class

      $('#comments .pager').css("display", "none"); // hides the comments pager div

      if ($('.loadmore').visible(true) && graburl != null) { // we check if the load here div is visible and also if the grab url is not empty (will be empty when we reach the last page, since there is no "next" button.

          $('.pager').remove(); // we remove/delete the pager from our website as we already grab the href with graburl variable and also we don't need this pager anymore.    
          $('.loadmore').html('<center><img src="https://i.stack.imgur.com/RCEAe.gif"></center>').load('' + graburl + ' .ajax-wrap').attr("class", "loaded"); // We place a loading gif. Then load the content inside the ajax-wrap div of "next page". Then we rename the div loadmore to loaded.

          }      

       setTimeout(Forever, 1); // if it was 1000 we would run this code every 1 second, but since it is 1, we run this code every millisecond. Basically we are looping this code.

   })();

})(jQuery);

The cool thing, if for some reason the user browser blocks jQuery, they will be able to browse the comments using the pager.

PS: In comments-wrapper.tpl.php you should move the comment form above the comments, that way people don't have to scroll all the way to the end to get the comment box. (something I did not do)

4
  • This is an awesome alternative to a pager, thanks for the idea! i gave it try and it works as designed. The only thing is that if this approach is used in combination with Ajax Comments module, it disables ajax functionality on edit/delete/reply links. I haven't opportunity yet to look deeper into the issue. This is something to keep in mind.
    – oksana-c
    Apr 8, 2016 at 14:42
  • @oksana-c that is odd, I just tried it on mine, and it works fine with Ajax Comments. Try testing it on a fresh drupal install.
    – No Sssweat
    Apr 9, 2016 at 4:58
  • You could also try using/adding jQuery.noConflict(); see 2nd example.
    – No Sssweat
    Apr 9, 2016 at 5:03
  • @oksana-c oh I see what could be causing the error. You need to install and enable jQuery Update and use the 1.10.x or 2.1.x version. I kept getting errors when I disabled jQuery Update module.
    – No Sssweat
    Apr 9, 2016 at 6:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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