首页
微语
统计
友链
留言
memos
圈子
图床
推荐
相册
网站监控
VPS监控
Search
1
实现typecho微信时光机功能的图文教程
45,235 阅读
2
为Typecho添加webp解析
43,191 阅读
3
emlog数据成功迁移到typecho
26,741 阅读
4
Memos备忘录,记录瞬间想法
25,724 阅读
5
Jasmine - 简约、美观的博客主题
24,395 阅读
手机达人
免费资源
电脑网络
娱乐休闲
网站建设
威言威语
Typecho
Emlog
WordPress
服务器
主题
插件
排行榜    
登录
/
注册
Search
标签搜索
wordpress
发布
插件
免费
教程
typecho
EMlog
PHP
代码
CSS
华为
图片
代码修改
安装
评论
手机
诺基亚
微信
文章
智能
Chen'mo
累计撰写
1,266
篇文章
累计收到
374
条评论
首页
栏目
手机达人
免费资源
电脑网络
娱乐休闲
网站建设
威言威语
Typecho
Emlog
WordPress
服务器
主题
插件
页面
微语
统计
友链
留言
memos
推荐
相册
网站监控
VPS监控
搜索到
2
篇与
的结果
2021-05-12
typecho 真的很简单的自定义评论列表
以前写过一个关于自定义评论的文章,时至如今来看,还是有很多不足的,昨晚再新写主题的时候,也重新写了一次自定义评论,嗯,有了新的理解,因为其实真的很简单,仔细阅读本篇文章,相信你会有收获的。自定义评论模板到底要怎么做很简单,可以理解为两步:编写自定义评论的模板通过php渲染出自定义模板评论而为什么大多数人不会,其实就是因为官方的文档真的是,如果懂php的人,可能看了一两遍后明白了怎么回事,但是如果是小白入门,纯前端的童鞋,可能看的一脸蒙蔽。就算是原封不动的copy官方的示例代码也还是会报错,心累...因为,你不知道他要做什么,我编写了自定义模板函数threadedComments;然后呢???然而官方啥也没说。(当然,我不能保证这篇教程的绝对正确,但是从我的理解和使用上,还是可以正常运作的)自定义评论模板的编写我们可以创建一个用于存放模板的php文件,比如list-template.php模板本身其实就是一个php的函数,不管那些if啥的代码,其实他就是一个空架子<?php function threadedComments($comments, $options) { ?> ...自定义评论模板具体的html内容 <?php } ?>那么官方文档中开头那部分$commentClass是做什么的,其实是一个用于设置class的php变量,这个变量需要判断这条评论是文章作者的,还是其他人评论的,然后$commentLevelClass则是用来判断,这条评论是主评论还是子评论。事实上官方在 具体的html内容部分又if判断了一次,这条评论是主评论还是子评论,所以,$commentLevelClass这段我们可以删掉,并不会影响后面的内容,当然,待会我会仔细讲讲这段代码怎么用,因为官方写错啦!$commentClass那么,$commentClass我们是需要的,如果你的html样式里面不需要判断这条评论是作者的还是其他人的,那么这块代码,包括$commentClass变量,我们可以去除。$commentClass = ''; if ($comments->authorId) { if ($comments->authorId == $comments->ownerId) { $commentClass .= ' comment-by-author'; //如果是文章作者的评论添加 .comment-by-author 样式 } else { $commentClass .= ' comment-by-user'; //如果是评论作者的添加 .comment-by-user 样式 } }$commentLevelClass$commentLevelClass = $comments->_levels > 0 ? ' comment-child' : ' comment-parent'; //评论层数大于0为子级,否则是父级再官方的文档中,可以看到开头这么一段代码,咋一看好像没啥问题,但是他在后面的li元素那,也有一个判断:<li id="li-<?php $comments->theId(); ?>" class="comment-body<?php if ($comments->levels > 0) { echo ' comment-child'; $comments->levelsAlt(' comment-level-odd', ' comment-level-even'); } else { echo ' comment-parent'; } $comments->alt(' comment-odd', ' comment-even'); echo $commentClass; ?>">仔细看,是不是似曾相识:levels、comment-child、comment-parent、> 0、这不就是一样的意思吗???为什么要写两遍,所以,我们可以二选一,可以保留li的if判断,删除上面的$commentLevelClass;也可以保留$commentLevelClass,删除li里面的if判断。但是,如果你要保留$commentLevelClass的话,那么需要把_levels改为levels代码才能正常运行。而li这边则需要改成:<li id="li-<?php $comments->theId(); ?>" class="comment-body<?php echo $commentLevelClass;?> <?php if ($comments->levels > 0) { $comments->levelsAlt(' comment-level-odd', ' comment-level-even'); }; $comments->alt(' comment-odd', ' comment-even');?>">是不是感觉有点麻烦,其实还可以拆分:<?php echo $commentLevelClass;?>这句就不多说了,又不是瞎子,是吧!后面这一大段:<?php if ($comments->levels > 0) { $comments->levelsAlt(' comment-level-odd', ' comment-level-even'); }; $comments->alt(' comment-odd', ' comment-even'); ?>仔细看看,其实就是一个判断这条评论是奇数偶数,然后添加对应class的判断而已,何必这么麻烦,是不是,css的选择器::nth-child(odd)和:nth-child(even)不香吗???所以,我个人是建议,这句话干掉他,还我一个干净的html代码。干掉后代码如下:<li id="li-<?php $comments->theId(); ?>" class="comment-body <?php echo $commentLevelClass;?>">就这样,我们完事了。是不是一下就明白了!现在对于class变量我们知道了,现在来看具体的html评论代码html评论代码先看下预设的php变量方法作用<?php $comments->gravatar(); ?>评论者头像(avatar源)<?php $comments->author(); ?>评论者名字<?php $comments->permalink(); ?>评论者当前评论的页面和定位,点击可以跳转到该评论位置<?php $comments->date('Y-m-d H:i'); ?>评论的时间,可以到data查看对应的格式<?php $comments->reply('Reply'); ?>回复按钮<?php $comments->content(); ?>评论的内容id="<?php $comments->theId(); ?>"评论的唯一值id评论代码只需要在html中套用就行了<li id="li-<?php $comments->theId(); ?>" class="comment-body <?php echo $commentLevelClass;?>"> <div class="media" id="<?php $comments->theId(); ?>"> <?php $comments->gravatar(); ?> <div class="media-body"> <?php $comments->author(); ?> <?php $comments->content(); ?> </div> <div class="media-footer"> <time><?php $comments->date('Y-m-d H:i'); ?></time> <?php $comments->reply('Reply'); ?> </div> </div> </li>一个经典的bootstrap的medai评论卡片就完成了,当然这里还只是单条的评论,如有子评论,我们还需要加上一个判断<li id="li-<?php $comments->theId(); ?>" class="comment-body <?php echo $commentLevelClass;?>"> <div class="media" id="<?php $comments->theId(); ?>"> <?php $comments->gravatar(); ?> <div class="media-body"> <?php $comments->author(); ?> <?php $comments->content(); ?> </div> <div class="media-footer"> <time><?php $comments->date('Y-m-d H:i'); ?></time> <?php $comments->reply('Reply'); ?> </div> </div> <?php if ($comments->children) { ?> <div class="comment-children"> <?php $comments->threadedComments($options); ?> </div> <?php } ?> </li>这样一个完整的评论就产生了,由于子评论嵌套在父评论里面,li的效果会产生padding-left的左间距,所以,回复评论太多,宽度就会不太够,所以,官方再博客后台评论设置那,可以设置最多回复多少条,一般是5条就需要新开回复了。那么,如果想避免这个情况,就可以再这里调整下嵌套结构,比如,像我的做法是我会将子评论和li做同级处理,当然这个做法不是很符合Ol>Li的结构,但是也没啥好办法吧,2333,看大家的智慧了完整代码现在就是合体了<?php function threadedComments($comments, $options) { $commentClass = ''; if ($comments->authorId) { if ($comments->authorId == $comments->ownerId) { $commentClass .= ' comment-by-author'; } else { $commentClass .= ' comment-by-user'; } } $commentLevelClass = $comments->levels > 0 ? ' comment-child' : ' comment-parent'; ?> /* 自定义评论的代码结构 */ <li id="li-<?php $comments->theId(); ?>" class="comment-body <?php echo $commentLevelClass;?>"> <div class="media" id="<?php $comments->theId(); ?>"> <?php $comments->gravatar(); ?> <div class="media-body"> <?php $comments->author(); ?> <?php $comments->content(); ?> </div> <div class="media-footer"> <time><?php $comments->date('Y-m-d H:i'); ?></time> <?php $comments->reply('Reply'); ?> </div> </div> <?php if ($comments->children) { ?> <div class="comment-children"> <?php $comments->threadedComments($options); ?> </div> <?php } ?> </li> <?php } ?>关于审核提示(不一定是正确的)官方在文档末尾说:最新版本更新:首次评论审核提示,在自定义评论代码的适当地方添加以下语句,否则将看不到审核提示语句。<?php $singleCommentOptions->commentStatus(); ?>但是这句话使用有问题,最直白的就是:$singleCommentOptions这边变量哪里来的,在threadedComments函数中,找遍天也没有创建过这个变量。事实上这个$singleCommentOptions需要改为$options所以实际代码是这个:<?php $options->commentStatus(); ?>但是,当我们在评论里面添加这句话的时候,你会发现,他并不是真的智能输出的,不管你这条评论是不是真的在审核,他都会显示文字:您的评论正等待审核!我在百度找到了一个判断:<?php if ('waiting' == $comments->status): ?> <?php $options->commentStatus(); ?> <?php endif;?>通过这个判断来输出是否需要显示审核提示,but,既然我if都能判断了,<?php $options->commentStatus(); ?>这句话反倒可有可无了,因为我可以自己写提示文字啊。<?php if ('waiting' == $comments->status): ?> <span>什么吊评论,还要老子审核!!!</span> <?php endif;?>这不香吗???所以,我感觉这代码真的好尬啊!!!php渲染出自定义模板评论现在我们模板已经写好了,是时候让它出现在我们的页面上了。在我们需要添加评论的页面先引入list-template.php文件<?php $this->need("components/list-template.php");?>$this->need()方法,他是相对于当前主题目录的,比如你主题名字叫nmd,那么components就是nmd主题目录下的一个文件夹nmd 主题文件夹 | ---- components |----| | ---- list-template.php | ...大概是这样的一个结构,具体就不细说了,意思到位就行!引入模板后,我们需要使用<?php $comments->listComments(); ?>这段代码渲染评论,但是要注意,如果你的代码前面,没有声明$comments代码的话,使用这句话就会报错。那么代码应该是这样:<?php //评论列表 模板->$comments对象->渲染?> <?php $this->need("components/list-template.php");?> <?php $this->comments()->to($comments); ?> <?php $comments->listComments(); ?>ok,到这基本上你已经领悟了typecho的自定义评论了!恭喜出师。。。老父亲留下激动的泪水注意在评论中点击回复,可能会导致刷新页面,原因是因为在评论的回复表单那(form)元素,没有添加取消回复的代码:<?php $comments->cancelReply('放弃回复'); ?>这个代码记得添加到form表单那,当然form表单那边id啥的记得不要删了,按照官方文档那种基本上没啥问题。而本次教程只是讲怎么自定了评论列表,如果以后有时间,再讲讲怎么自定评论表单吧!
2021年05月12日
6,578 阅读
4 评论
3 点赞
2021-02-08
Typecho自定义后台编辑器功能
首先看下效果图上面的增加按钮很简单,append一个li标签就可以实现,主要是在于向文本框中插入内容,以及输入键盘按键也能实现插入对应的功能。在网上百度了一番,都是互相抄袭,而且也不封装一下,有bug都没人解决,很无奈自己折腾了一个使用方法首先在主题 functions.php 里增加一个插件函数,这个函数的用途是在编辑文章和编辑页面里面引入自定义JSTypecho_Plugin::factory('admin/write-post.php')->bottom = array('Editor', 'edit'); Typecho_Plugin::factory('admin/write-page.php')->bottom = array('Editor', 'edit'); class Editor { public static function edit() { echo "<script src='" . Helper::options()->themeUrl . '/typecho/editor/joe.extend.js' . "'></script>"; echo "<script src='" . Helper::options()->themeUrl . '/typecho/editor/joe.editor.js' . "'></script>"; } } 上面的 joe.extend.js 没压缩也没加密,下面是 joe.extend.js 源码(function ($) { $.fn.extend({ /* 按键盘实现插入内容 */ shortcuts: function () { this.keydown(function (e) { var _this = $(this); e.stopPropagation(); if (e.altKey) { switch (e.keyCode) { case 67: _this.insertContent('[code]' + _this.selectionRange() + '[/code]'); break; } } }); }, /* 插入内容 */ insertContent: function (myValue, t) { var $t = $(this)[0]; if (document.selection) { this.focus(); var sel = document.selection.createRange(); sel.text = myValue; this.focus(); sel.moveStart('character', -l); var wee = sel.text.length; if (arguments.length == 2) { var l = $t.value.length; sel.moveEnd('character', wee + t); t <= 0 ? sel.moveStart('character', wee - 2 * t - myValue.length) : sel.moveStart('character', wee - t - myValue.length); sel.select(); } } else if ($t.selectionStart || $t.selectionStart == '0') { var startPos = $t.selectionStart; var endPos = $t.selectionEnd; var scrollTop = $t.scrollTop; $t.value = $t.value.substring(0, startPos) + myValue + $t.value.substring(endPos, $t.value.length); this.focus(); $t.selectionStart = startPos + myValue.length; $t.selectionEnd = startPos + myValue.length; $t.scrollTop = scrollTop; if (arguments.length == 2) { $t.setSelectionRange(startPos - t, $t.selectionEnd + t); this.focus(); } } else { this.value += myValue; this.focus(); } }, /* 选择 */ selectionRange: function (start, end) { var str = ''; var thisSrc = this[0]; if (start === undefined) { if (/input|textarea/i.test(thisSrc.tagName) && /firefox/i.test(navigator.userAgent)) str = thisSrc.value.substring(thisSrc.selectionStart, thisSrc.selectionEnd); else if (document.selection) str = document.selection.createRange().text; else str = document.getSelection().toString(); } else { if (!/input|textarea/.test(thisSrc.tagName.toLowerCase())) return false; end === undefined && (end = start); if (thisSrc.setSelectionRange) { thisSrc.setSelectionRange(start, end); this.focus(); } else { var range = thisSrc.createTextRange(); range.move('character', start); range.moveEnd('character', end - start); range.select(); } } if (start === undefined) return str; else return this; } }); })(jQuery); 上面的shortcuts方法主要用于实现按下键盘插入内容接着看 joe.edit.js的内容/* 增加自定义功能 */ const items = [ { title: '回复可见', id: 'wmd-hide-button', svg: '<svg t="1612402690962" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15751" width="20" height="20"><path d="M554.666667 438.101333V277.333333h-85.333334v160.768L330.112 357.717333l-42.666667 73.898667L426.666667 512l-139.221334 80.384 42.666667 73.898667L469.333333 585.898667V746.666667h85.333334v-160.768l139.221333 80.384 42.666667-73.898667L597.333333 512l139.221334-80.384-42.666667-73.898667L554.666667 438.101333z" p-id="15752" fill="#9b9b9b"></path></svg>', text: '\n[@hide]这里的内容回复后才能看见[/hide]\n' } ]; items.forEach(_ => { let item = $(`<li class="wmd-button" id="${_.id}" title="${_.title}">${_.svg}</li>`); item.on('click', function () { $('#text').insertContent(_.text); }); $('#wmd-button-row').append(item); });
2021年02月08日
3,422 阅读
0 评论
4 点赞