使用google-code-prettify实现代码高亮

首先感谢坏猫的方法。
因为我这两天其实一直就在筹划干掉玻璃泉的wp-code-highlight插件,今天看到坏猫的办法之后,正好两厢参照,作出了自己的方案。

首先,说说为什么要干掉wp-code-highlight。因为一直在谋划心目中的完美主题,其中一个先期工作就是要让所有css和js可控。而很不幸wp-code-highlight的js和css不是按照wp的正统方式追加的,也就是说,我要么使用这个插件,要么不用,但无法做到启用后限定js的作用范围。

因为坏猫那边说得已经很详细了,所以我这里的侧重点是如何分页面控制加载js。
我这里的习惯是把这种可以与主题分开的控制项目,单独做成一个插件,这样即使换了主题,代码也可以生效。如果想要在自己的主题里实现,尽管加到functions.php里好了,具体的不同参照注释。能自己改代码的应该都能看懂……

第一步,追加触发动作

add_action('plugins_loaded', 'apip_init');
//add_action( 'after_setup_theme', 'apip_init' ); /*如果是主题,用这句*/
function apip_init()
{
	add_action('get_header','apip_header_actions') ;
	add_action('get_footer','apip_footer_actions') ;
	
	add_action('admin_print_footer_scripts','apip_quicktags');
}

第二步,在header动作里追加对于文章内容的过滤项。加上这个,就不用修改既存的《pre》标签了。

function apip_header_actions()
{
	if ( in_category('code_share') )
	/*定义一个categroy,只有这个类别的才加载css,可以提高一丢丢速度。或者换成in_tag然后追加一个tag也可*/
	{
		add_filter('the_content', 'apip_code_highlight') ;
	}
}

//下面这个函数要感谢玻璃泉。不加的话双引号会引起内容错乱。
function wch_stripslashes($code){
	$code=str_replace('\"', '"',$code);
	$code=htmlspecialchars($code,ENT_QUOTES);
	return $code;
}

//如果想要行号,在prettyprint 后面加上一个 linenums
function apip_code_highlight($content) {
	return preg_replace("/<pre(.*?)>(.*?)<\/pre>/ise",                                                          
		"'<pre class=" prettyprint ">'.wch_stripslashes('$2').'</ pre>'", $content);
}

第三步,在footer里加css和js。一般来说css和js要在footer里加。但因为已经对类别进行了限制,所以跟第二步的写到一起其实也影响不大。

function apip_footer_actions()
{
	if ( in_category('code_share') )
	{
?>
		<script type="text/javascript">
			window.onload = function(){prettyPrint();};
		</script>
<?php
		//如果是主题,下面两个函数换成template_dir_url( __FILE__ )
		wp_enqueue_script('prettify_js', plugin_dir_url( __FILE__ ) . 'js/prettify.js', array('jquery'), null, true);
		wp_enqueue_style( 'prettify_style', plugin_dir_url( __FILE__ ) . 'css/prettify.css' );
	}
}

第四步,追加编辑画面的标签

function apip_quicktags()
{
?>
	<script type="text/javascript" charset="utf-8">
		QTags.addButton( 'eg_pre', 'pre', '<pre>\n', '\n</ pre>\n', 'p' );
	</script>
<?php
}

js和css的下载地址,自备梯子。

===== Update.2019.8.7 =====
因为php7不支持preg_replace第一个参数的/e选项,所以第二步的第三段代码要作如下修改:

function apip_code_highlight($content) {
    $result = preg_replace_callback('/<pre(.*?)>(.*?)<\/pre>/is', function ($matches) {
        return '<pre class=" prettyprint ">' . wch_stripslashes($matches[2]) . '</ pre >'; } , $content);
   return $result ;
}

已有11条评论

  1. 我也有用不过没做的你这么高级。

    1. 这个其实只是捎带,我在尝试不同的页面加载不同的js.但主题不是自己写的不明白每个js的用途,闹心.

      1. 如果不是合并加密的js,应该不难看懂啊。

        1. 加了min了
          而且我现在用的是子主题的方法,追求父主题一字不动之道。

  2. 我也想着EM里编辑器里能否有个引用,图片边框的效果。

    1. 这个直接写css就能实现吧

      1. 谢谢支招,空下来了就试试。

        1. 只对贴代码程序猿的有意义.王老师转行当攻城狮的时候才能用得上吧…

  3. 精益求精的态度啊,用什么加载什么,赞。

    1. 因为被一个测速度的网站鄙视了.

  4. 这个还不错,相对而言代码看起来清晰

    1. 在坏猫的基础上改的。

  5. 我前两天也折腾了,但是影响加载速度哦,就没搞了。

    1. 我的方法不会影响首页,只在有代码的时候加载

      1. 怎么引用这些呢?

        1. 你指的是引js吗?我是在第三步做的.

  6. 个人觉得知更鸟的那个代码高亮转换挺不错的,代码实现挺好的

    1. 宁可慢死也不会每次贴代码都去访问一下他的站.

      1. 这个倒也是,我也是用他的主题,顺便的。如果不用他的主题,也挺麻烦的,折腾这个

        1. 自己动手丰衣足食

  7. 上面列出的代码都需要写到functions.php里吗?

    1. 往主题里加的话,是。
      if ( in_category(‘code_share’) )注掉,这是我自己的分类。
      我更喜欢放到自己写的插件里。

你好,新朋友。留言前请先填写昵称邮箱