7

I want to show comments of nodes ordered by vote result (most popular comment at the top of the list). I have installed voting API, rate and views module. Then add a yes/no voting to comments and enable threading for comments in order to let users reply each other.

I created a views to show comments in most popular order with these sort criteria:

Comment: Thread (asc)
SUM(Votes: Value)

Now the problem is that when views tries to keep thread it sort theme by post date (asc/disc) and do not see the second sort criteria.

So how can I sort comments by vote results keeping threading?

EDIT: views config

8
  • can you post a screenshot of your view config? Jan 29, 2017 at 5:33
  • @longboardnode yes of course. I add it to my question
    – shekoufeh
    Jan 29, 2017 at 5:41
  • why are you using aggregation?
    – No Sssweat
    Feb 1, 2017 at 8:57
  • 1
    @NoSssweat because I need the summation of vote result. It doesn't effect the problem for sure.
    – shekoufeh
    Feb 1, 2017 at 10:41
  • What happens if you remove Comment: Thread (asc)?
    – No Sssweat
    Feb 1, 2017 at 10:46

1 Answer 1

2
+25

Main problem

Currently there is no way to tie all the children and grandchildren comments to the Main Parent (original/first ever parent). Also, need a way to separate the Main parent from all the children.

TL, DR Solution

Use the Views field view module to separate the children from main parent, and add all children as a field. That way, we are able to sort Main Parent's by Votes without affecting the children and grandchildren.

But there is no way to just show all children and grandchildren of a Main Parent CID; therefore, create a custom module to solve this problem, so we can use the view field technique.

Detailed Solution

Requirements:

Views field view, Entity API, Main PID (custom module below).


main_pid.info

name = Main PID
description = Links all children and grandchildren comments to the main parent by saving main parent cid into main_parent_pid field when comment is saved.
package = custom
core = 7.x

main_pid.module

<?php

/**
 * Implements hook_comment_presave()
 */ 
function main_pid_comment_presave($comment) {
  
  $pid = $comment->pid;
  
  if ($pid > 0){
  
    while ($pid > 0) {
      // Implements comment_load()
      $load_comment = comment_load($pid);
  
      $pid = $load_comment->pid;
      $cid = $load_comment->cid;
      
    }
    
    $comment->field_main_pid[LANGUAGE_NONE][0]['value'] = $cid;
  
  }
  
  elseif ($pid == 0) {
    
    $comment->field_main_pid[LANGUAGE_NONE][0]['value'] = 0;
    
  }
  
}

Now in comments add a new field called Main PID with machine name of field_main_pid. You can do this programmatically or using the Drupal UI (I will leave this up to you)

enter image description here

Now, hide field from display

enter image description here


In your view:

In fields, add Comment: Rendered Comment (Thanks to Entity API)

enter image description here

In fields, add Comment ID

enter image description here


Now add a new block

enter image description here

Click on block, and change the display name

enter image description here

In fields add Depth

enter image description here

In fields, add Comment: Rendered Comment (Thanks to Entity API)

enter image description here

The style settings will allow you to indent the children with CSS.

Example:

.depth-1 { width: 480px; margin-left: 10px; }
.depth-2 { width: 470px; margin-left: 20px; }

In Filter Criteria, add Content: Main PID

enter image description here

Only the Main parent has PID of 0, therefore, this will show all the children only

Then add Content: Thread in Sort and Main PID in Contextual Filter

So your Children View should look like this:

enter image description here


Going back to the first View:

In Filter Criteria add Main PID

enter image description here

This time equal to 0, since we only want the main parents.

Now in Fields, add Global: View (Thanks to Views field View)

enter image description here

Your Original/Main View Should look like this:

Important: Add contextual filter of NID here (forgot to do that).

enter image description here

Lastly, In Sort Criteria, add the Votes Value (Not shown on screenshot since I did not bother to install Voting API and Rate) and remove the default Post date.

7
  • thanks alot for your complete answer. there is two problems: first, if I add fields in views one by one the vote API module does not work. I mean it works just when I use rendered entity. Second, I can not add a field to comments because I have three tabs sorting comments by oldest, newest and most popular. So the collection of requirements limits me and it is making me crazy.
    – shekoufeh
    Feb 5, 2017 at 5:02
  • @shekoufeh I add fields in views one by one the vote API module does not work. I mean it works just when I use rendered entity but in my answer the Comment: Rendered Comment field renders the entity (comment)... (no need to add fields one by one, title, body, etc..), so it should work here too. Did you try my answer out? Second, I can not add a field to comments because I have three tabs sorting comments by oldest, newest and most popular. On your screenshot I do not see this, also why would adding a field affect your tab?
    – No Sssweat
    Feb 5, 2017 at 6:15
  • How did you set Main PID in Contextual Filter? set it to "Display all results for the specified field " in Contextual Filter setting page?
    – shekoufeh
    Feb 9, 2017 at 7:31
  • @shekoufeh yep.
    – No Sssweat
    Feb 9, 2017 at 7:34
  • 1
    the original list of comments need comment:nid in order to show comments of each node of themselves.
    – shekoufeh
    Feb 9, 2017 at 8:38

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.