<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel rdf:about="https://www.ishiguang.cn/feed/rss/tag/%E6%8F%92%E4%BB%B6/">
<title>拾光 - 插件</title>
<link>https://www.ishiguang.cn/tag/%E6%8F%92%E4%BB%B6/</link>
<description></description>
<items>
<rdf:Seq>
<rdf:li resource="https://www.ishiguang.cn/16495.html"/>
<rdf:li resource="https://www.ishiguang.cn/14392.html"/>
<rdf:li resource="https://www.ishiguang.cn/7463.html"/>
<rdf:li resource="https://www.ishiguang.cn/6673.html"/>
<rdf:li resource="https://www.ishiguang.cn/6672.html"/>
<rdf:li resource="https://www.ishiguang.cn/6671.html"/>
<rdf:li resource="https://www.ishiguang.cn/6665.html"/>
<rdf:li resource="https://www.ishiguang.cn/6645.html"/>
<rdf:li resource="https://www.ishiguang.cn/4646.html"/>
<rdf:li resource="https://www.ishiguang.cn/4643.html"/>
</rdf:Seq>
</items>
</channel>
<item rdf:about="https://www.ishiguang.cn/16495.html">
<title>edge 谷歌浏览器插件推荐</title>
<link>https://www.ishiguang.cn/16495.html</link>
<dc:date>2022-08-16T21:45:00+08:00</dc:date>
<description>edge 谷歌浏览器插件推荐其实EDGE也是用的谷歌的内核所以他们很多插件都基本共用,所以我就只说插件扩展名称就好了1.JavaScript and CSS Code Beautifier访问js css等文件高亮格式化用的  美观方便查看！2.Seven JSON ViewerAPI 查看json数据高亮格式化3.Stylebot前端CSS美化工具！4.Wappalyzer - Technology profiler显示网站程序名称 和 所用框架扩展！另外如果想对API数据测试可以去 Apifox 功能：API 文档、API 调试、API Mock、API 自动化测试地址：https://www.apifox.cn/另外他支持在线测试和下载工具测试！ 前端开发必备吧！  </description>
</item>
<item rdf:about="https://www.ishiguang.cn/14392.html">
<title>typecho自定义头部CSS,JS插件</title>
<link>https://www.ishiguang.cn/14392.html</link>
<dc:date>2022-02-03T13:29:00+08:00</dc:date>
<description>typecho自定义头部CSS,JS插件使用方法复制 CustomCssAndJs 文件夹到 Plugins 文件夹后台启用插件到设置面板设置相关配置即可代码高亮设置 CSS：//cdn.jsdelivr.net/highlight.js/9.9.0/styles/atom-one-dark.min.css
 JS: //cdn.jsdelivr.net/highlight.js/9.9.0/highlight.min.js自定义JS脚本(参见 Highlight.js 官网)：$(document).ready(function() {
 $(&#039;pre code&#039;).each(function(i, block) {
 hljs.highlightBlock(block);
 //$(&quot;pre&quot;).css(&quot;background&quot;,$(&quot;code&quot;).css(&quot;background&quot;));
 });
 });

CustomCssAndJs.zip</description>
</item>
<item rdf:about="https://www.ishiguang.cn/7463.html">
<title>typecho 编辑器插件 ueditor</title>
<link>https://www.ishiguang.cn/7463.html</link>
<dc:date>2021-03-27T23:32:00+08:00</dc:date>
<description>这个编辑器还行 主要是我之前的文章迁移自worspress 很多文章有很多代码然而使用markdown无法编辑，这个编辑器就可以解决了！对markdown不太熟悉。typecho1.1版本编辑器无法解析html代码typecho 1.0原生markdown解析器非常弱，无法解析表格。typecho 1.1原生markdown解析器必须使用特权模式才可以解析html代码.你可以使用该插件替换掉typecho的markdown的解析引擎： https://github.com/kokororin/typecho-plugin-Parsedown你可以使用该插件替换掉typecho的编辑器：https://github.com/chanshengzhi/ueditor-for-typecho/启用这两个插件后，无需任何设置，自动替换前台文章解析，支持解析表格和html代码。一：下载编辑器插件ueditor for typecho 2018安装方式1：在线安装a.使用ueditor.install.php在服务器上下载和安装b.访问https://github.com/chanshengzhi/ueditor-for-typecho/releasesc.下载最新版本的安装脚本(ueditor.install.php)d.上传到ueditor.install.php到/usr/plugins文件夹下e.访问yourdomain.com/usr/plugins/ueditor.install.php进行安装f.安装成功后进入typecho插件管理界面启用即可.安装方式2：下载安装a.服务器位于某些特定的区域时可能无法使用在线安装,无法使用在线安装时请下载插件压缩包上传到服务器进行安装.b.访问https://github.com/chanshengzhi/ueditor-for-typecho/releases,下载所需版本的压缩包,解压后上传其中的ueditor文件夹到/usr/plugins文件夹下, 进入typecho插件管理界面启用即可二：typecho parsedown 解析markdown插件使用parsedown替换typecho自带的markdown解析库。启用前请将目录名重命名为parsedown。a.下载插件：https://github.com/kokororin/typecho-plugin-Parsedownb.上传yourdomain/usr/pulgins目录下c.解压，并重命名为：Parsedownd.在typecho后台启动插件插件下载地址：UEditor.rar  这个是完整的插件包，上传启用就可以了！新版编辑器还是只支持1.1及以下的：新版地址 https://github.com/LinkPoly/UEditor-for-Typecho </description>
</item>
<item rdf:about="https://www.ishiguang.cn/6673.html">
<title>typecho调用热门标签</title>
<link>https://www.ishiguang.cn/6673.html</link>
<dc:date>2021-03-08T18:42:57+08:00</dc:date>
<description>typecho调用热门标签  全部标签Typecho常用代码之：输出全部标签并按文章数量排序(下面代码中的limit=20即输出的标签数量)： &lt;?php $this-&gt;widget(&#039;Widget_Metas_Tag_Cloud&#039;, array(&#039;sort&#039; =&gt; &#039;count&#039;, &#039;ignoreZeroCount&#039; =&gt; true, &#039;desc&#039; =&gt; true, &#039;limit&#039; =&gt; 20))-&gt;to($tags); ?&gt;  
 &lt;?php while($tags-&gt;next()): ?&gt;  
 &lt;li&gt;&lt;a rel=&quot;tag&quot; href=&quot;&lt;?php $tags-&gt;permalink(); ?&gt;&quot;&gt;&lt;?php $tags-&gt;name(); ?&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;?php endwhile; ?&gt;
输出全部标签列表，按照MID（创建时间）排序：    &lt;?php $this-&gt;widget(&#039;Widget_Metas_Tag_Cloud&#039;)
   -&gt;to($taglist); ?&gt;&lt;?php while($taglist-&gt;next()): ?&gt;
   &lt;li&gt;&lt;a href=&quot;&lt;?php $taglist-&gt;permalink(); ?&gt;&quot; title=&quot;&lt;?php $taglist-&gt;name(); ?&gt;&quot;&gt;&lt;?php $taglist-&gt;name(); ?&gt;&lt;/a&gt;&lt;/li&gt;
   &lt;?php endwhile; ?&gt;</description>
</item>
<item rdf:about="https://www.ishiguang.cn/6672.html">
<title>typecho调用指定文章</title>
<link>https://www.ishiguang.cn/6672.html</link>
<dc:date>2021-03-08T18:31:00+08:00</dc:date>
<description>typecho调用指定文章   在functions.php中加入如下代码 class Widget_Post_fanjubiao extends Widget_Abstract_Contents
{
public function __construct($request, $response, $params = NULL)
{
    parent::__construct($request, $response, $params);
    $this-&gt;parameter-&gt;setDefault(array(&#039;pageSize&#039; =&gt; $this-&gt;options-&gt;commentsListSize, &#039;parentId&#039; =&gt; 0, &#039;ignoreAuthor&#039; =&gt; false));
}
public function execute()
{
    $select  = $this-&gt;select()-&gt;from(&#039;table.contents&#039;)
-&gt;where(&quot;table.contents.password IS NULL OR table.contents.password = &#039;&#039;&quot;)
-&gt;where(&#039;table.contents.type = ?&#039;, &#039;post&#039;)
-&gt;limit($this-&gt;parameter-&gt;pageSize)
-&gt;order(&#039;table.contents.modified&#039;, Typecho_Db::SORT_DESC);

 if ($this-&gt;parameter-&gt;fanjubiao) {
 $fanju=explode(&quot;,&quot;,$this-&gt;parameter-&gt;fanjubiao);
 $select-&gt;where(&#039;table.contents.cid in ?&#039;, $fanju);
 }
  $this-&gt;db-&gt;fetchAll($select, array($this, &#039;push&#039;));
}
  }然后在前台调用热门文章时就可以这样写了 &lt;?php 
 $week1=&quot;728,1197&quot;;//指定文章id集合多个文章中间用英文逗号隔开
 $this-&gt;widget(&#039;Widget_Post_fanjubiao@fanjubiao&#039;, &#039;fanjubiao=&#039;.$week1)-&gt;to($fanju); ?&gt;
 &lt;?php while($fanju-&gt;next()): ?&gt;
 文章链接：&lt;?php $fanju-&gt;permalink() ?&gt;
 文章标题：&lt;?php $fanju-&gt;title(); ?&gt;
 &lt;!--等等--&gt;
  &lt;?php endwhile; ?&gt;这种写法非常原生，使用方法也同typecho调用某分类下的文章语法一致</description>
</item>
<item rdf:about="https://www.ishiguang.cn/6671.html">
<title>typecho 热门文章调用方法</title>
<link>https://www.ishiguang.cn/6671.html</link>
<dc:date>2021-03-08T15:48:00+08:00</dc:date>
<description>typecho 热门文章调用方法   （阅读最多的调用方法）//热门文章
class Widget_Contents_Hot extends Widget_Abstract_Contents
{
public function execute()
{
    $this-&gt;parameter-&gt;setDefault(array(&#039;pageSize&#039; =&gt; 10));
    $select = $this-&gt;select();
    $select-&gt;cleanAttribute(&#039;fields&#039;);
    $this-&gt;db-&gt;fetchAll(
        $select-&gt;from(&#039;table.contents&#039;)
            -&gt;where(&quot;table.contents.password IS NULL OR table.contents.password = &#039;&#039;&quot;)
            -&gt;where(&#039;table.contents.status = ?&#039;, &#039;publish&#039;)
            -&gt;where(&#039;table.contents.created &lt;= ?&#039;, time())
            -&gt;where(&#039;table.contents.type = ?&#039;, &#039;post&#039;)
            -&gt;limit($this-&gt;parameter-&gt;pageSize)
            -&gt;order(&#039;table.contents.views&#039;, Typecho_Db::SORT_DESC),
        array($this, &#039;push&#039;)
    );
}
}
调用方法  &lt;?php $this-&gt;widget(&#039;Widget_Contents_Hot@Index&#039;, &#039;pageSize=4&#039;)-&gt;to($item); ?&gt;
                        &lt;?php while ($item-&gt;next()) : ?&gt;
   &lt;?php $item-&gt;permalink(); ?&gt;//调用方法
   &lt;?php $item-&gt;title(); ?&gt;//调用方法   
  //其他方法自己参考更改就行了

  &lt;?php endwhile; ?&gt;</description>
</item>
<item rdf:about="https://www.ishiguang.cn/6665.html">
<title>Typecho 主题开发 - 文章自定义字段和主题设置字段</title>
<link>https://www.ishiguang.cn/6665.html</link>
<dc:date>2021-03-02T11:09:00+08:00</dc:date>
<description>在 Typecho 官方的主题开发文档中，很少有关于文章自定义字段和主题设置相关的开发说明。我也是查看了一些开源主题的代码才搞懂自定义字段和主题设置的开发。这里就简单写一下文章自定义字段和主题设置的定义和调用。文章自定义字段文章自定义字段定义后会显示在文章编辑界面的编辑框下方，用户可以使用定义好的选项来设置每篇文章的偏好，在输出文章的时候可以调用用户的设置，实现一些个性化功能。文章自定义字段需要在主题目录下的 functions.php 文件中的 themeFields 函数中定义。input 输入框下面定义一个 input 输入框：function themeFields($layout) {
$image = new Typecho_Widget_Helper_Form_Element_Text(&#039;image&#039;, null, null, _t(&#039;文章头图&#039;), _t(&#039;文章头图会显示在文章的顶部。&#039;));
$mmusic-&gt;input-&gt;setAttribute(&#039;class&#039;, &#039;w-100 setfb&#039;);
$layout-&gt;addItem($image);  //  注册
}
$mmusic-&gt;input-&gt;setAttribute('class', 'w-100 setfb');是设置输入框CSS长度的Typecho_Widget_Helper_Form_Element_Text 的第一个参数是字段名。第二个参数目前暂时未知。第三个参数是默认值。第四个参数是提示信息，会显示在输入框关联的 label 标签中。第五个参数是更详细的提示信息，会显示在输入框下方。在输出文章的时候可以通过 $this-&gt;fields-&gt;image() 输出自定义字段的内容，其中的 image 就是字段名称。如果要判断字段是否有内容可以直接用 if 来判断 $this-&gt;fields-&gt;image ，如果有内容就会返回 true ，否则就返回 false 。自定义字段使用调用字段$field = $this-&gt;fields-&gt;fieldName;输出字段$this-&gt;fields-&gt;fieldName();判断字段if(isset($this-&gt;fields-&gt;fieldName)){
echo &#039;字段存在，值为：&#039;.$this-&gt;fields-&gt;fieldName;
}else{
echo &#039;字段不存在&#039;;
}
--------官方文档地址 http://docs.typecho.org/help/custom-fieldsselect 下拉选择下面定义一个 select 下拉选择：function themeFields($layout) {
$articleCopyright = new Typecho_Widget_Helper_Form_Element_Select(&#039;articleCopyright&#039;, array(
    &#039;show&#039; =&gt; &#039;显示&#039;,
    &#039;hide&#039; =&gt; &#039;不显示&#039;
), &#039;show&#039;, _t(&#039;显示原创声明&#039;), _t(&#039;开启后会在本篇文章底部显示版权声明。&#039;));
$layout-&gt;addItem($articleCopyright);  //  注册  
}
注意！只要是文章的自定义字段都需要写在 themeFields 函数内，多个字段也只需要写在一个 themeFields 函数内。Typecho_Widget_Helper_Form_Element_Select 的第一个参数是字段名称。第二个参数是下拉选择的内容，需要传入一个数组。第三个参数是默认值，默认值的类型为字符串，需要传入一个数组的键名。第四个参数是 label 标签关联的提示信息。第五个参数是更详细的提示信息。在输出文章的时候可以用 if 来判断 $this-&gt;fields-&gt;articleCopyright 的值，其中 articleCopyright 就是字段名。下面判断 $this-&gt;fields-&gt;articleCopyright 的值：if ($this-&gt;fields-&gt;articleCopyright == &#039;show&#039;) {
//  如果是选中状态就返回 true
}
下面是 input 输入框和 select 下拉选择 在文章编辑页的效果：主题设置字段主题设置字段定义后会显示在主题的外观设置页，用户可以使用定义好的选项来设置主题的外观和功能。主题设置的字段需要在主题目录下的 funcions.php 中的 themeConfig 函数中定义。input 输入框下面定义一个 input 输入框：function themeConfig($cfg) {
$logoUrl = new Typecho_Widget_Helper_Form_Element_Text(&#039;logoUrl&#039;, null, null, _t(&#039;站点 Logo 地址&#039;), _t(&#039;Logo 会显示在标签页的标题前面。&#039;));
$cfg-&gt;addInput($logoUrl);  //  注册
}
主题设置字段的 Typecho_Widget_Helper_Form_Element_Text 参数和文章自定义字段的 Typecho_Widget_Helper_Form_Element_Text 的参数是一样的。主题设置字段可以在任何一个页面使用 $this-&gt;options-&gt;logoUrl() 输出，其中的 logoUrl 就是字段名。如果要判断字段是否有内容也可以用 if 来判断 $this-&gt;options-&gt;logoUrl ，如果有内容就会返回 true ，否则返回 false 。textarea 输入框下面定义一个 textarea 输入框：function themeConfig($cfg) {
$cssCode = new Typecho_Widget_Helper_Form_Element_Textarea(&#039;cssCode&#039;, null, null, _t(&#039;自定义 CSS&#039;), _t(&#039;通过自定义 CSS 您可以很方便的设置页面样式，自定义 CSS 不会影响网站源代码。&#039;));
$cfg-&gt;addInput($cssCode);  //  注册
}
注意！所有的主题设置字段都需要写在 themeConfig 函数中，多个字段也只需要写在一个 themeConfig 函数中。Typecho_Widget_Helper_Form_Element_Textarea 的参数和 input 输入框的参数是一样的。textarea 的输出和查询和上面的 input 是一样的。checkbox 复选框下面定义一组 checkbox 复选框：function themeConfig($cfg) {
$sidebarBlock = new Typecho_Widget_Helper_Form_Element_Checkbox(&#039;sidebarBlock&#039;,
    array(
        &#039;ShowRecentPosts&#039; =&gt; _t(&#039;显示最新文章&#039;),
        &#039;ShowRecentComments&#039; =&gt; _t(&#039;显示最近回复&#039;),
        &#039;ShowCategory&#039; =&gt; _t(&#039;显示分类&#039;),
        &#039;ShowTag&#039; =&gt; _t(&#039;显示标签云&#039;),
        &#039;ShowArchive&#039; =&gt; _t(&#039;显示归档&#039;),
        &#039;ShowOther&#039; =&gt; _t(&#039;显示其它杂项&#039;),
        &#039;HideLoginLink&#039; =&gt; _t(&#039;隐藏登录入口&#039;)
    ),
    array(
        &#039;ShowRecentPosts&#039;,
        &#039;ShowRecentComments&#039;,
        &#039;ShowCategory&#039;
    ), _t(&#039;侧边栏显示&#039;)
);
$cfg-&gt;addInput($sidebarBlock-&gt;multiMode());  //  注册
}
Typecho_Widget_Helper_Form_Element_Checkbox 的第一个参数是字段名。第二个参数是复选框的内容，需要传入一个数组。第三个参数是复选框的选中状态，需要传入一个数组，数组的内容就是第二个参数中数组的键名。第四个参数是复选框组的标题，会显示在复选框的上方。注意！在注册的时候需要传入 Typecho_Widget_Helper_Form_Element_Checkbox 的 multiMode() 方法。如果需要判断复选框的选中状态可以使用 in_array 函数来查找 $this-&gt;options-&gt;sidebarBlock 的选项。下面判断 显示最新回复 是否选中 ：if (is_array($this-&gt;options-&gt;sidebarBlock) &amp;&amp; in_array(&#039;ShowRecentComments&#039;, $this-&gt;options-&gt;sidebarBlock)) {
//  返回 true
}
如果一组复选框中没有一个被选中，$this-&gt;options-&gt;sidebarBlock 的值就是 null 。只使用 in_array() 查找的话可能会报错，需要先用 is_array() 判断是否是数组。复选框的效果如下：radio 单选框下面定义一组 radio 单选框：function themeConfig($cfg) {
$navbarColor = new Typecho_Widget_Helper_Form_Element_Radio(&#039;navbarColor&#039;, array(
    &#039;white&#039; =&gt; &#039;白色&#039;,
    &#039;black&#039; =&gt; &#039;黑色&#039;
), &#039;black&#039;, _t(&#039;导航栏颜色&#039;));
$cfg-&gt;addInput($navbarColor);
}

Typecho_Widget_Helper_Form_Element_Radio 的第一个参数是字段名。第二个参数是单选框的内容，需要传入一个数组。第三个参数是单选框的选中状态，需要传入第二个参数数组的键名。第四个参数是单选框组的标题，会显示在单选框的上方。如果要判断单选框的选中状态可以用 if 来判断 $this-&gt;options-&gt;navbarColor 的值，其中的 navbarColor 是字段名。下面判断单选框的选中状态：if ($this-&gt;options-&gt;navbarColor == &#039;black&#039;) {
//  如果黑色选中就返回 true
}
下面是单选框的效果：这就是Typecho 主题开发 - 文章自定义字段和主题设置字段</description>
</item>
<item rdf:about="https://www.ishiguang.cn/6645.html">
<title>typecho插入bilibili视频播放器 B站插件</title>
<link>https://www.ishiguang.cn/6645.html</link>
<dc:date>2021-02-22T15:48:00+08:00</dc:date>
<description>typecho插入bilibili视频 B站插件插件功能：前台自动加入CSS布局后台启用插件就可以了，不需要任何设置在编辑器加入按钮，直接输入BVID 就可以了禁用了跳转B站测试地址 ：https://www.ishiguang.cn/6646.html效果图：更新:1.06修正某些分页，css加载地址错误的问题修改禁止自动播放！避免同个页面多个视频同时播放1.07 更新了CSS文件路径BUG新版本直接下载就行了(不需要再下载上面的替换文件了)2022.3.8 更新1.08 更新视频自动调用高清视频，一般为720P，如果视频没有720P则调用360P2022.5.9 更新1.09 默认关闭弹幕！2022.12.1 更改播放器显示样式 :&(蛆音娘_滑稽)   1.1.0 版本：biliplayer_20221201112452.zip1.0.9 旧版 https://github.com/qq8244409/typecho-plugins-biliplayerPS: 折腾插件不易，我只是个小学毕业的，还请各位大佬键盘下留情！我发布的任何东西都不曾收费，只为方便更多的人！有问题联系qq: 8244409</description>
</item>
<item rdf:about="https://www.ishiguang.cn/4646.html">
<title>Typecho评论增强插件：TeComment</title>
<link>https://www.ishiguang.cn/4646.html</link>
<dc:date>2021-02-20T09:23:03+08:00</dc:date>
<description>TeComment（2017.09.07更新）Typecho 评论增强插件，可为Typecho评论增加评论工具栏、实现评论列表异步加载以及Ajax提交评论功能1、安装插件下载插件后，确认插件文件夹名称为TeComment,上传插件文件夹TeComment至网站目录usr/plugins/进入后台，在导航 控制台 &gt; 插件 页面，选择启用TeComment插件2、使用插件2.1、评论工具栏安装好插件后，要想显示评论工具栏，需要修改当前所使用主题的comments.php文件:在textarea标签后插入如下代码(可自行确定放置位置)&lt;?php TeComment_Plugin::showTool();?&gt;
2.2、使用评论列表异步加载或Ajax提交评论功能前提在开启评论列表异步加载或Ajax提交评论功能前，需要修改当前所使用主题的functions.php文件:若functions.php文件中添加或替换threadedComments函数为/**
 * 重写评论显示函数
 */
function threadedComments($comments, $options){
$html = TeComment_Plugin::parseCommentHtml($comments, $options);

$children = &#039;&#039;;
if ($comments-&gt;children) {
    ob_start();
    $comments-&gt;threadedComments();
    $children = ob_get_contents();
    ob_end_clean();
}
$html = str_replace(&#039;&gt;{children}&lt;&#039;,&#039;&gt;&#039;.$children.&#039;&lt;&#039;,$html);
echo $html;
}

2.3、评论列表异步加载功能要开启‘评论异步加载’功能，在插件设置页面启用‘评论异步加载’后，还需要修改当前所使用主题的comments.php文件:代码&lt;?php $this-&gt;comments()-&gt;to($comments); ?&gt;
&lt;?php if ($comments-&gt;have()): ?&gt;
&lt;?php $comments-&gt;listComments(); ?&gt;
&lt;?php $comments-&gt;pageNav(&#039;&amp;laquo; 前一页&#039;, &#039;后一页 &amp;raquo;&#039;); ?&gt;
&lt;?php endif; ?&gt;
修改为&lt;?php if($this-&gt;options-&gt;plugin(&#039;TeComment&#039;)-&gt;commentAjaxLoad): ?&gt;
&lt;div id=&quot;comment-ajax-list&quot; data-cid=&quot;&lt;?php $this-&gt;cid();?&gt;&quot; data-num=&quot;&lt;?php $this-&gt;commentsNum();?&gt;&quot; data-comment-page=&quot;&lt;?php echo $this-&gt;request-&gt;commentPage;?&gt;&quot;&gt;&lt;/div&gt;
&lt;?php else: ?&gt;
&lt;?php $this-&gt;comments()-&gt;to($comments); ?&gt;
&lt;?php if ($comments-&gt;have()): ?&gt;
&lt;?php $comments-&gt;listComments(); ?&gt;
&lt;?php $comments-&gt;pageNav(&#039;&amp;laquo; 前一页&#039;, &#039;后一页 &amp;raquo;&#039;); ?&gt;
&lt;?php endif; ?&gt;
&lt;?php endif; ?&gt;
代码&lt;?php $comments-&gt;cancelReply(); ?&gt;
修改为&lt;?php echo &#039;&lt;a id=&quot;cancel-comment-reply-link&quot; href=&quot;&#039; . $this-&gt;permalink . &#039;#&#039; . $this-&gt;respondId . &#039;&quot; rel=&quot;nofollow&quot;&#039; . ($this-&gt;request-&gt;filter(&#039;int&#039;)-&gt;replyTo ? &#039;&#039; : &#039; style=&quot;display:none&quot;&#039;) . &#039; onclick=&quot;return TypechoComment.cancelReply();&quot;&gt;&#039;._t(&#039;取消回复&#039;).&#039;&lt;/a&gt;&#039;; ?&gt;
2.4、Ajax提交评论要开启‘Ajax提交评论’功能，只需要在在插件设置页面启用‘Ajax提交评论’即可此功能兼容系统默认的反垃圾保护功能2.5、评论模板为了实现评论列表异步加载和Ajax提交评论功能，插件引入了评论模板，默认的评论模板为：&lt;li id=&quot;{theId}&quot; class=&quot;widget {commentClass}&quot;&gt;
&lt;div class=&quot;comment-meta&quot;&gt;
    &lt;div class=&quot;comment-meta-avatar&quot;&gt;{authorAvatar}&lt;/div&gt;
    &lt;div class=&quot;comment-meta-author&quot;&gt;
        &lt;strong&gt;{beforeAuthor}&lt;a href=&quot;{authorUrl}&quot; rel=&quot;external nofollow&quot; target=&quot;_blank&quot;&gt;{authorName}&lt;/a&gt;{afterAuthor}{commentStatus}&lt;/strong&gt;
    &lt;/div&gt;
    &lt;div class=&quot;comment-meta-time&quot;&gt;{beforeDate}{created}{afterDate}&lt;/div&gt;
        &lt;div class=&quot;comment-meta-reply&quot;&gt;{replyLink}&lt;/div&gt;
    &lt;/div&gt;
&lt;div class=&quot;comment-content&quot;&gt;{content}&lt;/div&gt;
&lt;div class=&quot;comment-children&quot;&gt;{children}&lt;/div&gt;
&lt;/li&gt;
可根据模板的需要自行设计评论模板，可用参数包括:{theId} 评论锚点ID {commentClass} 评论列表样式 {authorAvatar} 评论用户头像{authorName} 评论用户名称 {authorUrl} 评论用户主页 {authorUrl} 评论用户邮箱 {created}评论发布时间，时间格式为后台设置的格式 {replyLink}回复评论的链接 {content} 评论内容 {children} 子评论旧插件使用方法：&lt;?php TeComment_Plugin::showTool();?&gt;
启用插件后，在comments.php文件的合适位置加上以上代码即可下载地址：TeComment本文为转载，食用方法自己去参考！！！</description>
</item>
<item rdf:about="https://www.ishiguang.cn/4643.html">
<title>typecho实现Ajax评论功能</title>
<link>https://www.ishiguang.cn/4643.html</link>
<dc:date>2021-02-20T08:55:00+08:00</dc:date>
<description>为了不使用插件实现Ajax评论功能需要实现：监听评论表单，改用ajax方式提交创建新的评论表单提交地址（用Typecho 主题提供的系统方法themeInit实现）当访问文章加载主题时，themeInit方法首先被加载，可在此方法中判断是否为添加评论的操作，即新的评论表单地址为文章的链接(permalink).具体判断方法如下// 主题初始化
function themeInit($archive){
// 判断是否是添加评论的操作
// 为文章或页面、post操作，且包含参数`themeAction=comment`(自定义)
if($archive-&gt;is(&#039;single&#039;) &amp;&amp; $archive-&gt;request-&gt;isPost() &amp;&amp; $archive-&gt;request-&gt;is(&#039;themeAction=comment&#039;)){
    // 为添加评论的操作时
    ajaxComment($archive);
}
}
要实现ajax评论，则无法使用系统默认的feedback,这里我们将复制feedback功能并改造为我们需要的方法/**
* ajaxComment
* 实现Ajax评论的方法(实现feedback中的comment功能)
* @param Widget_Archive $archive
* @return void
*/
function ajaxComment($archive){
$options = Helper::options();
$user = Typecho_Widget::widget(&#039;Widget_User&#039;);
$db = Typecho_Db::get();
// Security 验证不通过时会直接跳转，所以需要自己进行判断
// 需要开启反垃圾保护，此时将不验证来源
if($archive-&gt;request-&gt;get(&#039;_&#039;) != Helper::security()-&gt;getToken($archive-&gt;request-&gt;getReferer())){
    $archive-&gt;response-&gt;throwJson(array(&#039;status&#039;=&gt;0,&#039;msg&#039;=&gt;_t(&#039;非法请求&#039;)));
}
/** 评论关闭 */
if(!$archive-&gt;allow(&#039;comment&#039;)){
    $archive-&gt;response-&gt;throwJson(array(&#039;status&#039;=&gt;0,&#039;msg&#039;=&gt;_t(&#039;评论已关闭&#039;)));
}
/** 检查ip评论间隔 */
if (!$user-&gt;pass(&#039;editor&#039;, true) &amp;&amp; $archive-&gt;authorId != $user-&gt;uid &amp;&amp;
$options-&gt;commentsPostIntervalEnable){
    $latestComment = $db-&gt;fetchRow($db-&gt;select(&#039;created&#039;)-&gt;from(&#039;table.comments&#039;)
                -&gt;where(&#039;cid = ?&#039;, $archive-&gt;cid)
                -&gt;where(&#039;ip = ?&#039;, $archive-&gt;request-&gt;getIp())
                -&gt;order(&#039;created&#039;, Typecho_Db::SORT_DESC)
                -&gt;limit(1));

    if ($latestComment &amp;&amp; ($options-&gt;gmtTime - $latestComment[&#039;created&#039;] &gt; 0 &amp;&amp;
    $options-&gt;gmtTime - $latestComment[&#039;created&#039;] &lt; $options-&gt;commentsPostInterval)) {
        $archive-&gt;response-&gt;throwJson(array(&#039;status&#039;=&gt;0,&#039;msg&#039;=&gt;_t(&#039;对不起, 您的发言过于频繁, 请稍侯再次发布&#039;)));
    }        
}

$comment = array(
    &#039;cid&#039;       =&gt;  $archive-&gt;cid,
    &#039;created&#039;   =&gt;  $options-&gt;gmtTime,
    &#039;agent&#039;     =&gt;  $archive-&gt;request-&gt;getAgent(),
    &#039;ip&#039;        =&gt;  $archive-&gt;request-&gt;getIp(),
    &#039;ownerId&#039;   =&gt;  $archive-&gt;author-&gt;uid,
    &#039;type&#039;      =&gt;  &#039;comment&#039;,
    &#039;status&#039;    =&gt;  !$archive-&gt;allow(&#039;edit&#039;) &amp;&amp; $options-&gt;commentsRequireModeration ? &#039;waiting&#039; : &#039;approved&#039;
);

/** 判断父节点 */
if ($parentId = $archive-&gt;request-&gt;filter(&#039;int&#039;)-&gt;get(&#039;parent&#039;)) {
    if ($options-&gt;commentsThreaded &amp;&amp; ($parent = $db-&gt;fetchRow($db-&gt;select(&#039;coid&#039;, &#039;cid&#039;)-&gt;from(&#039;table.comments&#039;)
    -&gt;where(&#039;coid = ?&#039;, $parentId))) &amp;&amp; $archive-&gt;cid == $parent[&#039;cid&#039;]) {
        $comment[&#039;parent&#039;] = $parentId;
    } else {
        $archive-&gt;response-&gt;throwJson(array(&#039;status&#039;=&gt;0,&#039;msg&#039;=&gt;_t(&#039;父级评论不存在&#039;)));
    }
}
$feedback = Typecho_Widget::widget(&#039;Widget_Feedback&#039;);
//检验格式
$validator = new Typecho_Validate();
$validator-&gt;addRule(&#039;author&#039;, &#039;required&#039;, _t(&#039;必须填写用户名&#039;));
$validator-&gt;addRule(&#039;author&#039;, &#039;xssCheck&#039;, _t(&#039;请不要在用户名中使用特殊字符&#039;));
$validator-&gt;addRule(&#039;author&#039;, array($feedback, &#039;requireUserLogin&#039;), _t(&#039;您所使用的用户名已经被注册,请登录后再次提交&#039;));
$validator-&gt;addRule(&#039;author&#039;, &#039;maxLength&#039;, _t(&#039;用户名最多包含200个字符&#039;), 200);

if ($options-&gt;commentsRequireMail &amp;&amp; !$user-&gt;hasLogin()) {
    $validator-&gt;addRule(&#039;mail&#039;, &#039;required&#039;, _t(&#039;必须填写电子邮箱地址&#039;));
}

$validator-&gt;addRule(&#039;mail&#039;, &#039;email&#039;, _t(&#039;邮箱地址不合法&#039;));
$validator-&gt;addRule(&#039;mail&#039;, &#039;maxLength&#039;, _t(&#039;电子邮箱最多包含200个字符&#039;), 200);

if ($options-&gt;commentsRequireUrl &amp;&amp; !$user-&gt;hasLogin()) {
    $validator-&gt;addRule(&#039;url&#039;, &#039;required&#039;, _t(&#039;必须填写个人主页&#039;));
}
$validator-&gt;addRule(&#039;url&#039;, &#039;url&#039;, _t(&#039;个人主页地址格式错误&#039;));
$validator-&gt;addRule(&#039;url&#039;, &#039;maxLength&#039;, _t(&#039;个人主页地址最多包含200个字符&#039;), 200);

$validator-&gt;addRule(&#039;text&#039;, &#039;required&#039;, _t(&#039;必须填写评论内容&#039;));

$comment[&#039;text&#039;] = $archive-&gt;request-&gt;text;

/** 对一般匿名访问者,将用户数据保存一个月 */
if (!$user-&gt;hasLogin()) {
    /** Anti-XSS */
    $comment[&#039;author&#039;] = $archive-&gt;request-&gt;filter(&#039;trim&#039;)-&gt;author;
    $comment[&#039;mail&#039;] = $archive-&gt;request-&gt;filter(&#039;trim&#039;)-&gt;mail;
    $comment[&#039;url&#039;] = $archive-&gt;request-&gt;filter(&#039;trim&#039;)-&gt;url;

    /** 修正用户提交的url */
    if (!empty($comment[&#039;url&#039;])) {
        $urlParams = parse_url($comment[&#039;url&#039;]);
        if (!isset($urlParams[&#039;scheme&#039;])) {
            $comment[&#039;url&#039;] = &#039;http://&#039; . $comment[&#039;url&#039;];
        }
    }

    $expire = $options-&gt;gmtTime + $options-&gt;timezone + 30*24*3600;
    Typecho_Cookie::set(&#039;__typecho_remember_author&#039;, $comment[&#039;author&#039;], $expire);
    Typecho_Cookie::set(&#039;__typecho_remember_mail&#039;, $comment[&#039;mail&#039;], $expire);
    Typecho_Cookie::set(&#039;__typecho_remember_url&#039;, $comment[&#039;url&#039;], $expire);
} else {
    $comment[&#039;author&#039;] = $user-&gt;screenName;
    $comment[&#039;mail&#039;] = $user-&gt;mail;
    $comment[&#039;url&#039;] = $user-&gt;url;

    /** 记录登录用户的id */
    $comment[&#039;authorId&#039;] = $user-&gt;uid;
}

/** 评论者之前须有评论通过了审核 */
if (!$options-&gt;commentsRequireModeration &amp;&amp; $options-&gt;commentsWhitelist) {
    if ($feedback-&gt;size($feedback-&gt;select()-&gt;where(&#039;author = ? AND mail = ? AND status = ?&#039;, $comment[&#039;author&#039;], $comment[&#039;mail&#039;], &#039;approved&#039;))) {
        $comment[&#039;status&#039;] = &#039;approved&#039;;
    } else {
        $comment[&#039;status&#039;] = &#039;waiting&#039;;
    }
}

if ($error = $validator-&gt;run($comment)) {
    $archive-&gt;response-&gt;throwJson(array(&#039;status&#039;=&gt;0,&#039;msg&#039;=&gt; implode(&#039;;&#039;,$error)));
}

/** 添加评论 */
$commentId = $feedback-&gt;insert($comment);
if(!$commentId){
    $archive-&gt;response-&gt;throwJson(array(&#039;status&#039;=&gt;0,&#039;msg&#039;=&gt;_t(&#039;评论失败&#039;)));
}
Typecho_Cookie::delete(&#039;__typecho_remember_text&#039;);
$db-&gt;fetchRow($feedback-&gt;select()-&gt;where(&#039;coid = ?&#039;, $commentId)
-&gt;limit(1), array($feedback, &#039;push&#039;));
// 返回评论数据
$data = array(
    &#039;cid&#039; =&gt; $feedback-&gt;cid,
    &#039;coid&#039; =&gt; $feedback-&gt;coid,
    &#039;parent&#039; =&gt; $feedback-&gt;parent,
    &#039;mail&#039; =&gt; $feedback-&gt;mail,
    &#039;url&#039; =&gt; $feedback-&gt;url,
    &#039;ip&#039; =&gt; $feedback-&gt;ip,
    &#039;agent&#039; =&gt; $feedback-&gt;agent,
    &#039;author&#039; =&gt; $feedback-&gt;author,
    &#039;authorId&#039; =&gt; $feedback-&gt;authorId,
    &#039;permalink&#039; =&gt; $feedback-&gt;permalink,
    &#039;created&#039; =&gt; $feedback-&gt;created,
    &#039;datetime&#039; =&gt; $feedback-&gt;date-&gt;format(&#039;Y-m-d H:i:s&#039;),
    &#039;status&#039; =&gt; $feedback-&gt;status,
);
// 评论内容
ob_start();
$feedback-&gt;content();
$data[&#039;content&#039;] = ob_get_clean();

$data[&#039;avatar&#039;] = Typecho_Common::gravatarUrl($data[&#039;mail&#039;], 48, Helper::options()-&gt;commentsAvatarRating, NULL, $archive-&gt;request-&gt;isSecure());
$archive-&gt;response-&gt;throwJson(array(&#039;status&#039;=&gt;1,&#039;comment&#039;=&gt;$data));
}
当已经在functions.php文件中添加完上述方法时，就已经可以接收ajax评论了。此时我们需要修改评论表单添加的方式及提交的地址。在footer.php文件中添加方法// 依赖jquery,请自行加载
$(function(){
// 监听评论表单提交
$(&#039;#comment-form&#039;).submit(function(){
    var form = $(this), params = form.serialize();
    // 添加functions.php中定义的判断参数
    params += &#039;&amp;themeAction=comment&#039;;
    
    // 解析新评论并附加到评论列表
    var appendComment = function(comment){
        // 评论列表
        var el = $(&#039;#comments &gt; .comment-list&#039;);
        if(0 != comment.parent){
            // 子评论则重新定位评论列表
            var el = $(&#039;#comment-&#039;+comment.parent);
            // 父评论不存在子评论时
            if(el.find(&#039;.comment-children&#039;).length &lt; 1){
                $(&#039;&lt;div class=&quot;comment-children&quot;&gt;&lt;ol class=&quot;comment-list&quot;&gt;&lt;/ol&gt;&lt;/div&gt;&#039;).appendTo(el);
            }else if(el.find(&#039;.comment-children &gt; .comment-list&#039;).length &lt;1){
                $(&#039;&lt;ol class=&quot;comment-list&quot;&gt;&lt;/ol&gt;&#039;).appendTo(el.find(&#039;.comment-children&#039;));
            }
            el = $(&#039;#comment-&#039;+comment.parent).find(&#039;.comment-children&#039;).find(&#039;.comment-list&#039;);
        }
        if(0 == el.length){
            $(&#039;&lt;ol class=&quot;comment-list&quot;&gt;&lt;/ol&gt;&#039;).appendTo($(&#039;#comments&#039;));
            el = $(&#039;#comments &gt; .comment-list&#039;);
        }
                    // 评论html模板，根据具体主题定制
        var html = &#039;&lt;li id=&quot;comment-{coid}&quot; class=&quot;comment-body comment-ajax&quot;&gt;&lt;div class=&quot;comment-author&quot;&gt;&lt;span&gt;&lt;img class=&quot;avatar&quot; src=&quot;{avatar}&quot; alt=&quot;{author}&quot; width=&quot;32&quot; height=&quot;32&quot;&gt;&lt;/span&gt;&lt;cite class=&quot;fn&quot;&gt;{author}&lt;/cite&gt;&lt;/div&gt;&lt;div class=&quot;comment-meta&quot;&gt;&lt;a href=&quot;{permalink}&quot;&gt;&lt;time&gt;{datetime}&lt;/time&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;comment-content&quot;&gt;{content}&lt;/div&gt;&lt;/li&gt;&#039;;
        $.each(comment,function(k,v){
            regExp = new RegExp(&#039;{&#039;+k+&#039;}&#039;, &#039;g&#039;);
            html = html.replace(regExp, v);
        });
        $(html).appendTo(el);
    }
    // ajax提交评论
    $.ajax({
        url: &#039;&lt;?php $this-&gt;permalink();?&gt;&#039;,
        type: &#039;POST&#039;,
        data: params,
        dataType: &#039;json&#039;,
        beforeSend: function() { form.find(&#039;.submit&#039;).addClass(&#039;loading&#039;).html(&#039;&lt;i class=&quot;icon icon-loading icon-pulse&quot;&gt;&lt;/i&gt; 提交中...&#039;).attr(&#039;disabled&#039;,&#039;disabled&#039;);},
        complete: function() { form.find(&#039;.submit&#039;).removeClass(&#039;loading&#039;).html(&#039;提交评论&#039;).removeAttr(&#039;disabled&#039;);},
        success: function(result){
            if(1 == result.status){
                // 新评论附加到评论列表
                appendComment(result.comment);
                form.find(&#039;textarea&#039;).val(&#039;&#039;);
            }else{
                // 提醒错误消息
                alert(undefined === result.msg ? &#039;&lt;?php _e(&#039;评论出错!&#039;);?&gt;&#039; : result.msg);
            }
        },
        error:function(xhr, ajaxOptions, thrownError){
            alert(&#039;评论失败，请重试&#039;);
        }
    });
    return false;
});
});
ajax评论需要自定义评论模板，获取使用其他方式拼接评论html。评论form表单的提交按钮需要添加class="submit"或修改代码为其他自定义的class注：需开启评论的反垃圾保护（本文转自绛木子） 具体使用方式还未去实现，只是为了存资料，方便以后学习</description>
</item>
</rdf:RDF>