前言

@权那他网站的时候,惊奇地发现Major主题竟然有个贴心的小功能:使用QQ/Github快速评论,这个功能对于我这样一个懒癌来说简直不要太爽。

通过这个功能,我们仅仅输入QQ/Github账号就可以免去填写一大堆信息(昵称、网址、邮箱),从而减少评论的负担。

我与权那他的对话
我与权那他的对话

方法

贴心的博主@权那他也是非常乐意地贴出了教程1,这里我也引用下:

  • 首先,找到文件comments.php

https://github.com/typecho/typecho/blob/master/usr/themes/default/comments.php
比如在官方模板的第24行找到:

<p>
   <label for="author" class="required"><?php _e('称呼'); ?></label>
   <input type="text" name="author" id="author" class="text" value="<?php $this->remember('author'); ?>" required />
</p>

QQ部分

  • 然后在输入网址的后面复写一个, 重要的是id="qqNum",比如:
<p>
   <label for="qqNum"><?php _e('快速评论'); ?></label>
   <input placeholder="QQ号输入快速评论" type="text" id="qqNum" class="text" style="font-size: 12px;"/>
</p>
  • 然后 Js 监控输入事件,注意#qqNum
$(document).on("input propertychange", "#qqNum", function (event) {
        event.preventDefault();
        let oldVal = $(this).val();
        let qq = window.setTimeout(function () {
            let newVal = $("#qqNum").val();
            if (newVal.length > 0 && oldVal === $("#qqNum").val() && !newVal.isNaN) {
                $.ajax({
                    url: 'https://api.krait.cn/?interface=personage&target=tencent&object=' + newVal,
                    dataType: 'jsonp',
                    jsonpCallback: 'portraitCallBack',
                    scriptCharset: "GBK",
                    contentType: "text/html; charset=GBK",
                    success: function (data) {
                        console.log(data);
                        //document.getElementById("comment-form-avatar").getElementsByTagName("img")[0].src = data["avatar_url"];  这里是替换头像,有些的评论框有展示头像的,比如我的就是,可以把comment-form-avatar替换为你绑定的头像div的id
                        $('#author').val(data["nickname"]);
                        $('#mail').val(data["email"]);
                    }
                })
            }
        }, 500);// 这里的500,表示输入过后0.5秒开始请求
    });

别忘记放在<script> //code </script>里面,最好在加在<?php if(!$this->user->hasLogin()): ?> //code <?php endif; ?>因为登录的用户不需要,只是给来访者的。

可以看出这里用到的 api 接口是https://api.krait.cn/?interface=personage&target=tencent&object=qqNum
为什么呢?这是因为腾讯这个坑爹的不给全接口,而且给非常隐蔽的接口还不能跨站请求。

如果怕不安全,可以自己写API接口,以下是@权那他附上的代码:

header("Access-Control-Allow-Origin: *");
header("Content-type: text/json; charset=UTF8");
if (
    !isset($_GET["object"]) ||
    $_GET["object"] == null ||
    !is_numeric($_GET["object"]) ||
    strlen($_GET["object"]) < 5) exit('Access Violation');
$object = $_GET["object"];
$apiInterface = 'http://r.qzone.qq.com/fcg-bin/cgi_get_score.fcg?mask=7&uins=';

try {
    $data = $this->curl_file_get_contents($apiInterface . $object);
    $pattern = '/portraitCallBack\((.*)\)/is';
    preg_match($pattern, $data, $result);
    $nickname = json_decode($result[1], true)["$object"][6];
    $json = json_encode(
        array(
            "id" => $object,
            "nickname" => $nickname,
            "avatar_url" => "https://q2.qlogo.cn/headimg_dl?dst_uin=$object&spec=100",
            "email" => $object . "@qq.com"
        ),
        JSON_UNESCAPED_UNICODE
    );
    echo "portraitCallBack(" . $json . ");";
} catch (Exception $e) {
    echo $e;
}

Github部分

  • 基本和QQ部分相同,把id="qqNum"改为id="githubNum"

然后就是JavaScript代码:

function isEmpty(obj) {
        return typeof obj == "undefined" || obj == null || obj == "";
}
$(document).on("input propertychange", "#githubNum", function (event) {
        event.preventDefault();
        let oldVal = $(this).val();
        let github = window.setTimeout(function () {
            let newVal = $("#githubNum").val();
            if (newVal.length > 0 && oldVal === $("#githubNum").val()) {
                $.ajax({
                    url: 'https://api.github.com/users/' + newVal,
                    dataType: 'jsonp',
                    scriptCharset: "GBK",
                    contentType: "text/html; charset=GBK",
                    success: function (data) {
                        console.log(data);
                        let personal = data["data"];
                        //document.getElementById("comment-form-avatar").getElementsByTagName("img")[0].src = personal["avatar_url"];
                        $('#author').val(isEmpty(personal["name"]) ? personal["login"] : personal["name"]);
                        $('#url').val(isEmpty(personal["blog"]) ? personal["html_url"] : personal["blog"]);
                        //$('#mail').val(isEmpty(personal["email"]) ? "@" : personal["email"]);
                    }
                })
            }
        }, 1000);//这里是一秒,尽量长一些
    });

接口是https://api.github.com/users/name
至此快速评论功能就添加完毕了,剩下的就是需要自己根据模板进行调整。

补充

Typecho默认评论头像是获取Gravatar头像,那么如何实现输入QQ邮箱获取QQ头像,而输入Gravatar注册邮箱获取Gravatar头像呢?其实非常简单

只需要找到var/Typecho/common.php这个文件,在1000行左右有获取Gravatar头像的代码,将其修改为

public static function gravatarUrl($mail, $size, $rating, $default, $isSecure = false)
    {
            $reg = "/^\d{5,11}@[qQ][Qq]\.(com)$/";
            if (preg_match($reg, $mail)) {
                $img    = explode("@", $mail);
                $url = "//q2.qlogo.cn/headimg_dl?dst_uin={$img[0]}&spec=100";
            } else {
                if (defined('__TYPECHO_GRAVATAR_PREFIX__')) {
                    $url = __TYPECHO_GRAVATAR_PREFIX__;
                } else {
                    $url = $isSecure ? 'https://secure.gravatar.com' : 'http://www.gravatar.com';
                    $url .= '/avatar/';
                }
                if (!empty($mail)) {
                    $url .= md5(strtolower(trim($mail)));
                }
                $url .= '?s=' . $size;
                $url .= '&amp;r=' . $rating;
                $url .= '&amp;d=' . $default;
            }
            return $url;
    }

后记

不得不说这个功能是真的方便,再次感谢@权那他博主的教程和热情地帮我实现这个功能。也欢迎大家使用@权那他博主自己写的Typecho手机客户端 - Nabo

此外,我特别害怕有人看到评论信息这么多反而不评论了,这恰恰违背了我简化评论的初衷。所以,我特别增加了评论必看,用以说明:使用QQ或Github账号可以自动填写信息,并且特别说明必填和非必填。

本博也新增了垃圾验证 - 非机器人验证,虽然这个功能挺鸡肋的,并不能抵挡超厉害的垃圾评论...但还是请大家认真评论,并勾选「非机器人」

总之,我希望大家都能认真评论,说出真实看法,建议也好批评也好,这些都对我弥足珍贵,而不是仅仅是留个脚印。


  1. Krait原文:《让博客评论起来更方便》