WordPress最近遇到几个安全问题

1)Froget Password Disable
据说会被Hack, 查找了一下,可以通过filter取消forget password的功能。

function remove_lostpassword_text ( $text ) {
if ($text == 'Lost your password?'){$text = '';}
return $text;
}
add_filter( 'gettext', 'remove_lostpassword_text' );


function disable_password_reset() {
return false;
}
add_filter ( 'allow_password_reset', 'disable_password_reset' );

2) 删除不需要的主题
前一阵子我的一个网站被入侵,就是wordpress默认自带的主题Twenty Eleven. Google了一下,发现是个很典型的问题,所以现在新安装的wordpress就删除这些没用的主题吧。

 

WP-Douban-Post发布后记

距离WP-Douban-Post发布已经有差不多两个月了。总想写点什么总结一下。

缘由

说起来初衷很简单。我的博客可以同步到twitter,新浪,就差同步到豆瓣上了。受不了每次人肉同步的繁琐,又没找到合适的现成wordpress插件,又打算学习一下Oauth+Douban API + WordPress Plugin的各种技术,袖子管一卷咱就干了起来。

过程

前后大概花了一周的业余时间,大概按照如下的步骤走了一遍,总算是客服了重重难关,完成了这个插件。
1)Wordpress Hello World Plugin (了解Wordpress插件结构)
2)Wordpress Option Page(了解添加配置选项,存取数据库,添加事件响应)
3)Douban Oauth (Douban Zend Client太复杂,只好自己用php oauth library。自己拼接header,测试MD5验证,多谢Douban API支持,这部分是最艰辛的)
4)Douban API 调用(真正开始调用API,发送自己的记录到我说)
5)WP-Douban-Post (拼装完成,达达达搭)

推广

说是推广其实是抬举了自己。自己作了好用当然是想广而告之显摆一下。第一个想到的自然就是wordpress.org插件库。如果可以在Plugins里面搜索到自己的名字,想想就威风。
提交开发者申请,编写README,提交代码。所有的步骤都有清楚的指南。Wordpress.org基于SVN的发布系统让我大开眼界,收益非浅。
1)通过README提取插件信息,例如作者信息,安装指南,Q&A,对开发人员和wordpress.org都是方便清楚。
2)建议开发者拉branch进行发布,通过README元信息指定发布的具体branch.通过这样的最佳实践直接帮助开发者分清了发布和开发的代码。清晰明了。

然后就是更新豆瓣应用信息,在豆瓣API小组发贴庆祝。然后就是每天刷屏期待了。。。这就是我做的推广-,-。大概的情形趋势图上都清清楚楚。
1)2011-01-19,推荐给了几个用豆瓣也用Wordpress的朋友,小推销了一把,迎来了下载高峰。
2)2011-01-21 to 2011-02-12,春节期间,下载量逐渐走低。。。。
3)2011-02-13 to 2011-02-20,春节结束,赢了小小的反弹。。。。
4)2011-02-21 to 2011-03-20, 大概可以看出周末基本没有下载,工作日偶尔有人。。
5)2011-03-25, 豆瓣有了应用小站,很荣幸被发布了出来,还被表扬了^@^,也迎来了之后小小的高峰。。。

没有什么特别的期待,有人用,觉得有用大概就是对我最大的夸奖了。呵呵。欢迎提意见给我。

后记

1)听说豆瓣九点可以自动收录wordpress,我那叫一个后悔啊。新手不会玩豆瓣,sigh。
2)想要php调用douban Oauth的同学,可以参考我在wordpress.org上的代码,这可是汗水和泪水啊-,-
3)wordpress.org的缺点也很明显,一定需要wordpress.com的账号才能rate和vote,这导致基本没人回来给意见。

WordPress.org 地址

http://wordpress.org/extend/plugins/wp-douban-post/stats/

Douban应用小站 地址

http://site.douban.com/widget/notes/2324209/note/141570144/

WP-Douban-Post Stats 2011-03-26

WP-Douban-Post Stats 2011-03-26

 

WordPress Ajax Widget开发

本篇文章是紧接上一篇WordPress 2.8+ Widget 插件开发.
自己开发得一个小工具 WP Dict需要调用服务器端方法查询单词,但是个人觉得页面跳转的用户体验不好,所以小研究了一把ajax的实现方法而且试验成功,特此记录。

注册服务端方法


function wp_dict_request_handler() {
}
add_action('init', 'wp_dict_request_handler');

比想象的更加简单,Wordpress可以通过add_action注册自己的服务器端方法,所有页面均可调用。唯一需要注意的是方法名需要保证唯一。

注册jquery

在Widget类的构造方法中添加如下语句。

// Load jQuery
wp_enqueue_script('jquery');

获得Widget ID

在widget()方法extract方法后天添加如下语句。

function widget( $args, $instance ) {
extract( $args );
// Get the div id of the widget
$widgetid = $args['widget_id'];
。。。
}

Ajax实现

在Widget的显示内容部分($after_title,$after_widget之间)添加ajax调用代码。

echo $after_title;
?>
<script type="text/javascript">
jQuery(document).ready(function($){
$("#wp_dict_submit").click(function(){
$.ajax({
type : "GET",
url : "index.php",
data : { mywidget_request : "wp_dict_request_handler",
query : $("#wp_dict_query").val() },
success : function(response) {
// The server has finished executing PHP and has returned something,
// so display it!
$("#wp_dict_result").html(response);
}
});
});
});
</script>
<?php

/* After widget (defined by themes). */
echo $after_widget;

基本就是jQuery调用ajax的典型用法。不过这里有几点针对wordpress的说明

  • url参数其实可以是任意有效的php路径。
  • mywidget_request配置的就是之前注册的方法名。
  • mywidget_request之后的都是自定义的参数,这里我需要一个query的单词名。

最后

按照普通Widget的要求,把widget添加之后,就可以在页面看到并使用了。相当方便。

遗留问题

WP Super Cache会把页面内容转化成静态HTML,所以Ajax会破坏这个机制。参考资料中另外一篇文章,不过还没有时间学习。

参考资料

AJAX-ifying WordPress Widgets
Make Any Plugin Work with WP Super Cache

 

WordPress 2.8+ Widget 插件开发

WordPress 2.8.0之后的版本对Widget提供了一套详细的API规范。貌似和水煮鱼团队的范例有很大区别。

加载Widget


<?php

/* Add our function to the widgets_init hook. */
add_action( 'widgets_init', 'example_load_widgets' );

/* Function that registers our widget. */
function example_load_widgets() {
register_widget( 'Example_Widget' );
}

Wordpress 2.8以上的版本中,widgets_init事件会在wordpress注册默认widgets之后被触发。Example_Widget是具体实现widget的类名。

配置你的Widget


function Example_Widget() {
/* Widget settings. */
$widget_ops = array( 'classname' => 'example', 'description' => 'An example widget that displays a person\'s name and sex.' );

/* Widget control settings. */
$control_ops = array( 'width' => 300, 'height' => 350, 'id_base' => 'example-widget' );

/* Create the widget. */
$this->WP_Widget( 'example-widget', 'Example Widget', $widget_ops, $control_ops );
}

这里主要配置的Widget的一些基本信息,例如标识符,描述,以及大小等信息。

显示你的Widget


function widget( $args, $instance ) {
extract( $args );

/* User-selected settings. */
$title = apply_filters('widget_title', $instance['title'] );
$name = $instance['name'];
$sex = $instance['sex'];
$show_sex = isset( $instance['show_sex'] ) ? $instance['show_sex'] : false;

/* Before widget (defined by themes). */
echo $before_widget;

/* Title of widget (before and after defined by themes). */
if ( $title )
echo $before_title . $title . $after_title;

/* Display name from widget settings. */
if ( $name )
echo '<p>Hello. My name is' . $name . '.</p>';

/* Show sex. */
if ( $show_sex )
echo '<p>I am a ' . $sex . '.</p>';

/* After widget (defined by themes). */
echo $after_widget;
}

Wordpress 2.8以上的版本中,规定了function widget( $args, $instance )这个接口。这个接口专门用来实现widget的显示内容的。其中extract( $args );是标准用法,只需要添加就可以了。除此之外Wordpress还提供了四个标准变量用来区分显示的阶段:$before_widget, $after_widget, $before_title, and $after_title。最后$instance是用来获取Widget本身实例属性的。Widget实例属性的操作会在后面提到。

Widget配置页面

在Widgets页面中添加了某个Widget之后可以配置该Widget的实例属性。

function form( $instance ) {

/* Set up some default widget settings. */
$defaults = array( 'title' => 'Example', 'name' => 'John Doe', 'sex' => 'male', 'show_sex' => true );
$instance = wp_parse_args( (array) $instance, $defaults ); ?>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>">Title:</label>
<input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" style="width:100%;" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'name' ); ?>">Your Name:</label>
<input id="<?php echo $this->get_field_id( 'name' ); ?>" name="<?php echo $this->get_field_name( 'name' ); ?>" value="<?php echo $instance['name']; ?>" style="width:100%;" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'sex' ); ?>">Sex:</label>
<select id="<?php echo $this->get_field_id( 'sex' ); ?>" name="<?php echo $this->get_field_name( 'sex' ); ?>" class="widefat" style="width:100%;">
<option <?php if ( 'male' == $instance['format'] ) echo 'selected="selected"'; ?>>male</option>
<option <?php if ( 'female' == $instance['format'] ) echo 'selected="selected"'; ?>>female</option>

</p>
<p>
<input class="checkbox" type="checkbox" <?php checked( $instance['show_sex'], true ); ?> id="<?php echo $this->get_field_id( 'show_sex' ); ?>" name="<?php echo $this->get_field_name( 'show_sex' ); ?>" />
<label for="<?php echo $this->get_field_id( 'show_sex' ); ?>">Display sex publicly?</label>
</p>
<?php
}
?>

Wordpress提供了标准接口function form( $instance ) 用来显示该配置页面的内容。方法中主要包含两个部分。

  • 第一部分配置了所有实例属性的默认值。
  • 第二个部分是配置页面的显示内容。

更新Widget实例属性


function update( $new_instance, $old_instance ) {
$instance = $old_instance;

/* Strip tags (if needed) and update the widget settings. */
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['name'] = strip_tags( $new_instance['name'] );
$instance['sex'] = $new_instance['sex'];
$instance['show_sex'] = $new_instance['show_sex'];

return $instance;
}

Wordpress提供了标准接口function update( $new_instance, $old_instance )用来处理实例属性的更新。更新的内容直接设置在$instance中就可以了。不需要直接操作数据库。

总结

这就是所有开发正常widget所需要了解的内容了。快动手吧。

参考资料

http://codex.wordpress.org/Widgets_API
The complete guide to creating widgets in WordPress 2.8

 

WP-Dict version 1.0.0 released

=== Plugin Name ===
Contributors: windlx
Donate link: http://blog.tech4k.com/
Tags: dict, translation, wp-dict
Requires at least: 2.8
Tested up to: 3.0.4
Stable tag: 1.0.0

Widget Plugin. A widget could help to translate between English and Chinese.Take advantage of the API from dict.cn.

== Description ==

Widget Plugin. A widget could help to translate between English and Chinese.Take advantage of the API from dict.cn. Implimented by Ajax.

== Installation ==

  1. Unzip wp-douban-post to the ‘/wp-content/plugins/’ directory
  2. Activate the plugin through the ‘Plugins’ menu in WordPress
  3. Add ‘WP Dict’ in through the ‘Widgets’ menu in WordPress
  4. Any problem, please contact windlx from my blog.
  1. 解压后将文件上传到’/wp-content/plugins/’目录
  2. 在插件中激活wp-dict
  3. 在Widget中添加WP-Dict
  4. 如有问题,请通过我的博客windlx联系我

== Frequently Asked Questions ==

= What do I need before the installation? =

You don’t need anything. Dict.cn API is open to everyone.

= Why I can’t see WP Dict Widget from my ‘Widgets’? =

There is a build issue before 2011/01/23. If you used to install it, please delete the plugin and reinstall it. Everything will be fine.

== Screenshots ==

1. WP-Dict

== Changelog ==

= 1.0.0 =
Get the Translation of the words by Ajax.

== Upgrade Notice ==

= 1.0.0 =
Basic Version.

 

WP-Douban-Post 1.0.0 Released

=== Plugin Name ===
Contributors: windlx
Donate link: http://blog.tech4k.com/
Tags: douban, post, douban-post
Requires at least: 2.0
Tested up to: 3.0.4
Stable tag: 1.0.0

Send one message to your douban broadcasting mysaying when you publish the post.

== Description ==

Send one message to your douban broadcasting mysaying when you publish the post.

== Installation ==

  1. Unzip wp-douban-post to the ‘/wp-content/plugins/’ directory
  2. Activate the plugin through the ‘Plugins’ menu in WordPress
  3. Visit WP Douban Post Options
  4. Click the button “Get Access Token”, it will open a new window for you to authorize WP Douban Post.
  5. Close the window after the authorization is done.
  6. The option page will refresh automatically. If everything works fine, you can see you Douban ID and access token.
  7. Next time when you publish the post, there will be one message sent to your Douban Broadcasting Mysaying.
  8. Any problem, please contact @windlx at Twitter.
  1. 解压后将文件上传到’/wp-content/plugins/’目录
  2. 在插件中激活wp-douban-post
  3. 访问WP Douban Post选项页
  4. 点击Get Access Token按钮, 会打开豆瓣网页,要求你对WP Douban Post应用进行授权。
  5. 授权结束后,点击Close按钮,关闭返回页面。
  6. 选项页会自动刷新,如果一切正常,页面会显示你的Douban ID, Acces Token和Access Token Secret.
  7. 如有问题,请通过新浪微博@windlx联系我

== Frequently Asked Questions ==

= What do I need before the installation? =

You need to have a Douban ID for authorization.

== Screenshots ==

1. WP-Douban-Post.

== Changelog ==

= 1.0.0 =
* Configuration Page in WordPress Admin
* Generate Douban Access Token
* Send one message to user’s Douban Broadcasting Mysaying when publish the post.

== Upgrade Notice ==

= 1.0.0 =
Basic Version.

参考插件
WP-DoubanShow
Douban Connect
Twitter Tools

 

WordPress插件开发入门心得

WordPress用了一段时间,有了一些自己的需求。于是硬着头皮就自己做起了插件。眼见0.1.0总算要release了。把这一周的新的体会记录下来。当作是总结。

插件入门

强烈推荐水煮鱼团队的系列文章(见下面的参考),第一篇非常清楚的描述了Wordpress 插件入门的步骤。其实就是一个附带规定格式备注的php。还能更容易么?

/*
Plugin Name: XXXXXX
Plugin URI: XXXXXXXX
Description: XXXXXXXXXXXXXXXXX
Version: XXXXXXXX
Author: XXXXXXXX
Author URI: XXXXXXXX
*/

把上面的信息保存到php文件中,把php文件放到wp-content/plugins//下。你的插件就可以在Plugins列表中看到了。说实话,这一步超酷的,这也是吸引我做下去的关键一步。

Action and Filter

WordPress提供了丰富的API供开发者调用。其中核心的概念就是Action和Filter。
Action指的就是事件,发布博客,进入Admin页面,激活插件,这些都是action。Wordpress可以让开发者将这些action与自己实现的方法关联起来,从而在事件激发的时候能够完成自己的功能。
Filter指的就是过滤器。Wordpress可以让开发者通过注册filter的方式修改Wordpress地默认表现。例如自定义短链接,格式化标题等等。
参考资料中包含了Action和Filter的具体列表。

后台选项页

没想到如此的简单,三步就能完成。
一,注册Action,用户进入Admin页面的时候需要调用的方法。

add_action('admin_menu', 'plugin_name_options_admin');

二,用户进入Admin页面的时候需要具体显示的文字,注册打开选项页时调用的方法。

//Set option page for the plugin
function plugin_name_options_admin(){
add_options_page('wp_douban_post', __('XXXXXXXX, 'xxxxxxxxxxxxxx'), 5,
__FILE__, 'plugin_name_options');
}

三,实现打开选项页时调用的方法。

function wp_douban_post_options()
{
//页面提交需要实现的功能

if($_POST['update_doubanshow_option'])
{
$wp_doubanshow_option_saved = get_option("wp_doubanshow_option");
$wp_doubanshow_option = array (
"userid" => $_POST['userid'],
"apikey" => $_POST['apikey'],
"profile" => $_POST['profile'],
"collection" => $_POST['collection'],
"recommendations" => $_POST['recommendations'],
"powerby" => $_POST['powerby']
);
if ($wp_doubanshow_option_saved != $wp_doubanshow_option)
{
if(!update_option("wp_doubanshow_option",$wp_doubanshow_option))
{
$message = __('Update Failed', 'wp-doubanshow');
}
}
update_doubanshow();

echo $message ;
}
//这部分是显示的html
<div class=wrap>
<form method="post" action="">
<h2><?php _e('DoubanShow Options', 'wp-doubanshow'); ?></h2>
<fieldset name="wp_basic_options" class="options">
<table>
<tr>
<td valign="top" align="right"><?php _e('Douban ID:', 'wp-doubanshow'); ?></td>
<td><input type="text" name="userid" value="<?php echo $userID; ?>" /> <?php _e('Enter your Douban ID.', 'wp-doubanshow'); ?></td>
</tr>
</table>
</fieldset>
<p class="submit"><input type="submit" name="update_doubanshow_option" value="Update Options »" /></p>
</form>
</div>
}

比我想想的容易很多。轻松过了这关。

参数数据库保存

WordPress提供了get_option()和 c()两个方法,可以方便的保存选项页中的参数。

get_option


<?php echo get_option( $show, $default ); ?>
$show
(string) (required) Name of the option to retrieve. A list of valid default options can be found at the Option Reference.
$default
(mixed) (optional) The default value to return if no value is returned (ie. the option is not in the database).

update_option


<?php update_option( $option_name, $newvalue ); ?>
option_name
(string) (required) Name of the option to update. A list of valid default options to update can be found at the Option Reference.
newvalue
(mixed) (required) The NEW value for this option name. This value can be a string, an array, an object or a serialized value.

需要注意的是所有插件的option都保存在一张表,所以为了避免冲突,option名字需要格外当心。

后台定时任务

WordPress提供了简单机制使得插件可以完成定时更新之类的功能。示例如下。

//自定义Action,并注册相关function
add_action('my_event', 'my_function');

//定义Action的出发频率
if (!wp_next_scheduled('my_event')) {
wp_schedule_event( time(), 'hourly', 'my_event' );
}

//当插件被停止时候,移除相关Function
function update_deactivation(){
wp_clear_scheduled_hook('my_event');
}

register_deactivation_hook(basename(__FILE__),' update_deactivation');

总结

总之就是动手做,其乐无穷啊~~~~~~~~~

参考资料

WordPress Plugin API
Write a Plugin
Plugin API/Action Reference
Plugin API/Filter Reference
自己动手写 WordPress 插件
用 Eclipse PDT 开发一个 WordPress 插件

 

用Google Custom Engine替代WordPress默认搜索

创建自己的Google Custom Engine

Step 1

访问http://www.google.com/coop/cse/?hl=zh-CN,选择”创建自定义搜索“.

Step 2

按照提示定义自己的搜索引擎语言和网站范围.由于主要使用自己Blog的搜索,所以我选择的是”仅我选择的网站“.然后在”要搜索的网站“中填入自己网站的地址.

Step 3

完成创建后就可以在”我创建的搜索引擎“中看到你刚才创建的自定义搜索了.点击”控制面板“进行下一步的配置.

Step 4

选择”编制索引“,将你网站的sitemap导入你的自定义搜索,编制索引可能需要花一些时间,所以一开始你的搜索是不会有任何结果的.

Step 5

选择”代码“,点击”在您的网站上托管搜索结果“,”iframe“.获得”搜索框代码“和”搜索结果代码“.

这样,你的自定义搜索就算创建完成了.你还可以通过”优化”,”外观”来完善你的自定义搜索.

修改Wordpress默认搜索

主要修改的就是你当前theme中的searchform.php和search.php.你可以手动修改也可以通过Appearance->Editor来修改.

Step 1 修改searchform.php.

这是我修改后的searchform.php.

<form method=”get” id=”cse-search-box” action=”<?php bloginfo(‘url’); ?>/”>
<label class=”hidden” for=”s”><?php _e(‘Search for:’); ?></label>
<div><input type=”text” value=”<?php the_search_query(); ?>” name=”q” id=”q” size=”31″ />
<input type=”submit” id=”searchsubmit” value=”Search” />
<input type=”hidden” name=”cx” value=”xxxxxxxxxxxxxxxxxxxxxxxxxxxx” />
<input type=”hidden” name=”cof” value=”FORID:xx” />
<input type=”hidden” name=”ie” value=”UTF-8″ />
<input type=”hidden” name=”s” value=”Search”/>
<input type=”hidden” name=submit” value=””/>

</div>
</form>

请注意黑色的修改部分,具体的修改根据theme也会略有不同。主要都是根据”搜索框代码“进行的修改。比较注意的是需要增加”s=Search”,”submit=”这两个hidden,这是为了让wordpress能够跳转到search.php.

Step 2 修改search.php.

我选择的是两栏式的Theme,然后希望搜索结果显示在页面的左中,所以将search.php修改成如下格式.

<?php get_header(); ?>
<div id=”main”>
<div id=”content” class=”narrowcolumn”>
<!–               Google Search Result Code                    –>
<!–               Google Search Result Code                    –>
</div>
<?php get_sidebar(); ?>
</div>
<?php get_footer(); ?>

将之前获得的”搜索结果代码“贴在指定的地方就可以了。如果你不想要sidebar,也可以在这个基础上作自己的修改。

Tip 1:

貌似http://www.google.com/coop/cse/http://www.google.com/coop/cse/?hl=zh-CN的数据同步有一些问题.一开始在英文版下注册的Custom Engine在中文版里面看不到.考虑到最后需要中文效果,所以我还是选择在后者创建自己的搜索引擎.

Tip 2:

我的”搜索框代码”不知道为什么缺少下面这段JS调用,一开始尝试了半天也没有办法起作用.创建其他新的自定义搜索就没有问题,真实奇怪.Anyway,如果你的搜索框无法正常跳转,看看是不是这个问题.

<script type=”text/javascript” src=”http://www.google.com/coop/cse/brand?form=cse-search-box&lang=zh-Hans”></script>

Tip 3:

通过”控制面板“->”赚钱“.你可以通过到你的Adsense帐户创建”搜索广告”,在你搜索结果页中显示Google Adsense广告,赚点小钱.

具体就不细说了,有问题可以联系我.

 

“咻~咻~咻~~~我是风”博客正式上线啦!

好不容易通过了verrification,正式在HostMonster安了家。

安装上Wordpress,google了半天plugins,又挑选了半天themes.

终于后的终于,”咻~咻~咻~~~我是风”正式上线啦!

 

VPS攒机经历(4)

1添加ucenter
2添加uchome
3添加discuz
4添加ecshop
5添加wordpress
 
6添加ruby openssl支持
yum install openssl-devel
cd ruby/ext/
ruby ./extconf.rb
make && make install
 
7添加应用
heroku clone comparefriends
问题
7.1
No ssh public key found in /root/.ssh/id_[rd]sa.pub.  You may want to specify the full path to the keyfile.
解决
ssh-keygen -t rsa
 
8gem install rmagick
9安装应用
问题
9.1
/usr/local/ruby/lib/ruby/1.8/irb/completion.rb:10:in `require’: no such file to load — readline (LoadError)
解决
yum install readline-devel
cd ruby/ext/readline
ruby ./extconf.rb
make && make install
9.2
中文乱码
解决
mysql设置默认字符集
修改/etc/my.cnf
在[client]和[mysqld]中添加
default-character-set=utf8
 
 

 

无觅相关文章插件,快速提升流量