Note: Since I stopped using this theme later on, this content is for reference only, orz.

@良心发现's theme Oneiro, which he claims is an "impromptu piece of tinkering with HTML5," uses a large number of new HTML features and contains much experimental content. Normally, as someone who merely gets by on the frontend and wants to devote more energy to the backend, I would have ignored this theme. But it's just too beautiful — really well done.

So I downloaded the theme, crudely modified a bunch of settings, and directly deployed it on my small site. Previous modifications were mostly of the "I just like it this way" variety. Today I made some tweaks to fix minor flaws. This post mainly records some improvements to the comments section.

Switching "Reply" back to JS control

Liangxin set comment replies to a flat style. Compared to the increasingly popular nested version, it looks more harmonious, and if I tried to modify it, I — a CSS novice with a naturally poor sense of aesthetics — obviously couldn't do better. So the flat format stays. The problem is that in the original design, when "a replies to b," b is on some floor above and a simply @-mentions b, and that @ isn't even a link. This makes comment interaction quite problematic. Moreover, although the original work @-mentions the person above, the comment data structure in the backend doesn't reflect that relationship either. So if the theme is later changed to a nested format, organizing these conversations in the interim will be less than ideal.

Checking the backend code, you can see this structure:

While iterating through the comments list, the author added a "Reply" hyperlink to each comment item. This hyperlink calls a JS function:

JavaScript
function to_reply(commentID,author) {
  var nNd='@'+author+':';
  ...
  var myField = document.getElementById('comment');
  ...
  if (document.selection) {
    sel = document.selection.createRange();
    sel.text = nNd;
    myField.focus();
  }
}

It actually does three things: find the comment form, add some content to its textarea, and focus it.

According to the requirements, the first modification is to enrich this "add some content." Since commentID is already available, we can directly modify the value of nNd.

Change the second line above to

JavaScript
var nNd='<a href=\'#comment-'+commentID+'\'>@'+author+' </a>';
This way, the @ target in each comment becomes much more meaningful, and clicking the hyperlink jumps directly to the replied-to floor.

Previously, I directly changed it to submit a POST and used WP's built-in method to handle it — obviously that wasn't appropriate.

Nesting comments

The WordPress comment form looks roughly like this:
mysql> show columns from wp_comments;
+----------------------+---------------------+------+-----+---------------------+----------------+
| Field                | Type                | Null | Key | Default             | Extra          |
+----------------------+---------------------+------+-----+---------------------+----------------+
| comment_ID           | bigint(20) unsigned | NO   | PRI | NULL                | auto_increment |
| comment_post_ID      | bigint(20) unsigned | NO   | MUL | 0                   |                |
| comment_author       | tinytext            | NO   |     | NULL                |                |
| comment_author_email | varchar(100)        | NO   |     |                     |                |
| comment_author_url   | varchar(200)        | NO   |     |                     |                |
| comment_author_IP    | varchar(100)        | NO   |     |                     |                |
| comment_date         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| comment_date_gmt     | datetime            | NO   | MUL | 0000-00-00 00:00:00 |                |
| comment_content      | text                | NO   |     | NULL                |                |
| comment_karma        | int(11)             | NO   |     | 0                   |                |
| comment_approved     | varchar(20)         | NO   | MUL | 1                   |                |
| comment_agent        | varchar(255)        | NO   |     |                     |                |
| comment_type         | varchar(20)         | NO   |     |                     |                |
| comment_parent       | bigint(20) unsigned | NO   | MUL | 0                   |                |
| user_id              | bigint(20) unsigned | NO   |     | 0                   |                |
| comment_mail_notify  | tinyint(4)          | NO   |     | 0                   |                |
+----------------------+---------------------+------+-----+---------------------+----------------+

Among them, the comment_parent column is actually the ID of the person being replied to. If there is no reply target, it's 0.

Liangxin's theme uses Willin Kan's comments-ajax.php. Checking this PHP file, you can see:

PHP
$comment_parent = isset($_POST['comment_parent']) ? absint($_POST['comment_parent']) : 0;

So as long as the form submitted via AJAX contains the comment_parent variable, it's sufficient.

And the WP form being submitted contains the comment_parent element:

HTML, XML
<input type='hidden' name='comment_parent' id='comment_parent' value='0' />

So we just need to modify its value in the to_reply function mentioned earlier.

Add one line in the to_reply function:

document.getElementById('comment_parent').value = commentID;
One line solves the problem.

Reply email notifications

Previously I used WP Mail SMTP and Mail to Commenter. WP Mail SMTP has been in use all along and works very well. Mail to Commenter was officially recommended by the theme author, Liangxin. But the results were unsatisfactory. Later I switched to the combination of Configure SMTP + Comment Reply Notification. After several tests, it performed well. Although I don't know whether it will remain stable in the future, at least for now it can be considered perfectly done.