最近开始整理 WordPress 的插件,发现有些插件功能越来越重,比如 Yoast SEO 的插件,出于个人洁癖就把他删除了。但是目前网站原来的 Breadcrumbs 导航功能是这个插件提供的,所以就开始查找替换方案。网上搜索发现一片文章介绍的比较具体 --- 《WordPress实现面包屑导航的方法》,博主其实也是参考了国外网友的非插件实现。
以下代码都是基于 Dimox 的原创,我只是在他基础上做了微调,改动不大:
学会编程我们能够和计算机沟通
最近开始整理 WordPress 的插件,发现有些插件功能越来越重,比如 Yoast SEO 的插件,出于个人洁癖就把他删除了。但是目前网站原来的 Breadcrumbs 导航功能是这个插件提供的,所以就开始查找替换方案。网上搜索发现一片文章介绍的比较具体 --- 《WordPress实现面包屑导航的方法》,博主其实也是参考了国外网友的非插件实现。
以下代码都是基于 Dimox 的原创,我只是在他基础上做了微调,改动不大:
最近突然涌起兴趣去阅读 CPython 源码,网上也看了不少解析的文章,后来网上看到《Python源码剖析》评价不错,可惜现在已经绝版,只能从豆瓣阅读购买了一本电子书观摩 。
我从网上下载的是最新的 Python 2.7 源码,这本书配套的解说代码是 Python 2.5 的,这是一个遗憾,但是大体上相差不大,刚好昨天遇到一处。
昨天看到 Python int 实现的原理,这里不详细表述,有兴趣的可以去看看书。其中整数加法 (int_add) 的实现,虽然代码只有几行,但是其中隐藏的知识点还是非常多的,花了点时间回顾了一些基础知识,在这里也简单总结下。
以下是 2.5 里面加法的实现,也是书中提供的例子,这里直接引用过来作为参考对比,注释是作者加入的。
static PyObject* int_add(PyIntObject *v, PyIntObject *w) { register long a, b, x; CONVERT_TO_LONG(v, a); CONVERT_TO_LONG(w, b); x = a + b; //[1] : 检查加法结果是否溢出 if ((x^a) >= 0 || (x^b) >= 0) return PyInt_FromLong(x); return PyLong_Type.tp_as_number->nb_add((PyObject *)v, (PyObject *)w); }
下面是 2.7 中的代码对比,大体都没有变化:
static PyObject *
int_add(PyIntObject *v, PyIntObject *w)
{
register long a, b, x;
CONVERT_TO_LONG(v, a);
CONVERT_TO_LONG(w, b);
/* casts in the line below avoid undefined behaviour on overflow */
x = (long)((unsigned long)a + b);
if ((x^a) >= 0 || (x^b) >= 0)
return PyInt_FromLong(x);
return PyLong_Type.tp_as_number->nb_add((PyObject *)v, (PyObject *)w);
}
WordPress 内嵌 Gist 链接的方法很简单,将以下代码添加到当前主题的 functions.php 文件中:
/* * Embed gists with a URL in post article */ function dangopress_embed_gist($matches, $attr, $url, $rawattr) { $embed = sprintf( '<script src="https://gist.github.com/%1$s.js%2$s"></script>', esc_attr($matches[1]), esc_attr($matches[2]) ); return apply_filters('dangopress_embed_gist', $embed, $matches, $attr, $url, $rawattr); } wp_embed_register_handler('gist', '#https?://gist\.github\.com(?:/[a-z0-9-]+)?/([a-z0-9]+)(\?file=.*)?#i', 'dangopress_embed_gist');
在上面的代码中,我们注册了 Gist 链接的处理方法 dangopress_embed_gist
。当我们拷贝 Gist 链接到编辑框时,会调用改方法生成内嵌内容。
Gist 链接是通过注册过程中,指定的正则表达式匹配的:
#https?://gist\.github\.com(?:/[a-z0-9-]+)?/([a-z0-9]+)(\?file=.*)?#i
开发过程中为了减少 hardcode,不可避免的需要提供配置文件给用户定制。对于高级编程语言来说,因为有丰富的第三方库,可供选择的配置文件格式有很多,比如 xml、jsno、ini、yaml 等等。
而对于 linux shell,基本上很难使用前面提到的各种格式。所以在 unix 系统上,很多 shell 脚本的配置文件都是纯粹的 key=value 文本格式,例如绝大多数的开机服务启动脚本、网络配置文件等。
例子 1:ntp 配置文件
$ cat /etc/sysconfig/ntpd # Drop root to id 'ntp:ntp' by default. OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid" # Set to 'yes' to sync hw clock after successful ntpdate SYNC_HWCLOCK=no # Additional options for ntpdate NTPDATE_OPTIONS=""
例子 2:网络配置文件
$ cat /etc/sysconfig/network NETWORKING="yes" HOSTNAME="xx.com"
而且,要注意得是,一般 key=value
的等号两边不应该有空格,因为大多数脚本都是直接 source 配置文件的(当然,也有部分脚本是会自己处理配置文件格式),使用起来很简单,基本上没有解析的操作:
$ cat /etc/init.d/network if [ ! -f /etc/sysconfig/network ]; then exit 0 fi . /etc/sysconfig/network
理所当然,这种格式无法满足更复杂的配置文件需求,比如 ini 格式的 section。那么,在 shell 中除了满世界去找一个解析库之外,能有什么方法可以实现呢?
假设,我们管理着 n 个集群,每个集群配置项都是一样的,我们需要在 shell 脚本中,可以根据集群的名称来导入对应的配置。
Bash 里的 word splitting 是很基础的一个知识点,如果没有理解透彻,很多时候会犯下不少奇奇怪怪的错误(参见 Bash Pitfalls,或者本博客翻译 Bash Pitfalls: 编程易犯的错误(一))。
一个例子,现在我们现在要一次读入文件 onefile.txt 的内容并输出,假设文件的内容是这样的:
kodango -> ~/Workspace/coding/test $ cat onefile.txt hello world
当我们习惯性地使用 for 循环来解决这个问题时,你会发现输出的结果与预期大相径庭:
$ for i in $(<onefile.txt); do echo "$i"; done hello world
给我们的脑子也打开调试开关。首先 onefile.txt 的内容一次性地输出给 for 循环,我在中间用比较形象的 tag 来描述一个空白字符:
hello<blank>world<newline><blank><newline>
这个时候,word splitting 发生了,将以上字符串按照 IFS 分隔成 hello
,world
。IFS 是用来分隔命令中的每一个单词的,它可以有多个字符组成,每个字符都被视作分隔符。默认情况下,它的值为 <newline><tab><whitespace
,这也是为什么默认都是按空格、回车等空白字符分隔的原因。
这样一来 hello 和 world 被分隔可以很好地解释,但是那又是为什么第二行的空行没有了呢?原来,当 IFS 包含空白字符时(比如回车、空格、制表符等),在任何需要分隔单词的场景下,位于字符串开头和结尾的空白字符会被删除,另外一点是,字符串中间的连续空白会被压缩成一个。
我的博客人气一般,但是垃圾评论却特别之多,严重影响我的心情。自从开博客以来,我一直都是通过 Akismet 插件来发现和过滤垃圾评论,效果非常不错,很少有漏网之鱼。但是前两天在阅读了云淡然同学写的文章wp_create_nonce实现wordpress垃圾评论终极防御之后,我突然萌生出自己写一些阻挡垃圾评论策略的想法。
下面我介绍几条本博客现在正在使用的阻挡垃圾评论的策略,几天下来效果还可以接受。每一种策略都不是完美的,所以只能多种方式配合使用。当然,道高一尺,魔高一丈,很多策略都必须要不断地改进与完善,并且最好根据自己的情况适当地调整。当然,如果你不想折腾,还是老老实实地使用 Akismet 插件来防护吧,插件的功能更加完善可靠,本文的方法只适合于不想启用过多插件和喜欢折腾的同学。
首先我们可以借助 .htaccess 文件来阻挡部分恶意的垃圾评论,这一类评论往往是通过脚本或者工具自动提交的。请将以下内容添加到网站根目录的 .htaccess 文件中:
RewriteEngine On RewriteCond %{REQUEST_METHOD} POST RewriteCond %{REQUEST_URI} .wp-comments-post\.php$ RewriteCond %{HTTP_REFERER} !.*kodango.com.* [OR] RewriteCond %{HTTP_USER_AGENT} ^$ RewriteRule (.*) http://%{REMOTE_ADDR}/$ [R=301,L]
上面的几条规则,可以阻挡来源不是你博客,或者 user agent 信息为空的机器人评论。
新浪微博的置顶功能相信大家非常熟悉,其实 WordPress 早在 2.7 之后就拥有了文章置顶的功能。但是,实际上这个功能在大多主题上却没太多用武之地。我想其中的一个原因,是很多像我们这样的个人博客,首页基本上只展示最新的5-10篇文章,如果再置顶个几篇,首页的内容基本上就不变了。
不过,如果我们换个角度,把置顶文章从页面中央移到侧栏,这样的 效果应该会不错,首先首页的文章列表中不会受到置顶的干扰,同时位于侧栏的置顶文章又有类似文章推荐的效果,我们动手来试试。
整个解决方案需要考虑到两点:
在主题的 functions.php 中加入以下代码:
/* * Alter the main loop */ function dangopress_alter_main_loop($query) { /* Only for main loop in home page */ if (!$query->is_home() || !$query->is_main_query()) return; // ignore sticky posts, don't show them in the start $query->set('ignore_sticky_posts', 1); } add_action('pre_get_posts', 'dangopress_alter_main_loop');
这里通过指定ignore_sticky_posts
为1,查询出的文章列表就会忽略置顶文章。
Google Code Prettify 是 Google 开源的一个用于代码高亮的 Javascript 库,支持 C/C++, Java, Python, Ruby, PHP,Javascript 等等常见语言,目前包括 Google Code、Stackoverflow.com 在内的很多网站都在使用它。最吸引人的是,在使用它进行代码高亮时,甚至不需要指明语言类型,Prettify 会自动判断并处理。
使用 Prettify 一般只需要包含两个文件:prettify.js 和 prettify.css,压缩过后的 prettify.js 大小差不多在 15K 左右,非常小巧。
在网站页面中引用 Prettify文件:
<link href="prettify.css" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="prettify.js"></script>
同时增加以下代码,让页面加载完成时执行 Prettify:
<script type="text/javascript"> window.onload = function(){prettyPrint();}; </script>
Prettify 会在网页中查找<pre class="prettyprint">...</pre>
或者<code class="prettyprint">...</code>
包围的代码片断,对它们进行高亮。