如何为WordPress实现关键词自动添加链接


这几天在闲来没事的时候就会想着和blog相关的配置问题,有一个问题在写比较长的文章的时候经常会考虑:在别人blog的文章中是如何对其中出现的某些关键字,比如sqlmap,添加链接的?(说直白一点就是:如何为文章中的某些关键词自动添加链接?)手动一个一个添加在文章数量较少、内容不多的时候还撑得过去,但是一旦文章多起来了,而且像有的blog还是用爬虫自动抓取的内容进行发布,人工添加显然就不现实了,想着想着,就决定得解决这个问题(念念不忘,必有回想)。

组织一下搜索关键字:WordPress、关键词、自动添加链接。

然后就开始Bing/Google搜索(Baidu在这种情况下能帮到的忙不大,一般只会在迫不得已的情况下才会去试试),从一堆链接中选了几个出来,先大致看看思路,然后在对其中看起来可能性较大的研究一下,找出来的方法如下:

1.用插件实现

这种方法就不多说了,WordPress上的一些问题/功能基本上都可以用插件解决/实现,不过插件相对于自己修改代码来说要稍微多耗些资源,如果服务器性能较高的话也就没什么影响了,这里就稍微列一下网上给出的一些推荐:Simple Tags、SEO Smart Links、WP KeywordLink、Keyword Link Plugin ……(自己也可以去WordPress的后台安装插件那儿搜关键字“keyword”、“tag/link”这些,肯定还是能够找到适合自己的一款的)

2.修改代码(一)

在之前也修改过几次代码以实现一些小功能,所以现在对修改代码的流程也有了一个大致的了解–修改对应主题下的functions.php文件,一般是在文件末尾进行添加功能函数(在文件末尾添加是为了方便的知道你自己到底修改了哪些内容,方便在出现问题时rollback到最初的状态)

<?php
/**
* auto add tag link for WordPress
*/
$replace_limit = 1;	// 一篇文章中同一个标签添加几次链接
add_filter('the_content', 'tag_link', 1);

function tag_sort($a, $b){	//按tag名字的长度排序
	if ( $a->name == $b->name ) return 0;
	return ( strlen($a->name) > strlen($b->name) ) ? -1 : 1;
}

function tag_link($content){	//为符合条件的tag添加link
	global $replace_limit;
	$posttags = get_the_tags();
	if ($posttags) {
		usort($posttags, "tag_sort");
		foreach($posttags as $tag) {
			$link = get_tag_link($tag->term_id);
			$keyword = $tag->name;
			/* 添加链接的代码 */
			$cleankeyword = stripslashes($keyword);
			$url = "<a href="$link" title="".str_replace('%s', addcslashes($cleankeyword, '$'), __('View all posts in %s')).""";
			$url .= ' target="_blank"';
			$url .= ">".addcslashes($cleankeyword, '$')."</a>";
			$limit = $replace_limit;
			/* 不添加链接的代码 */
			$content = preg_replace( '|(<a[^>]+>)(.*)('.$ex_word.')(.*)(</a[^>]*>)|U'.$case, '$1$2%&&&&&%$4$5', $content);
			$content = preg_replace( '|(<img)(.*?)('.$ex_word.')(.*?)(>)|U'.$case, '$1$2%&&&&&%$4$5', $content);
			$cleankeyword = preg_quote($cleankeyword, ''');
			$regEx = ''(?!((<.*?)|(<a.*?)))('. $cleankeyword . ')(?!(([^<>]*?)>)|([^>]*?</a>))'s' . $case;
			$content = preg_replace($regEx, $url, $content, $limit);
			$content = str_replace( '%&&&&&%', stripslashes($ex_word), $content);
		}
	}
	return $content;
}

从网上找的代码,自己按照理解稍微修改了一下,也不复杂,自己看着办吧。

3.修改代码(二)

虽然说也是修改代码,思路也差不太多,但是是另一种实现方法,虽没上面的那个考虑的全,不过真的是简单方便也可以达到目的:

function replace_keywords($text){
	$replace = array(
	// '要查找的关键词' => '进行替换的关键词'
	'wordpress' => '<a href="#">wordpress</a>',
	'excerpt' => '<a href="#">excerpt</a>',
	'function' => '<a href="#">function</a>'
	);
	$text = str_replace(array_keys($replace), $replace, $text);
	return $text;
}

add_filter('the_content', 'replace_keywords');

你可以将href的值修改为对应的tag的URL也可以修改成网站地址,看个人喜好了。


在修改代码的过程中学到的一些知识:

WordPress中文文档    #以后可以在这上面有针对性的搜索/查找

WordPress中的add_filter()/add_action()的作用和区别

add_filter/add_action 介绍

WordPress 中有一种叫执行挂勾的机制,允许插件把一些功能“挂载”到 WordPress 当中。也就是说,在系统运行至某一个环节时,去调用插件内的一些函数。WordPress中有2个函数可以让我们执行WordPress标准操作到时候调用我们自定义的函数,这2个函数分别是 add_action() 和 add_filter()。

先看看WordPress里面关于这2个函数的定义,在 wp-includes/plugin.php 文件中,先看 add_filter() 的定义:

function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
	global $wp_filter, $merged_filters;
	$idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);
	$wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
	unset( $merged_filters[ $tag ] );
	return true;
}

再看看 add_action() 函数的定义:

function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
	return add_filter($tag, $function_to_add, $priority, $accepted_args);
}

看到这里你也许就明白了,其实add_action()是调用add_filter()的功能,没有加入新的处理操作,说明这两个函数是没有什么区别的。下面来详细说说add_filter()函数。

通过add_filter()函数的定义,我们可以看到该函数是把我们要hook的函数的一些变量存储在 global $wp_filter 这样一个全局数组中的,包括$tag,即我们要hook的函数;$priority即hook的顺序;还有就是$idx这个就是我们自定义函数的名称了。

值得注意的是如果我们在使用add_filter这个函数的时候没有指定顺序/优先级,那么默认的就是10,这个在插件开发的时候值得注意一下,以免和其它插件产生冲突。下面看看该函数的语法

<?php add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1); ?>
参数:
$tag (字符串)(必需)
连接到$function_to_add的过滤器名称 默认值:None

$function_to_add (回调)(必需)
应用过滤器时被调用函数的名称 默认值:None

$priority (整数)(可选)
用于规定函数被执行的顺序,函数与特定动作关联。较小的数字匹配较早的执行,同等优先级的函数按加入action的顺序被执行。 默认值:10

$accepted_args (整数)(必需)
函数所接受参数的数量。在WordPress 1.5.1及之后版本中,连接的函数可吸收其它在调用do_action() 或 apply_filters()时设置的参数。 默认值:None

用户还需要为过滤器回调时函数的命名空间提供一个指示器,如:
<?php add_filter(‘media_upload_newtab’, array(&$this, ‘media_upload_mycallback’)); ?>
否则WordPress会为函数查找自备命名空间,从而引发异常状况。

返回的值
$function_to_add 成功添加到$tag过滤器时返回true。返回函数可接受的参数数量。在WordPress 1.5.1及之后版本中,连接的函数可吸收其它在调用 do_action() 或 apply_filters() 时设置的参数。例如,comment_id_not_found动作将传递任何函数,若该函数将所请求的评论编号连接到该动作。

示例
博客发表新内容时用电子邮件通知朋友:

function email_friends($post_ID)  {
	$friends = 'bob@example.org'
	mail($friends, "sally's blog updated" , 'I just put something on my blog: http://blog.example.com');
	return $post_ID;
}
add_filter('publish_post', 'email_friends');

总结一下:网上很多说到add_filter与add_action的区别,说的主观上的区别,add_filter是指在数据显示之前对数据进行一些(过滤)处理,而add_action则是执行一下复杂的操作。其实二者在功能上是没有任何区别的。

add_filter()函数的第一个参数也比较讲究:
  • wp_title
  • the_generator  #WordPress的版本等信息
  • publish_post   #发表的public属性的文章
  • the_content    #我猜的话应该就是文章要显示的内容
  • the_excerpt

我最后的选择

本来之前是非常想实现这样的自动化功能以减轻负担的,而且刚才也花了这么长时间进行搜索&代码阅读/修改,不过在看到了一句话(我也用过插件的方法,完美搞定博客的内链问题,但是我个人认为一篇文章是包含着作者思想的,是有血有肉有生命力的,我是不希望参杂一些比较机械的元素,即便是都要出现的链接,尽量的在最适合的位置去添加,这是人的思维,而机器是没办法理解的。所以插件和修改代码的方法我后来都未使用,本身每天写点内容并不算负担,没必要偷这个懒。)之后我改变了想法,反正blog现在的内容又不多,写文章也不是为了写而写,是在需要表达某种想法时自然而然的一个过程,并且在手动添加链接的过程中还可以对文章进行进一步的审阅、修改,所以,老老实实的选择手动添加吧,更准确,而且也是一种“情怀”……(然后呢,写这篇文章也就是为了记录一下折腾的过程,万一以后情怀渐渐消逝了呢?嘿嘿)

 

参考链接

 


《 “如何为WordPress实现关键词自动添加链接” 》 有 2 条评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注