matjash Posted December 20, 2016 Share Posted December 20, 2016 I need some help with threaded comments. 1. I want to use custom markup and display only 1 level deep, but I dont know how to iterate through array to output correctly. 2. I tried the general example by using function renderALL(), but the reply doesn't work. (I have put css in head and script to body) I tried with this code but it doesn't work because it double prints comments with children: <?php foreach($page->blog_comments as $comment) { if($comment->status < 1) continue; // skip unapproved or spam comments $cite = htmlentities($comment->cite); // make sure output is entity encoded $text = htmlentities($comment->text); $date = date('m/d/y g:ia', $comment->created); // format the date //If comment has children display parant and child if ($comment->children->count >= 1) { foreach ($comment->children as $children) { $cite2 = htmlentities($children->cite); // make sure output is entity encoded $text2 = htmlentities($children->text); $date2 = date('m/d/y g:ia', $children->created); // format the date include('rs-template/includes/comments/commentL2.php'); } //Display only parent } else { include('rs-template/includes/comments/commentL1.php'); } } ?> Link to comment Share on other sites More sharing options...
fbg13 Posted December 20, 2016 Share Posted December 20, 2016 This is how i do it: function getComments($comments, $page, $parentID = 0, $reply = true, $child = null) { $out = ""; foreach($comments as $comment) { if($comment->parent_id == $parentID) { $reply = ($reply == true) ? "<a class='CommentActionReply comment-reply-link' data-comment-id='{$comment->id}' href='#Comment{$comment->id}'>Reply</a>" : ""; if($comment->status < 1) continue; $cite = htmlentities($comment->cite); $text = htmlentities($comment->text); $userID = $comment->created_users_id; $u = wire("pages")->get($userID); $name = ($u->displayName) ? $u->displayName : $u->name; $date = date('m/d/y g:ia', $comment->created); $out .= " <div class='{$child}'> <article id='comment-{$comment->id}' class='comment-body single-comment'> <header class='comment-meta'> <img src='{$u->avatar->size(75,75)->url}'> <strong>{$name}</strong> <a href='{$page->httpUrl}#comment-{$comment->id}' title='Link to comment' class='comment-link'><time datetime='comment_date'>{$date}</time></a> </header> <div class='comment-content'>{$text}</div> {$reply}"; $out .= "</article>"; $out .= getComments($comments, $page, $comment->id, false, "child-comment"); $out .= "</div>"; } } return $out; } // and use in the template file echo getComments($page->comments, $page); If you have trouble understanding let me know and i'll explain, going to sleep now. 4 Link to comment Share on other sites More sharing options...
matjash Posted December 20, 2016 Author Share Posted December 20, 2016 Thank you the display is perfect, now i need to customize the reply button but i have a problem also with default method if I render form via renderAll() method as stated in documentation. The reply doesnt work. On click the hashtag gets comment id, and window moves to input form. Which functionality should then happen? Does the original message gets send to the cookie or does the form get some data from comment. Js and css gets loaded correctly. Link to comment Share on other sites More sharing options...
fbg13 Posted December 20, 2016 Share Posted December 20, 2016 I use $page->comments->renderForm($args) to display the form and when someone clicks reply a new comment form is added below, this form has a hidden input with the parent id. Link to comment Share on other sites More sharing options...
matjash Posted December 20, 2016 Author Share Posted December 20, 2016 Thanks again everything is working fine. I'm just fine tuning the form output. I'm pasting my code so someone with same problems can quickly view how to customize it based on your initial answer I had to add $childFinish since my child output was in UL tag: <?php function getComments($comments, $page, $parentID = 0, $reply = true, $child = null, $childFinish = null) { $out = ""; foreach($comments as $comment) { if($comment->parent_id == $parentID) { $reply = ($reply == true) ? "<a class='comment__reply js-comment-reply CommentActionReply comment-reply-link' data-comment-id='{$comment->id}' href='#Comment{$comment->id}'>Reply</a>" : ""; if($comment->status < 1) continue; $cite = htmlentities($comment->cite); $text = htmlentities($comment->text); $userID = $comment->created_users_id; $u = wire("pages")->get($userID); $name = ($u->displayName) ? $u->displayName : $u->name; $date = date('m/d/y g:ia', $comment->created); $out .= $child . " <li class='comment__item'> <div class='comment__item-body js-comment-item'> <div class='comment__avatar'><img src=" . wire('config')->urls->templates . "rs-template/assets/media-demo/avatars/01.jpg alt=''></div> <div class='comment__item-right'> <button class='comment__item-btn'>Edit</button> <button class='comment__item-btn'>Delete</button> </div> <div class='comment__info'><span class='comment__author'>" . $cite . "</span><span class='comment__date'>" . $date . "</span> <div class='comment__content'> <p>" . $text ."</p> </div> " . $reply ."</div> </div> <!-- end of block .comment__item-body--> "; $out .= "</li>" . $childFinish; $out .= getComments($comments, $page, $comment->id, false, "<ul class='comment__children'>", "</ul>"); } } return $out; } echo getComments($page->blog_comments, $page); ?> 4 Link to comment Share on other sites More sharing options...
fbg13 Posted January 12, 2017 Share Posted January 12, 2017 If comments are sorted newest to oldest than the nested ones are also sorted like that. To have the nested comments sorted oldest to newest add if( $parentID !== 0 ){ $comments = $comments->sort("created"); } at the top of the function. 1 Link to comment Share on other sites More sharing options...
MilenKo Posted August 8, 2017 Share Posted August 8, 2017 @fbg13 I used parts of your code for my Latest commeents block and it works fine, but I have a little issue I am trying to figure out - when I try to echo $cite it shows nothing instead of showing the author. I made it work by using your way: $userID = $comment->created_users_id; $u = wire("pages")->get($userID); $name = ($u->displayName) ? $u->displayName : $u->name; However I am trying to figure out why $cite would be empty as it is much easier to use that instead of the extra lines. Any ideas or thoughts about possible reasons? My code sample is in this topic Link to comment Share on other sites More sharing options...
adrian Posted August 8, 2017 Share Posted August 8, 2017 Remember that the "cite" field is not storing the same info as the "created_users_id". In most cases, "created_users_id" will be "40" - the ID of the guest user. "cite" can be entered manually. Have you checked the "cite" field in the DB table for the comment field? Is it actually being populated? May or may not be useful, but if your users are always logged in, check out this very old PR: https://github.com/ryancramerdesign/ProcessWire/pull/954 Link to comment Share on other sites More sharing options...
fbg13 Posted August 8, 2017 Share Posted August 8, 2017 @MilenKo Works for me. Check the db if there is an actual value for cite. Link to comment Share on other sites More sharing options...
MilenKo Posted August 8, 2017 Share Posted August 8, 2017 @adrian Thanks very much for the shared info and the link. As far as I am just finding out some pieces of the way comments can be pulled through the API, I did not went that far yet to check in the DB but will do. In case the cite in database does not have any value, are there any settings to have the values added for the comments or do you know of any possible reason why 'cite' would stay empty? So far I tried to add a few users to the site and post a few comments and they show perfectly well so the code borrowed from FBG worked in my case but not using $cite. @fbg13 What you are saying seems the same as adrian. Let me check if the DB holds any cite values and see what could be the issue if not. Link to comment Share on other sites More sharing options...
adrian Posted August 8, 2017 Share Posted August 8, 2017 3 minutes ago, MilenKo said: So far I tried to add a few users to the site and post a few comments and they show perfectly well so the code borrowed from FBG worked in my case but not using $cite. Again - using @fbg13's code is not pulling the value from the cite field, but rather from the details of the currently logged in user. If you require that a user is logged in before commenting, that will be fine, but if not, it will always return the guest user, so you would need to figure out the issue with cite. Let us know what you find regarding the cite DB column/field. As for why it might not be being populated, are you using $page->comments->renderForm() to generate the comment form, or are you creating it manually? Is it asking for "Your Name" along with email address and the actual comment The "Your Name" field is what populated the "cite" field in the db. Link to comment Share on other sites More sharing options...
MilenKo Posted August 8, 2017 Share Posted August 8, 2017 Oh, now after reading what you say, I might have an issue with the form that adds the comments as I did decided to allow the commenting for the registered users only (intending to provide an option for switching in the admin later), so if the user is logged on, I populate the name in the form directly leaving only the comment block to have hold the text. The name and email are hidden, so if cite is populated through the name, then there has to be something wrong with the value... Here is my comments block code: Spoiler <!-- Comments --> <div id="comments" class="comments-area"> <?php $comm_count = count($page->comments); if($comm_count) { ?> <h2 class="comments-title section-title h3"><i class="line"></i>There are <?=$comm_count?> comment(s) approved in this article:</h2> <? } ?> <?php foreach($page->comments as $comment) { if($comment->status < 1) continue; // skip unapproved or spam comments $text = htmlentities($comment->text); $date = date('d/m/y \a\t G:i', $comment->created); // format the date $datetime = date('Y-m-d\TH:m:s', $comment->created); // Grab the author ID $userID = $comment->created_users_id; // Obtain the displayName using $u variable $u = wire("pages")->get($userID); // Obtain the user name and assign it to $name for printing $name = ($u->displayName) ? $u->displayName : $u->name; ?> <ol class="comment-list"> <li id="comment-<?=$comment->id?>" class="comment even thread-even depth-1"> <article id="div-comment-<?=$comment->id?>" class="comment-body"> <footer class="comment-meta"> <div class="comment-author vcard"> <img alt="" src="http://1.gravatar.com/avatar/?s=50&d=mm&r=g" srcset="http://1.gravatar.com/avatar/?s=100&d=mm&r=g 2x" class="avatar avatar-50 photo avatar-default" height="50" width="50"> <b class="fn"><?=$name?></b> <span class="says">said on <a href="<?=$page->url?>#comment-<?=$comment->id?>"><time datetime="<?=$datetime?>"><?=$date?> </time></a>: <br/><br/> <p><?=$text?></p> </span> </div> <!-- .comment-author --> </footer> <!-- .comment-meta --> <div class="comment-content"> </div> <!-- .comment-content --> <div class="reply comment-reply text-right"><a class="comment-reply-link btn btn-custom btn-sm" href="?replytocom=<?=$comment->id?>#respond" onclick="return addComment.moveForm( "div-comment-<?=$comment->id?>", "<?=$comment->id?>", "respond", "193" )" aria-label="Reply to ">Reply</a></div> </article> <!-- .comment-body --> </li> <!-- #comment-## --> </ol> <? } if ($user->isGuest()) { ?> <div id="respond" class="comment-respond"> <div class="alert alert-warning alert-custom"> <i class="fa fa-warning text-danger"></i> <h4>Want to add a comment?</h4> You must be <a href="#">logged in</a> to post a comment. </div> </div> <!-- #respond --> <? } else { // Process submitted comments if ($input->post->submit) { $c = new Comment(); $c->name = $sanitizer->name($input->post['name']); $c->email = $sanitizer->email($input->post['email']); $c->text = $sanitizer->textarea($input->post['text']); $c->created = time(); $c->user_agent = $_SERVER['HTTP_USER_AGENT']; $c->ip = $_SERVER['REMOTE_ADDR']; $c->created_users_id = $user->id; $c->sort = count($page->comments)+1; // set status (Spam = -2; Pending = 0; Approved = 1; ) $c->status = 1; // add new comment object to the page "comments" field $page->setOutputFormatting(false); $page->comments->add($c); $page->save('comments'); $session->redirect("./"); } ?> <div id="respond" class="comment-respond form-border"> <h3 id="reply-title" class="comment-reply-title section-title"><br /> <i class="line"/>Leave a Reply <small class="pull-right"> <a rel="nofollow" id="cancel-comment-reply-link" href="<?=$page->url?>#respond" style="display:none;" class="btn btn-custom btn-xs">Cancel reply</a> </small> </h3> <form action="./" method="post" id="commentform" class="comment-form" novalidate=""> <div class="row"> <div class="col-md-12"> <div class="comment-form-author form-group"> <input id="name" name="name" type="hidden" class="form-control" value="<?=$user->name?>" size="30"> </div> <div class="comment-form-email form-group"> <input id="email" name="email" type="hidden" class="form-control" value="<?=$user->email?>" size="30"> </div> </div> <div class="col-md-12"> <div class="form-group"> <textarea id="text" name="text" class="form-control" cols="45" rows="8" aria-required="true"></textarea> </div> </div> </div> <p class="form-submit"> <input name="submit" type="submit" id="submit" class="submit btn btn-custom btn-lg" value="Share your opinion" /> </p> </form> </div> <? } ?> </div> <!-- Comments --> Link to comment Share on other sites More sharing options...
MilenKo Posted August 8, 2017 Share Posted August 8, 2017 So I just checked and there is only one row in the DB that has in cite 'admin' . All the rest of the lines are empty, so it has to be something wrong with the form.. Link to comment Share on other sites More sharing options...
adrian Posted August 8, 2017 Share Posted August 8, 2017 6 minutes ago, MilenKo said: $c->name = $sanitizer->name($input->post['name']); You're setting the "name", but there isn't a "name" field, it's the "cite" field that you need to populate the new comment with. Maybe you could take a look at my old PR and update it for PW 3 and re-submit because it takes care of this without manually building/processing the comment submission form. 1 Link to comment Share on other sites More sharing options...
MilenKo Posted August 8, 2017 Share Posted August 8, 2017 @adrian PR? I just remembered, that the form was actually having the cite but I did not realized that I modified it to name without considering the fact that the field is caled cite but not name. Let me change it and see if it would populate the cite... Link to comment Share on other sites More sharing options...
MilenKo Posted August 8, 2017 Share Posted August 8, 2017 Yes, it did populate the name and you were perfectly right (as always ) @adrian So now I will just remove the comments and test the cite for populating the official name of the user. How would you approach leaving a comment from non-registered user? Would you allow to post and then moderate or just offer to register and then comment? Link to comment Share on other sites More sharing options...
adrian Posted August 8, 2017 Share Posted August 8, 2017 9 hours ago, MilenKo said: PR? Github Pull Request - I linked to it above, but here it is again: https://github.com/ryancramerdesign/ProcessWire/pull/954 9 hours ago, MilenKo said: How would you approach leaving a comment from non-registered user? Would you allow to post and then moderate or just offer to register and then comment? That really depends on how many comments the site is likely to get and how much time there is for moderation But then again, if there is no approval process for registration, it doesn't prevent spam comments anyway. Link to comment Share on other sites More sharing options...
MilenKo Posted August 8, 2017 Share Posted August 8, 2017 I got you, @adrian Well as far as the platform is intended to be used as an internal knowledge database, I would leave the registrations up to someone who will be charged for that, so I can eliminate the login-register forms etc. For sure I will have a look to see how it is done, but as of now it is all working. I noticed that in the comments form I was populating cite with $user->name but even if I post as a different user, all comment authors show admin instead of the user who posted the comment. Link to comment Share on other sites More sharing options...
adrian Posted August 8, 2017 Share Posted August 8, 2017 7 minutes ago, MilenKo said: I noticed that in the comments form I was populating cite with $user->name but even if I post as a different user, all comment authors show admin instead of the user who posted the comment. How are you posting as a different user? Are you logged in as a different user, or just entering a different name and email address? How are you retrieving the author - via "cite", or "created_user_id"? Link to comment Share on other sites More sharing options...
MilenKo Posted August 8, 2017 Share Posted August 8, 2017 OK. After figuring out why the cite was not populating, I changed the code to my Latest comments and in the articles-inner so that the author comes from $cite. Now for the tests I am logging as a different user (created one via the admin) and logged on as it to test the comments adding. Here is my comments adding form: <div id="respond" class="comment-respond form-border"> <h3 id="reply-title" class="comment-reply-title section-title"><br /> <i class="line"/>Leave a Reply <small class="pull-right"> <a rel="nofollow" id="cancel-comment-reply-link" href="<?=$page->url?>#respond" style="display:none;" class="btn btn-custom btn-xs">Cancel reply</a> </small> </h3> <form action="./" method="post" id="commentform" class="comment-form" novalidate=""> <div class="row"> <div class="col-md-12"> <div class="comment-form-author form-group"> <input id="cite" name="cite" type="hidden" class="form-control" value="<?=$user->name?>" size="30"> </div> <div class="comment-form-email form-group"> <input id="email" name="email" type="hidden" class="form-control" value="<?=$user->email?>" size="30"> </div> </div> <div class="col-md-12"> <div class="form-group"> <textarea id="text" name="text" class="form-control" cols="45" rows="8" aria-required="true"></textarea> </div> </div> </div> <p class="form-submit"> <input name="submit" type="submit" id="submit" class="submit btn btn-custom btn-lg" value="Share your opinion" /> </p> </form> </div> <? } ?> So I thought that $user->name would populate the name of the current user and if I am logged on as test, than the 'cite' would get populated with 'test' as author, but it shows admin on all comments in the DB and in the frontend. Link to comment Share on other sites More sharing options...
adrian Posted August 8, 2017 Share Posted August 8, 2017 Ok, but when looking at the comment form, is $user->name correctly populating the username of the currently logged in user? What about when you are processing the submission form - are you still using: $c = new Comment(); $c->name = $sanitizer->name($input->post['name']); or did you change this to the correct: $c->cite = $input->post->name('cite'); Note that I am using the $input sanitizer, but the key thing is that I am making use of the POSTed 'cite' field. Link to comment Share on other sites More sharing options...
MilenKo Posted August 8, 2017 Share Posted August 8, 2017 Well to populate the form I replaced name with cite in all instances. Here is the whole part of processing the comments: Spoiler <div id="respond" class="comment-respond"> <div class="alert alert-warning alert-custom"> <i class="fa fa-warning text-danger"></i> <h4>Want to add a comment?</h4> You must be <a href="#">logged in</a> to post a comment. </div> </div> <!-- #respond --> <? } else { // Process submitted comments if ($input->post->submit) { $c = new Comment(); $c->cite = $sanitizer->name($input->post['cite']); $c->email = $sanitizer->email($input->post['email']); $c->text = $sanitizer->textarea($input->post['text']); $c->created = time(); $c->user_agent = $_SERVER['HTTP_USER_AGENT']; $c->ip = $_SERVER['REMOTE_ADDR']; $c->created_users_id = $user->id; $c->sort = count($page->comments)+1; // set status (Spam = -2; Pending = 0; Approved = 1; ) $c->status = 1; // add new comment object to the page "comments" field $page->setOutputFormatting(false); $page->comments->add($c); $page->save('comments'); $session->redirect("./"); } ?> <div id="respond" class="comment-respond form-border"> <h3 id="reply-title" class="comment-reply-title section-title"><br /> <i class="line"/>Leave a Reply <small class="pull-right"> <a rel="nofollow" id="cancel-comment-reply-link" href="<?=$page->url?>#respond" style="display:none;" class="btn btn-custom btn-xs">Cancel reply</a> </small> </h3> <form action="./" method="post" id="commentform" class="comment-form" novalidate=""> <div class="row"> <div class="col-md-12"> <div class="comment-form-author form-group"> <input id="cite" name="cite" type="hidden" class="form-control" value="<?=$user->name?>" size="30"> </div> <div class="comment-form-email form-group"> <input id="email" name="email" type="hidden" class="form-control" value="<?=$user->email?>" size="30"> </div> </div> <div class="col-md-12"> <div class="form-group"> <textarea id="text" name="text" class="form-control" cols="45" rows="8" aria-required="true"></textarea> </div> </div> </div> <p class="form-submit"> <input name="submit" type="submit" id="submit" class="submit btn btn-custom btn-lg" value="Share your opinion" /> </p> </form> </div> <? } ?> Link to comment Share on other sites More sharing options...
adrian Posted August 8, 2017 Share Posted August 8, 2017 Did you clarify that the hidden cite form field is being populated with the correct value from $user->name ? In the DB for the comments field, you mention that the cite field getting populated with "admin" - if that is happening, then it's got to be due to the form population or processing and adding of the comment via the API. Do a test debug of the value of $input->post->cite in your code to make sure it is showing "test" and not "admin". Tracy Debugger's bd($input->post->cite) would be the easiest approach to this. Link to comment Share on other sites More sharing options...
MilenKo Posted August 8, 2017 Share Posted August 8, 2017 @adrian I am not sure how can I debug the $input->post->cite in Tracy Debugger's bd. I tried to unhide the Name and remove the value from it so that it is populated with the field content, but the comment does not show up and is not in NonApproved comments attached to the page. So something must be wrong with the form submission... Link to comment Share on other sites More sharing options...
adrian Posted August 8, 2017 Share Posted August 8, 2017 I just tested the code you posted last and it works perfectly for me, so not sure what it going on at your end. If you are new to Tracy, have a quick read of the docs: https://processwire.com/blog/posts/introducing-tracy-debugger/#bardump Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now