If you’re tired of Disqus and Jetpack, then you need to switch back to default WordPress comments. And it hurts.
Both, Disqus and Jetpack do two things: spam prevention and notifications. Plus Disqus looks good, while Jetpack needs some styling. But that’s another case.
Spam prevention
Probably that’s me being lazy, but I just took the Akismet. It works, doesn’t add javascript to the page and it’s invisible. Cool, I like that. I’m using Akismet for years and it’s all good. Sometimes legit comments land in spam, but it’s not a common issue and it requires checking that tab once in two weeks. No biggie.
Without a plugin? Eee… I do not recommend that. My main blog is not a big one, with ~300 daily visitors and I got 42 spam comments within last 5 days. Wow, right?
Notifications
You, as a blog post author, have the notifications on by default. Every time someone leaves a comment on the post you’ve written, you’ll get the email. But the thing we all love about
With default WordPress comments you don’t have any option to enable notifications. With Jetpack comments you can add the “subscribe” button, but it’s not good—it’ll email you with comments on a specific post, not just a replies to yours. Annoying? For sure. May work with smaller blogs, but it’s still not that what people really want.
Plugins? I’ve tried to find something and I failed, but that was years ago. Maybe there is something that actually works and my work is unnecessary (but I don’t want to think about it).
Let’s code, okay?
add_action();
What do you need to do when you want to do something? Think about it. Think it through. You need to know what you want to achieve and then collect all the pieces you might need.
add_action
— actions are the hooks that launch in WordPress core and then do specific things.
We need two actions:
One for posts that are published right away, meaning: posted by you or people who left comments before and you’ve approved them. They’re not jumping to the moderation panel. That’s important.
Second for comments that are moderated and changing status to approved
.
The actions we need are called comment_post
and transition_comment_status
. And to these actions we need to attach functions. Mine will be called dyzqus, since it’s Disqus-based and made by Yz (Yzoja)—me. Hi!
function dyzqus_nomoderation($comment_ID, $comment_approved ) {
}
add_action('comment_post', 'dyzqus_nomoderation', 10, 2 );
function dyzqus_moderation($new_status, $old_status, $data ) {
}
add_action('transition_comment_status', 'dyzqus_moderation', 10, 3);
add_action
structure: name of the hook, name of the function, priority and number or parameters used in your function and hook. I think the names states clearly which parameters do what.
That’s the base. Rest of the code will be inside the function.
function();
What we need to do now?
Check the status of the comment, right? We want to notify people only in the case that the comment is published. nomoderation
0
1
spam
$comment_approved
is 1
.
if ($comment_approved === 1) {
// magic, soon.
}
moderation
approved
unapproved
spam
$new_status
is approved
AND if the previous value is different than that. Because that would fire the function when you edit already approved comment to fix the typos or something like that. We don’t need that.
if ($old_status != 'approved' && $new_status == 'approved') {
// magic, soon.
}
Cool! What’s next?
Parent?
There is no point in trying if the comment doesn’t have parent—right?
We need to get the comment’s data to find out if the parent is 0
or something else. 0
$data = get_comment($comment_ID); // for nomoderation
In moderatated
part we have the $data
set already in the hook.
$parent = $data->comment_parent;
if ($parent != 0) {
}
}
Another code block to check if there is a parent or there isn’t (default value for comment_parent
0
. If there is a parent, then the value is the parent comment ID).
Parent done. We can send emails!
Data for the email
The fun starts here, right? I like using default wp_mail
function. Easy, works and allows to send HTML emails.
What we need?
Email address of the parent comment’s author. Check.
$parentData = get_comment($parent);
$email = $parentData->comment_author_email;
We could actually stop right there. Just send an email “Hi, someone replied to your comment”. But it would be nice to include at least the name of your blog, the post title, maybe the comment’s content and author?
$reply = $data->comment_content; // child comment's content
$author = $data->comment_author; // child comment's author name
$link = get_permalink($data->comment_post_ID); // post's link
With the get_the_title()
but it doesn’t work perfectly. If you’re using
Funny thing: Disqus “handles” it exactly that way. But we can do it better than Disqus, okay?
$title = get_the_title($data->comment_post_ID); // if you're not using special characters
$post = get_post($data->comment_post_ID);
$title = $post->post_title; // if you want to be careful
Now it’s time for gathering all the stuff we have, ready?
Sending emails
Now we need: email’s subject and content. We already have the email.
$blogname = get_bloginfo('name');
$subject = sprintf('[%1$s] Reply to your comment: "%2$s"', $blogname, $post_title );
That’s the “syntax” used in WordPress notification, basic but have everything. First part is the name of your blog and the second one the post title. So, it’s: [CSS Princess] Reply to your comment: Gutenberg 1.7.0. Feel free to change it. You can drop the blogname
part, use the Disqus style.
$subject = 'Re: Comment on ' . $post_title;
If you want, and I think you do, use the HTML in your emails, then you need to have headers set.
$headers = array('Content-Type: text/html; charset=UTF-8');
Headers can contain Bcc
$headers = array('Content-Type: text/html; charset=UTF-8', 'From: CSS Princess <notifications@devgirl.space>');
It’s time for the message.
$message = '<body style="font-size:16px;font-family:Arial;width: 100%;max-width: 500px;margin:0 auto;"><div style="color: #fff;font-weight:bold; border-radius:40px;background: #b90063;padding: 20px;font-size: 20px;">Someone replied to your comment</div><div style="padding:10px 20px;"><p>Hi,<br><strong>' . $author . '</strong> replied to your comment:</p></div><div style="margin: 20px;background:#eee;padding:10px;line-height:170%;font-size:14px;">' . wpautop($reply) . '.</div><div style="padding:10px 20px;"><p>Go to the post (' . $link . ') to reply.</p></div></body>';
Inline styles and all stacked together, sorry.
And more Disqus-looking alternative:
$message = '<body style="font-size:16px;font-family:Arial;background: #eee;"><div style="background: #fff;width: 100%;margin:0 auto;max-width: 500px;padding:20px;box-shadow:0 2px 4px rgba(0,0,0,0.1);"><p>Hi, there is a new comment on ' . blogname .'.</p><div style="background: #9be9f2;height: 5px;margin-bottom:20px;"></div><strong>' . $author . '</strong>:<div style="background:#eee;padding:10px;line-height:170%;font-size:14px;">' . wpautop($reply) . '.</div><div style="margin-top:30px;padding:10px 0px;"><a style="color:#fff;text-decoration:none;border-radius:4px;background:#9be9f2;font-weight:bold;font-size:12px;padding:10px 20px" href="' . $link . '">Go to the post to reply.</a></div></div></body>';
With email’s body, you can play for hours. Add images, buttons, posts excerpt, thumbnail, the avatar of the person who left a comment or the parent comment’s content, to let people know the context right there in the email notification.
Grand finale
wp_mail( $email, $subject, $message, $headers);
Done.
The full code:
function dyzqus_notifications($data, $comment_ID) {
$reply = $data->comment_content;
$author = $data->comment_author;
$post = get_post($data->comment_post_ID);
$post_title = $post->post_title;
$blogname = get_bloginfo('name');
$subject = sprintf( __('[%1$s] Reply to your comment: "%2$s"'), $blogname, $post_title );
$link = get_permalink($data->comment_post_ID);
$parent = $data->comment_parent;
if ($parent != 0) {
$parentData = get_comment($parent);
$email = $parentData->comment_author_email;
$message = '<body style="font-size:16px;font-family:Arial;background: #eee;"><div style="background: #fff;width: 100%;margin:0 auto;max-width: 500px;padding:20px;box-shadow:0 2px 4px rgba(0,0,0,0.1);"><p>Hi, there is a new comment on ' . blogname .'.</p><div style="background: #9be9f2;height: 5px;margin-bottom:20px;"></div><strong>' . $author . '</strong>:<div style="background:#eee;padding:10px;line-height:170%;font-size:14px;">' . wpautop($reply) . '.</div><div style="margin-top:30px;padding:10px 0px;"><a style="color:#fff;text-decoration:none;border-radius:4px;background:#9be9f2;font-weight:bold;font-size:12px;padding:10px 20px" href="' . $link . '">Go to the post to reply.</a></div></div></body>';
$headers = array('Content-Type: text/html; charset=UTF-8', 'From: CSS Princess <angie@devgirl.space>');
wp_mail( $email, $subject, $message, $headers);
}
}
function dyzqus_nomoderation( $comment_ID, $comment_approved ) {
if ($comment_approved === 1) {
$data = get_comment($comment_ID);
dyzqus_notifications($data, $comment_ID);
}
}
add_action( 'comment_post', 'dyzqus_nomoderation', 10, 2);
function dyzqus_moderation( $new_status, $old_status, $data ) {
if ($old_status != 'approved' && $new_status == 'approved') {
$comment_ID = $data->comment_ID;
dyzqus_notifications($data, $comment_ID);
}
}
add_action( 'transition_comment_status', 'dyzqus_moderation', 10, 3);
35 lines of code. 34 if you’ll delete that empty line 16 before
wp_mail
The code works, it feels good! Can work with just default WordPress comments or with Jetpack, or with any other plugin for comments that still
(P.S.: paste the code to your functions.php
, of course)
This is a great hack, and a really nice tutorial. Thank you for posting this!
Hi. Thanks for this code. I have question. How add link “unsubscribe”?
There is no such thing right now, but I’ll need to update the code to fit into GDPR guidelines (which is kinda tricky, because most efficient way would be to store the emails of the people, who want to unsubscribe…)