写了一个自用的小鸟主题,主页与分类页基本都定稿了,但是single页面的内容部分感觉过于单一,就想着是不是可以利用markdown加入类名。但尝试了很多网上的方案,hyperdown(typecho的markdown解析器)都无法正常解析。
于是转而考虑直接写入html语句的方式,为编辑器添加几个按钮,以含类名的html方式一些不同的类名,根据类名实现不同的视觉效果。比如利用"single-jplink"类名实现了下面这样一个按钮效果,链接指向joe主题的《自定义后台编辑器功能》,这也是本文的参考。
修改编辑的大致原理是通过插件语法在文章或页面的编辑页插入一段js,利用js添加按钮并绑定动作,首先在function.php里加入如下代码,这段代码会在页面编辑以及文章编辑页时在末尾插入一段js代码,代码的路径可以自行定义,博主把它暂时放在了主题的js文件夹里,就是代码中的“/js/editor.js”:
/*========
后台编辑器
========*/
Typecho_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 . '/js/editor.js' . "'></script>";
}
}
然后将命名为editor.js代码放入主题的js文件夹,js全文如下:
(function ($) {
$(document).on('DOMContentLoaded', function(){
const items=[
{
title:'下载',
id:'wmd-dllink-button',
class:'single-dllink'
},
{
title:'跳转',
id:'wmd-jplink-button',
class:'single-jplink'
},
];
items.forEach(function(item){
let element= $(`<li class="wmd-button" id="${item.id}" title="${item.title}">${item.title}</li>`);
element.on('click',function(){
$('#text').toggleSelection(item.class);
});
$('#wmd-button-row').append(element);
});
});
$.fn.extend({
toggleSelection: function (a) {
this.focus();
let selected=document.getSelection();
let result=selected.toString();
if(result.length==0)return;
let pattern=/<a class="(.*?)" href="(.*?)" rel="nofollow" target="_blank">(.*?)<\/a>/;
let before=`<a class="${a}" href="(.*?)" rel="nofollow" target="_blank">`;
let after='</a>'
if(pattern.exec(result)){
if(pattern.exec(result)[1]==a){
selected.focusNode.children[1].setRangeText(pattern.exec(result)[3]+"||"+pattern.exec(result)[2]);
}else{
selected.focusNode.children[1].setRangeText(result.replace(pattern.exec(result)[1],a));
}
}else{
selected.focusNode.children[1].setRangeText(before.replace('(.*?)',result.split('||')[1])+result.split('||')[0]+after);
}
}
});
})(jQuery);
程序实现了这样一个功能,将“aa||bb”格式的数据通过正则匹配,分别将aa作为a标签的内容,将bb填入元素的href。成功生成后,在选区未被变更的情况下,如果再次点击按钮,则让选区恢复为原值,如果想要更换为另一个类,则直接点击一下另一个按钮即可。
为了这个小功能看了整整两天的代码,但最后发现理想丰满但现实过于骨感,默认的编辑器不处理(即直接输出html)的标签极为有限,印象中仅有“ul|table|pre|a”等标签以及一些格式控制标签(比如加粗斜体等)会被正确处理为html元素,其他的大多会被一对双引号打回原形,成了单纯的字符。所以最终只实现了对于链接的类区分,利用不同的类对a标签实现了不同的样式。
一点补充
学习过程中发现,对于其他元素的支持,可以通过修改HyperDown.php文件的方式来扩展,但是,这种方式可能在升级程序后失效,感觉缺乏一些兼容性,而且更换其他主题后,很可能导致页面上出现多余的html标签,修改方法请点击上方链接查看。