WordPress建站过程中对于插件的使用是一个比较难取舍的问题,显而易见对于一些最常用的而且自己通过代码实现基本无可能的功能,比如实现缓存功能,插入一些常见的Slideshow等等,不太可能放弃现有非常完美的插件而自己去开发一个,类似很成熟的功能,首选肯定是安装对应的插件,然后对该插件做一些优化设置,结合本站之前教程中写过的 BuddyPress载入的jQuery easing与常用的slideshow插件冲突的终极解决方案 里边搭配类似 Plugin Organizer 插件对前台各个页面的插件载入进行有选择性的设置,从而防止因插件引起的冲突问题。

本文着重于对一些简单的功能实现,比如 admin bar 隐藏,彩色标签云的实现,删除后台新建的角色等等,类似的功能事实上也完全可以找到很多实现的插件,但是试想为了实现这么一个简单的功能而去安装一个插件,从而可能导致整站页面都因为这个插件而多载入js和css文件,明显不利于网站优化,基于这个考虑,本文着眼于类似功能的非插件的实现方式:

WordPress登陆后跳转回登录前的页面

/* Redirect back to referring page after login */
if ( (isset($_GET['action']) && $_GET['action'] != 'logout') || (isset($_POST['login_location']) && !empty($_POST['login_location'])) ) {
        add_filter('login_redirect', 'my_login_redirect', 10, 3);
        function my_login_redirect() {
                $location = $_SERVER['HTTP_REFERER'];
                wp_safe_redirect($location);
                exit();
        }
}

添加nofollow和target=_blank到出站链接中

/* Add nofollow and _blank to external link */
function rel_nofollow( $content ) {
    return preg_replace_callback( '/<a[^>]+/', 'rel_nofollow_callback', $content );
}     
add_filter( 'the_content', 'rel_nofollow', 99999 );

function rel_nofollow_callback( $matches ) {
    $link = $matches[0];
    $exclude = '('. home_url() .'|http://([^.]+\.)?(wp.org|wp.com))';
    if ( preg_match( '#href=\S('. $exclude .')#i', $link ) )
        return $link;

    if ( strpos( $link, 'rel=' ) === false ) {
        $link = preg_replace( '/(?<=<a\s)/', 'rel="nofollow" target="_blank" ', $link );
    } elseif ( preg_match( '#rel=\S(?!nofollow)#i', $link ) ) {
        $link = preg_replace( '#(?<=rel=.)#', 'nofollow ', $link );
    }

return $link;   
}

载入模版内部的文件格式代码

本条不算什么重要功能的实现代码,纯粹是因为自己经常忘记这个格式,一下子又无从找起,因此纯粹算是一个记录备用而已,见笑了。

<?php include(TEMPLATEPATH . '/top.php'); ?>

不装插件直接移除WordPress admin bar的方法

请在WordPress模版函数文件functions.php里边加入以下代码:

function my_function_admin_bar(){ return false; } 
add_filter( 'show_admin_bar' , 'my_function_admin_bar');

WordPress删除由Role editor之类的角色管理插件新建的角色

请在WordPress模版函数文件functions.php里边加入以下代码:

$wp_roles = new WP_Roles();
$wp_roles->remove_role("designer");

这里假设您新建的角色名称是designer。

不装插件实现彩色标签云的方法

本条适合需要放置侧边栏标签云,又嫌弃默认的标签云样式太过于死板,但又不想为这么点小功能而安装一个插件的用户,同样也是在模版函数文件functions.php里边加入如下代码即可:

/* 彩色标签云实现函数 */
function colorCloud($text) {
$text = preg_replace_callback('|<a (.+?)>|i', 'colorCloudCallback', $text);
return $text;
}
function colorCloudCallback($matches) {
$text = $matches[1];
$color = dechex(rand(0,16777215));
$pattern = '/style=(\'|\")(.*)(\'|\")/i';
$text = preg_replace($pattern, "style=\"color:#{$color};$2;\"", $text);
return "<a $text>";
}
add_filter('wp_tag_cloud', 'colorCloud', 1);

不装插件实现WordPress评论表情的方法

本方法借鉴了 “WordPress 非插件调用表情符” 在此表示感谢,方法如下:

首先下载模版目录新建一个文件叫做smiley.php,插入如下代码:

<script type="text/javascript" language="javascript">
/* <![CDATA[ */
    function grin(tag) {
    	var myField;
    	tag = ' ' + tag + ' ';
        if (document.getElementById('comment') && document.getElementById('comment').type == 'textarea') {
    		myField = document.getElementById('comment');
    	} else {
    		return false;
    	}
    	if (document.selection) {
    		myField.focus();
    		sel = document.selection.createRange();
    		sel.text = tag;
    		myField.focus();
    	}
    	else if (myField.selectionStart || myField.selectionStart == '0') {
    		var startPos = myField.selectionStart;
    		var endPos = myField.selectionEnd;
    		var cursorPos = endPos;
    		myField.value = myField.value.substring(0, startPos)
    					  + tag
    					  + myField.value.substring(endPos, myField.value.length);
    		cursorPos += tag.length;
    		myField.focus();
    		myField.selectionStart = cursorPos;
    		myField.selectionEnd = cursorPos;
    	}
    	else {
    		myField.value += tag;
    		myField.focus();
    	}
    }
/* ]]> */
</script>
<a href="javascript:grin(':?:')"><img src="/wp-includes/images/smilies/icon_question.gif" alt="" /></a>
<a href="javascript:grin(':razz:')"><img src="/wp-includes/images/smilies/icon_razz.gif" alt="" /></a>
<a href="javascript:grin(':sad:')"><img src="/wp-includes/images/smilies/icon_sad.gif" alt="" /></a>
<a href="javascript:grin(':evil:')"><img src="/wp-includes/images/smilies/icon_evil.gif" alt="" /></a>
<a href="javascript:grin(':!:')"><img src="/wp-includes/images/smilies/icon_exclaim.gif" alt="" /></a>
<a href="javascript:grin(':smile:')"><img src="/wp-includes/images/smilies/icon_smile.gif" alt="" /></a>
<a href="javascript:grin(':oops:')"><img src="/wp-includes/images/smilies/icon_redface.gif" alt="" /></a>
<a href="javascript:grin(':grin:')"><img src="/wp-includes/images/smilies/icon_biggrin.gif" alt="" /></a>
<a href="javascript:grin(':eek:')"><img src="/wp-includes/images/smilies/icon_surprised.gif" alt="" /></a>
<a href="javascript:grin(':shock:')"><img src="/wp-includes/images/smilies/icon_eek.gif" alt="" /></a>
<a href="javascript:grin(':???:')"><img src="/wp-includes/images/smilies/icon_confused.gif" alt="" /></a>
<a href="javascript:grin(':cool:')"><img src="/wp-includes/images/smilies/icon_cool.gif" alt="" /></a>
<a href="javascript:grin(':lol:')"><img src="/wp-includes/images/smilies/icon_lol.gif" alt="" /></a>
<a href="javascript:grin(':mad:')"><img src="/wp-includes/images/smilies/icon_mad.gif" alt="" /></a>
<a href="javascript:grin(':twisted:')"><img src="/wp-includes/images/smilies/icon_twisted.gif" alt="" /></a>
<a href="javascript:grin(':roll:')"><img src="/wp-includes/images/smilies/icon_rolleyes.gif" alt="" /></a>
<a href="javascript:grin(':wink:')"><img src="/wp-includes/images/smilies/icon_wink.gif" alt="" /></a>
<a href="javascript:grin(':idea:')"><img src="/wp-includes/images/smilies/icon_idea.gif" alt="" /></a>
<a href="javascript:grin(':arrow:')"><img src="/wp-includes/images/smilies/icon_arrow.gif" alt="" /></a>
<a href="javascript:grin(':neutral:')"><img src="/wp-includes/images/smilies/icon_neutral.gif" alt="" /></a>
<a href="javascript:grin(':cry:')"><img src="/wp-includes/images/smilies/icon_cry.gif" alt="" /></a>
<a href="javascript:grin(':mrgreen:')"><img src="/wp-includes/images/smilies/icon_mrgreen.gif" alt="" /></a>
<br />

在 comments.php 的 textarea 之前的适当位置加入以下代码:

<?php include(TEMPLATEPATH . '/smiley.php'); ?>

再到文章评论处刷新看看,一排很可爱的表情图片就出现了,是不是很酷。

高亮显示文章作者评论的方法

有关这个技巧网上好几年前就有相关的实现方法,无外乎就是判断当前评论的user_id号是否为1,为1的时候多输出一个类似authcomment的样式,然后通过定义此样式来实现评论作者高亮,这个方法有一个问题就是,只能高亮显示固定id号的作者,如果你的WordPress站点为多作者的站点,此方法将失效了,于是尝试找到一种更为通用的方法,结果发现最新版WordPress 3.5.1 的comment_class()函数自动带有了类似的功能,也就是凡是当前文章作者所发布的评论的li样式里边会自动带一个bypostauthor的样式,这样只要增加一条针对此样式的特殊高亮样式,就很轻松的实现了作者高亮显示的效果:

ol.comment_list li.bypostauthor{background-color: #FFF2C8 !important;}

不装插件实现文章浏览数的方法

这两天关注了本站各个插件所载入的时间,惊讶的发现WP-PostViews Plus用来显示文章浏览数的插件竟然载入时间高达一秒多,看来这个插件是非卸载不可了,一直以来对于文章浏览数的显示是否用插件就是一个很纠结的问题,现在看来没什么好犹豫的了,直接卸载,换成非插件方式来实现,首先在functions.php里边加入以下代码:

//Set the Post Custom Field in the WP dashboard as Name/Value pair
function bac_PostViews($post_ID) {
 
    //Set the name of the Posts Custom Field.
    $count_key = 'views';
     
    //Returns values of the custom field with the specified key from the specified post.
    $count = get_post_meta($post_ID, $count_key, true);
     
    //If the the Post Custom Field value is empty.
    if($count == ''){
        $count = 0; // set the counter to zero.
         
        //Delete all custom fields with the specified key from the specified post.
        delete_post_meta($post_ID, $count_key);
         
        //Add a custom (meta) field (Name/value)to the specified post.
        add_post_meta($post_ID, $count_key, '0');
        return $count . ' 浏览数';
     
    //If the the Post Custom Field value is NOT empty.
    }else{
        $count++; //increment the counter by 1.
        //Update the value of an existing meta key (custom field) for the specified post.
        update_post_meta($post_ID, $count_key, $count);
         
        //If statement, is just to have the singular form 'View' for the value '1'
        if($count == '1'){
        return $count . ' 浏览数';
        }
        //In all other cases return (count) Views
        else {
        return $count . ' 浏览数';
        }
    }
}

然后在single.php或者其他需要显示浏览数的地方插入如下代码即可:

<?php if(function_exists('bac_PostViews')) { echo bac_PostViews(get_the_ID()); }?>

以下部分于2013年2月15日更新

WordPress跳转页面兼顾SEO的方法

之前有尝试过多种WordPress跳转页面的制作方法,比如采用传递参数给$url,然后通过meta的refresh属性来做跳转,不过发现类似的方法会被google认为是诸如作弊之类的方式,对seo有较大影响,于是考虑通过WordPress的wp_redirect()来实现跳转,大致思路是这样的:如果该页面后缀带了诸如?url=usidc.net 之类的参数,则将该URL传递给wp_redirect()实现对应网址的跳转,反之则301永久跳转网站首页,代码实现如下:

<?php 
/**
 * Template Name: Redirect Page
 */
 $url=$_GET["url"];
?>
<?php if ($url) : ?>
<?php if (!preg_match('/^http:\/\//', $url)) $url = 'http://' . $url; ?>
<?php wp_redirect($url); ?>
<?php else : ?>
<?php
header("HTTP/1.1 301 Moved Permanently");
header("Location: ".get_bloginfo('url')."#301-redirect-from-redirect-without-url-page");
?>
<?php endif; ?>

然后后台新建跳转页面,并且绑定此模版,经测试该页面完美实现了WordPress跳转,当不带任何后缀参数的时候,实现了301跳转到网站首页的效果。

创建自定义的shortcode

打开模版的functions.php文件,插入以下代码:

function HelloWorldShortcode() {
    return '<p>Hello World!</p>';
}
add_shortcode('helloworld', 'HelloWorldShortcode');

然后在任意文章或者页面里边输入[helloworld]发布以后,即可调用该新建的shortcode。

关闭站内自我pingback功能

WordPress中有一个pingback的功能,当我们发表文章的时候,它就会自动向文章内的链接发送pingbacks。但令人困恼的是,它也会向自己的文章发送pingbacks。
很多朋友喜欢在写文章的时候插入一些内链,这就会导致wordpress向这些文章发送pingbacks。如果有好几个内链都指向同一篇文章,那么pingback也会发送好几次,这样会出现很多重复的pingbacks,所以关闭站内自我pingback功能势在必行,方法是打开模版里边的functions.php文件,插入如下代码:

<?php
/* No Self Pings */
//Pass the variable by reference to the function, so the function can modify the variable.
function no_self_ping (&$links) {
$home = get_option( 'home' );
foreach ( $links as $l => $link )
    //Find the position of the first occurrence of a substring in a string.
    //($a === $b) Identical operator. TRUE if $a is equal to $b, and they are of the same type.
    if ( 0 === strpos( $link, $home ) )
        //Unset the variable
        unset($links[$l]);
}
//Hooks the function to the specific action (pre_ping)
add_action( 'pre_ping', 'no_self_ping' );
?>

保存退出后即可。

2013年2月18日更新

关闭WordPress版本控制WP_POST_REVISIONS

WordPress 2.6版本引入了版本控制功能,对于多作者的博客网站来说这个版本控制非常实用,可以多人协同编辑同一篇文章并且确保不会丢失任何数据,但是对于大多数WordPress站点来说这个功能成了鸡肋,尤其是站点文章一旦几位数以后,每篇文章同时生成多篇的备份,可想而知数据库会因此变庞大多少,当然WordPress官方有公开声明过这些存在的备份版本并不会被前台所调用和索引,因此不会在任何程度上拖慢网站的载入,但是出于数据库不会越来越庞大的考虑,还是有必要关闭这个功能,或者至少做一个限制。

如果你想控制这个版本备份数为3,请打开wp-config.php文件,在位于 require_once(ABSPATH . 'wp-settings.php');之前输入如下代码:

define ('WP_POST_REVISIONS', 3);

又或者你想我一样根本用不着这个功能,那么就彻底关闭它吧,一样打开wp-config.php,在位于 require_once(ABSPATH . 'wp-settings.php');之前输入如下代码:

define ('WP_POST_REVISIONS', false);

那么对于那么多已经生成了的备份呢?好办,安装以下这个插件 Better Delete Revision ,当然这个插件版本有点旧了,不过别担心,因为这个插件实现的功能很简单就是执行了几个sql查询而已,在3.5版本上完美运行,再说仅仅是用来替代以下手工运行这些SQL而已,删除完以后直接删除这个插件就可以了。

自定义搜索框移除搜索按钮

默认的搜索框为常规的input加上一个submit按钮,中规中矩,界面也不容易定义到最佳的状态,兼容性更是要命,比如光是input和submit的对齐在各个浏览器里边的兼容性就得花很大的精力去处理,所以有必要去除后边这个submit按钮,仅仅保留一个input输入框,然后支持回车即启动搜索,代码如下:

<!--BEGIN #searchform-->
<form class="searchform" method="get" action="<?php bloginfo( 'url' ); ?>">
	<input class="search" name="s" onclick="this.value=''" type="text" value="Enter your search" tabindex="1" />
</form>
<!--END #searchform-->

2013年2月28日更新

关闭WordPress评论html的支持

在模版functions.php里加入如下代码可以关闭WordPress评论html的支持,这样可以一定程度上提高安全性:

    function disable_html_in_comments()
    {
        global $allowedtags;
        $allowedtags = array();
    }
    disable_html_in_comments();

是不是很简单,以上代码仅仅会对新添加的评论里边进行HTML代码移除,如果你还想进一步屏蔽所有评论包括以前老的评论,那么在functions.php里边加入如下代码:

    function disable_html_in_comments()
    {
        global $allowedtags;
        $allowedtags = array(
            'a' => array(
                'href' => array (),
                'title' => array ()
            )
        );
    }
    disable_html_in_comments();

2013年3月12日更新

去除WordPress插入图片的默认宽度和高度

通过WordPress后台媒体上传模块上传好图片以后,插入编辑框的时候,该图片会自动带上图片的真实width和height,这个功能很实用和方便,不过有时候我们可能不希望他带上这两个属性,很简单,只需要在functions.php里边插入如下代码即可:

add_filter( 'post_thumbnail_html', 'remove_width_attribute', 10 );
add_filter( 'image_send_to_editor', 'remove_width_attribute', 10 );

function remove_width_attribute( $html ) {
   $html = preg_replace( '/(width|height)="\d*"\s/', "", $html );
   return $html;
}

添加 class 到 next_posts_link 和 previous_posts_link 生成的链接里边

加入如下代码到functions.php以后,可以添加特定的class样式到由next_posts_link 和 previous_posts_link 生成的链接里边:

add_filter('next_posts_link_attributes', 'posts_link_attributes');
add_filter('previous_posts_link_attributes', 'posts_link_attributes');

function posts_link_attributes() {
    return 'class="styled-button"';
}

添加或者删除WordPress默认联系人字段

WordPress默认注册用户有E-mail, Website, AIM, Yahoo IM, Jabber / Google Talk等字段,需要删除或者添加个别字段可以在functions.php里边添加如下代码来实现:

function new_contactmethods( $contactmethods ) {
   $contactmethods['twitter'] = 'Twitter'; // Add Twitter
   $contactmethods['facebook'] = 'Facebook'; // Add Facebook
   unset($contactmethods['yim']); // Remove YIM
   unset($contactmethods['aim']); // Remove AIM
   unset($contactmethods['jabber']); // Remove Jabber

   return $contactmethods;
}

需要显示这些字段,可以加入如下代码:

$user_id = 1;
$key = 'twitter';
$single = true;

$user_twitter = get_user_meta( $user_id, $key, $single); 

echo $user_twitter; 

插入管理员才能看到的后台入口链接

插入如下代码即可:

<?php if (current_user_can("manage_options")) : ?>
       <a href="<?php echo bloginfo("siteurl") ?>/wp-admin/">Admin</a>
<?php endif; ?>

让WordPress媒体库支持SVG格式文件上传

functions.php插入如下代码可允许SVG格式的文件通过后台媒体库上传:

function cc_mime_types( $mimes ){
	$mimes['svg'] = 'image/svg+xml';
	return $mimes;
}
add_filter( 'upload_mimes', 'cc_mime_types' );

添加自定义样式到WordPress后台

添加如下代码到functions.php:

add_action('admin_head', 'my_custom_fonts');

function my_custom_fonts() {
  echo '<style>
    body, td, textarea, input, select {
      font-family: "Lucida Grande";
      font-size: 12px;
    } 
  </style>';
}

移除wp_nav_menu生成的li

加入如下代码到functions.php即可移除wp_nav_menu生成的li:

$menuParameters = array(
  'container'       => false,
  'echo'            => false,
  'items_wrap'      => '%3$s',
  'depth'           => 0,
);

echo strip_tags(wp_nav_menu( $menuParameters ), '<a>' );

删除WordPress默认Gallery嵌入的样式

在functions.php插入如下代码:

add_filter( 'use_default_gallery_style', '__return_false' );

获取文章里边的第一张图片

很多人会说WordPress不是有特色图片这个功能吗?干嘛舍近求远,的确对于新添加的文章可以直接通过设置特色图片来实现,但是对于大量的旧的没有设置过特色图片的文章呢,显然不可能一篇一篇的去手工更改,于是这个时候提取文章里边第一张图片作为封面缩略图就变得很实用了,方法就是在functions.php加入如下代码:

function catch_that_image() {
  global $post, $posts;
  $first_img = '';
  ob_start();
  ob_end_clean();
  $output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches);
  $first_img = $matches[1][0];

  if(empty($first_img)) {
    $first_img = "/path/to/default.png";
  }
  return $first_img;
}

在循环中使用方法如下:

if ( get_the_post_thumbnail($post_id) != '' ) {

  echo '<a href="'; the_permalink(); echo '" class="thumbnail-wrapper">';
   the_post_thumbnail();
  echo '</a>';

} else {

 echo '<a href="'; the_permalink(); echo '" class="thumbnail-wrapper">';
 echo '<img src="';
 echo catch_that_image();
 echo '" alt="" />';
 echo '</a>';

}

更多方法持续更新中,敬请期待……