本次功能完全由 ChatGPT 实现,因此发布此文也是近期我对人工智能使用的一个心得体会…让 WordPress 评论框显示在内容之前,ha?起因是有一博友说评论框在评论最后感觉不太合适,体验不佳。想想确实也是,当访客围观一篇旧文想要发表一点见解时,需要翻过正文再翻过长长的评论内容,然后才能到达输入框键入文字回复,用户体验确实比较糟糕……这么一想我那留言板长久以来没人发言恐怕也有这个因素。
说干就干,目前已经发现了问题,接下来开始需求分析:想要实现访客发表评论时尽快抵达评论框。然后是解决方案:1、给评论分页;2、给评论框区域加个快捷导航,访客点一下展开或者直达;3、调换评论框和评论内容的位置,保持其一直在前;4、做一个浮动评论框;5、评论内容前后都加上评论框;6、留给你们脑洞大开。
以上几种方案排除掉大动干戈的,比较好处理的是以上第 1、3、5 种方案,我个人十分讨厌内容分页,并且分页也并不利于访客浏览。于是尝试给留言板添加两个评论框…嗯,你可能觉得这很蠢,确实很蠢,就不展开说了。然后我又设想把评论框放在评论内容之前…emmm,我个人觉得评论条数不多的情况下,还是把我这又大又丑的评论框放在页脚比较好看一些。
咦!忽然想到:要不做个判定,当评论数在一定数量以上时评论框置顶,否则在底部。
确定了方案最后开始工程建设,首先找到控制 WordPress 评论的代码段,然后对其进行改造……具体的施工环节咱指挥工人干就行,毕竟咱只会动嘴不会动手。不过话虽如此,这些个施工工人没有咱的领导和指挥,干活效率和正确率是相当拉跨。另外经我体验,至少在 WordPress 编程这方面,国内的文心一言、通义千问、Kimi 都不行,它们或许能读懂,但若说要写代码那是真不行,而且要现学资料,反应极慢。
Devv作为专门的编程机器人勘用,但是输入字数限制较低且阅读理解能力一般,有时候会犯低级错误,上下文逻辑也很差。最后还得是 AI 老大哥 ChatGPT,我体验下来不管是编程还是常规的语言类工作,它的响应和准度都是最快最好的。以我博客起名那篇文章来说,我后来又分别把关键词给了文心一言和通义千问,它们给出的回复总感觉是刚读过几年书的中学生,内容没啥创新,就知道堆词,末了总要“综上所诉”或者“总结来说”,诸如此类。
回到正题,我首先找到控制 WordPress 评论的代码段(一般是 comments.php),将其整个喂给 AI 让先消化消化,然后开始对话:请修改以下代码,实现当评论超过 50 条时评论框在评论内容之前,否则在最底部。AI 很快作出响应,它通过在原代码中添加判定函数、增加评论框核心代码的方式来实现,报错。我把错误结果反馈给它,它又能迅速的调整…就这样经历数个回合以后,依然有小错误没有实现我想要的结果。
我无奈地,自嘲般对着机器感慨了一句:我放弃了,还是不对。没想到它竟提议让我们尝试另一种方式,并且很快给出了代码…我把它写进服务器后居然成功了!至此我发现了和人工智能对话的诀窍,即要灵活运用诸如:换个方式、尝试、比如等词汇,可能会事半功倍。
随后我又提了一些小的需求,AI 都一一帮我实现了,基本达到了我预想的“当 WordPress 评论超过 50 条时,评论框在评论内容之前,否则在底部”功能,虽说目前这办法比较蠢,但至少简单轻便,对于我这样的代码盲已经很好了。我完整的comments.php
代码如下,总的来说它是写了一个 JavaScript 脚本,作用在网页加载完成后,根据一些条件动态地控制网页元素的顺序和添加一些 CSS 样式。
<?php
/*
* Comments Template
*
* @version 1.0
* @author Greatives Team
* @URI https://greatives.eu
*/
if ( post_password_required() ) {
?>
<div class="help">
<p class="no-comments"><?php esc_html_e( 'This post is password protected. Enter the password to view comments.', 'impeka' ); ?></p>
</div>
<?php
return;
}
?>
<?php if ( have_comments() ) : ?>
<!-- Comments -->
<div id="grve-comments">
<div class="grve-comments-header">
<div class="grve-comments-number grve-h5">
<?php echo"「";echo get_the_title($ID);echo"」有 "; comments_number(); ?>
</div>
<nav class="grve-comment-nav" aria-label="<?php esc_attr_e( 'Comments', 'impeka' ); ?>">
<?php previous_comments_link(); ?>
<?php next_comments_link(); ?>
</nav>
</div>
<ul class="grve-comments-list">
<?php
wp_list_comments( array(
'callback' => 'impeka_grve_comments',
'short_ping' => true,
) );
?>
</ul>
</div>
<!-- End Comments -->
<?php endif; ?>
<?php if ( ! comments_open() && get_comments_number() && post_type_supports( get_post_type(), 'comments' ) ) : ?>
<div id="grve-comments">
<p class="no-comments"><?php esc_html_e( 'Comments are closed.', 'impeka' ); ?></p>
</div>
<?php endif; ?>
<?php if ( comments_open() ) : ?>
<?php
$commenter = wp_get_current_commenter();
$req = get_option( 'require_name_email' );
$args = array(
'id_form' => 'commentform',
'id_submit' => 'grve-comment-submit-button',
'title_reply' => esc_html__( 'Leave a Reply', 'impeka' ),
'title_reply_to' => esc_html__( 'Leave a Reply to', 'impeka' ) . ' %s',
'cancel_reply_link' => esc_html__( 'Cancel Reply', 'impeka' ),
'label_submit' => esc_html__( 'Submit Comment', 'impeka' ),
'submit_button' => '<input name="%1$s" type="submit" id="%2$s" class="%3$s" value="%4$s" />',
'comment_field' =>
'<div class="grve-form-textarea grve-border">'.
'<div class="grve-form-inner">' .
'<label>' . esc_attr__( 'Your Comment Here...', 'impeka' ) . '</label>' .
'<textarea class="grve-form-input-item" id="comment" name="comment" cols="45" rows="10" aria-required="true">' .
'</textarea></div></div>',
'must_log_in' =>
'<p class="must-log-in">' . esc_html__( 'You must be', 'impeka' ) .
'<a href="' . wp_login_url( get_permalink() ) . '">' . esc_html__( 'logged in', 'impeka' ) . '</a> ' . esc_html__( 'to post a comment.', 'impeka' ) . '</p>',
'logged_in_as' =>
'<div class="logged-in-as">' . esc_html__('Logged in as','impeka') .
'<a class="grve-text-content grve-text-hover-primary-1" href="' . esc_url( admin_url( 'profile.php' ) ) . '"> ' . $user_identity . '</a>. ' .
'<a class="grve-text-content grve-text-hover-primary-1" href="' . wp_logout_url( get_permalink() ) . '" title="' . esc_attr__( 'Log out of this account', 'impeka' ) . '"> ' . esc_html__( 'Log out', 'impeka' ) . '</a></div>',
'comment_notes_before' => '',
'comment_notes_after' => '' ,
'fields' => apply_filters(
'comment_form_default_fields',
array(
'author' =>
'<div class="grve-form-input grve-half-size grve-border">' .
'<div class="grve-form-inner">' .
'<label>' . esc_attr__( 'Name', 'impeka' ) . ' ' . ( $req ? esc_attr__( '*', 'impeka' ) : '' ) . '</label>' .
'<input id="author" class="grve-form-input-item" name="author" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '"' .
' />' .
'</div>' .
'</div>',
'email' =>
'<div class="grve-form-input grve-half-size grve-border">' .
'<div class="grve-form-inner">' .
'<label>' . esc_attr__( 'E-mail', 'impeka' ) . ' ' . ( $req ? esc_attr__( '*', 'impeka' ) : '' ) . '</label>' .
'<input id="email" class="grve-form-input-item" name="email" type="text" value="' . esc_attr( $commenter['comment_author_email'] ) . '"' .
' />' .
'</div>' .
'</div>',
'url' =>
'<div class="grve-form-input grve-border">' .
'<div class="grve-form-inner">' .
'<label>' . esc_attr__( 'Website', 'impeka' ) . '</label>' .
'<input id="url" class="grve-form-input-item" name="url" type="text" value="' . esc_attr( $commenter['comment_author_url'] ) . '"' .
' />' .
'</div>' .
'</div>',
)
),
);
?>
<script>
document.addEventListener("DOMContentLoaded", function() {
var commentForm = document.getElementById("grve-comment-form");
var commentsNumber = parseInt(document.querySelector(".grve-comments-number").textContent.match(/\d+/)[0]);
if (commentsNumber >= 50) {
var commentsHeader = document.querySelector(".grve-comments-header");
commentsHeader.parentNode.insertBefore(commentForm, commentsHeader);
var replyTitle = document.getElementById("reply-title");
replyTitle.style.display = "none";
var commentForm = document.getElementById("grve-comment-form");
commentForm.style.marginBottom = "30px";
}
});
</script>
<div id="grve-comment-form">
<?php
//Use comment_form() with no parameters if you want the default form instead.
comment_form( $args );
?>
</div>
<?php endif;
//Omit closing PHP tag to avoid accidental whitespace output errors.
至此,你可以对比本文评论部分和留言板的效果,应该说至少目的达到了吧……又借此逼逼奈奈水了一篇文章,但不得不说,AI 真的已经在改变我们的生活了。就最近我折腾 WordPress 时已经让 AI 帮忙做了很多工作,我就像个领导,指挥它、提示他、一步一步地完善,直到完成最后的工作……尽管我的需求可能无理,指挥的方向也不对,但不管怎样它都任劳任怨,不会摔键盘,工作态度相当 OK!
后来发现这个代码始终有一点小小的 Bug,且觉得在每个页面都去做条件判定有点儿浪费资源,反正我文章的评论不会很多…于是索性复制singular.php
另起了一个template-guestbook.php
,把上述的 Javascript 代码复制进去控制让评论框置顶,然后设置留言页面使用本模板,达到仅更改此页的目的。
另外分享一个代码片段:实现 WordPress 正文外部链接添加?ref=domain.com
网站来源信息和rel="external nofollow" target="_blank"
。这个代码片段因为我要排除目录 a 标签带来的干扰,也是 AI 沟通了许久才完美实现。
// 将正文所有外链加上 ?ref=shephe.com ,并添加 rel="external nofollow" target="_blank"
add_filter('the_content', 'rewrite_external_links');
function rewrite_external_links($content) {
$srcUrl = home_url(); // 获取站点 URL
$regexp = '/<a\s(?:[^>]*?\s)?href=(["\'])(.*?)\1(?:[^>]*)>(.*?)<\/a>/si';
preg_match_all($regexp, $content, $matches, PREG_SET_ORDER);
if (empty($matches)) {
return $content;
}
foreach ($matches as $match) {
$url = $match[2]; // 链接地址
if (strpos($url, $srcUrl) === false && strpos($url, '#') === false) { // 排除掉带#的链接(文章目录)
$new_url = $url . '?ref=shephe.com';
$new_tag = '<a href="' . $new_url . '" rel="external nofollow" target="_blank">' . $match[3] . '</a>';
$content = str_replace($match[0], $new_tag, $content);
}
}
return $content;
}
评论表单我也调在前面了,你的好像还在后面,没有在评论内容之前啊