终于准备开始写博客了,又懒得自己再去写一个,虽然简单,但是很烦。
说实话,很早以前就知道wordPress,也知道这货就是个“臃肿”的博客系统,但是可扩展性意外的强,抱着“反正博客访问量又不会很大,臃肿点也没关系”的想法安装了WP。
装完WP过后,发现并没有地方可以设置静态生成之内的东西,顶多只有伪静态,不知道是为啥,我用动态的方式,访问首页也好,内容页也好,页面请求都要等大概1s~2s才完成(单次页面请求, 不是完整加载), 用静态的方式就完全没问题!一次请求大概30ms,便开始琢磨,去插件中心找找静态的插件。
找了一圈,着实没找到合适的,其中一个甚至有点搞笑...生成了一个html静态文件,然而却是用php去访问这个html文件再输出...那和直接动态有啥区别?就是少一次数据库请求而已。
没办法,想着自己尝试写一个插件,不过介于并没有PHP开发经验,便开始看了下官方文档,意外的发现文档很全,毕竟有其他语言的开发经验,PHP代码还是很好上手的。
好了,废话到这里结束。
1.新建结构
按照官方文档所讲的, 第一件事应该是在wp-content/plugins
目录下新建一个文件夹作为插件的目录, 我这里起名叫wordpress_quick
, 同时进入文件夹, 新建同名php文件wordpress_quick.php
使用IDE或者notepad++打开文件, 不推荐用记事本, 否则会有UTF-8 BOM问题, 如果刚刚新建的PHP文件是使用右键-新建文本文档
的方式建立的话,最好使用notepad++打开,然后编码-使用UTF-8
, 否则可能PHP会直接报错。详情请百度PHP UTF-8 BOM
开始编辑wordpress_quick.php
文件, 写入最基本的插件信息
<?php
/*
Plugin Name: wordpress Quick
Plugin URI: http://URI_Of_Page_Describing_Plugin_and_Updates
Description: 只针对文章页面的静态文件简单生成插件
Version: 1.1
Author: xiaoC
Author URI: http://URI_Of_The_Plugin_Author作者地址
*/
?>
这时候就能在插件管理中看到你的插件了
2.了解WP的相关API
我这次的目的是在文章发布过后, 自动生成静态页面, 这里需要先确定几个问题
1.确定目录结构
2.确定生成时机
这里先确定目录结构, 我使用的是/article/%year%_%monthnum%_%day%/%post_id%.html
, 这个在设置-固定链接
里面修改, 修改完过后, 文章的URL应该为http://xiaoc.cn/article/2018_12_05/35.html
这样子
如果修改完过后, 发现打开是404了, 那么说明你的主机\VPS没有配置好URL重写相关的东西, 这里以我用的IIS为例, IIS需要单独下载URL重写的安装包进行安装后才能正常使用该功能。详情百度
IIS URL Rewrite
目录结构确定了, 接下来是生成的时机, 考虑了下, 至少需要在发布文章、修改文章、删除文章、评论通过、评论拒绝、评论列入垃圾列表、删除评论
这几个地方重新生成或者删除缓存文件。
好在这些东西都是有相应的动作;在WP中,基本上所有的操作均会触发相应的动作、触发器
,我们只需要注册相应的动作、触发器即可。
动作使用add_action
进行注册,这里我们需要用到这几个动作:
publish_post (文章的发布/修改/从回收站恢复时都会触发该动作)
wp_set_comment_status(所有评论相关的操作都会触发该动作)
wp_trash_post(文章被放入回收站时,会触发该动作)
构建代码
接下来就是构建PHP代码的阶段了, 我现在写这篇文章才真正接触PHP代码第三天, 基本上是PHP 0基础,所以写的烂代码不接受任何反驳!
由于是完全静态化,所以这里根据之前确定的目录结构,先写好创建多级目录的函数
//创建多级目录
function mkdirs($dir, $mode = 0777){
if (is_dir($dir) || @mkdir($dir, $mode)) return TRUE;
if (!mkdirs(dirname($dir), $mode)) return FALSE;
return @mkdir($dir, $mode);
}
然后是创建一个方法,用于生成静态文件,生成的方法比较特别...
//确定方法没有被创建
if( !function_exists('genArticleHtml') ){
function genArticleHtml($post_ID) {
//这个post_ID就是文章的ID
$date = get_post($post_ID) -> post_date; //通过ID获取发布时间, 这里为什么不直接date()呢???? 不要问我为什么, 我原本用的date("Y_m_d"),结果最后发现有时区问题,已经12月5号了,发布的文章还在2018_12_04文件夹下
$catime = strtotime($date);
$date = date("Y_m_d", $catime); //由于获取到的时间是时间戳,这里转换为格式化好的字符串格式
$dirPath = WP_CONTENT_DIR . "/../article/" . $date . "/"; //WP_CONTENT_DIR即为wp-content的绝对路径,由于没有找到获取根目录路径的方法,这里就用这种方式了
$fileName = $post_ID . ".html";
$filePath = $dirPath . $fileName;
mkdirs($dirPath, 0700);
if (file_exists($filePath))unlink($filePath); //这里需要先删除已经存在的缓存文件, 否则下面请求到的永远都是缓存数据
//接下来是生成的核心代码!!!!!
//你没看错,这是一个URL请求!
//我已经不想思考去构建一个页面了,所以这里直接就请求了动态的文章地址,然后直接把请求到的结果作为缓存文件!
//我把它称为“所见即所得”
$url= home_url() . '?p=' . $post_ID . '&time=' . date('Y_m_d');
$html = file_get_contents($url);
$myfile = fopen($filePath, "w");
fwrite($myfile, $html);
fclose($myfile);
}
}
好了,生成静态文件的方法完成了,接下来就是给这个方法注册上相应的动作
add_action('publish_post', 'genArticleHtml');
接下来就是激动人心的测试阶段,正常的话,在点击发布过后,WP根目录会自动生成article
文件夹,否则你可能需要检查下权限。
剩下的就是写另外2个方法:评论发生变动后更新和删除文章后清除缓存。
这里就直接贴所有代码了,相信你也能看懂(我都看得懂你敢说看不懂???)
<?php
/*
Plugin Name: wordpress Quick
Plugin URI: http://URI_Of_Page_Describing_Plugin_and_Updates
Description: 只针对文章页面的静态文件简单生成插件
Version: 1.1
Author: xiaoC
Author URI: http://URI_Of_The_Plugin_Author作者地址
*/
function mkdirs($dir, $mode = 0777){
if (is_dir($dir) || @mkdir($dir, $mode)) return TRUE;
if (!mkdirs(dirname($dir), $mode)) return FALSE;
return @mkdir($dir, $mode);
}
if( !function_exists('genArticleHtml') ){
function genArticleHtml($post_ID) {
$date = get_post($post_ID) -> post_date;
$catime = strtotime($date);
$date = date("Y_m_d", $catime);
$dirPath = WP_CONTENT_DIR . "/../article/" . $date . "/";
$fileName = $post_ID . ".html";
$filePath = $dirPath . $fileName;
mkdirs($dirPath, 0700);
if (file_exists($filePath))unlink($filePath);
$url= home_url() . '?p=' . $post_ID . '&time=' . date('Y_m_d');
$html = file_get_contents($url);
$myfile = fopen($filePath, "w");
fwrite($myfile, $html);
fclose($myfile);
}
}
if( !function_exists('genArticleHtmlForCommentID') ){
function genArticleHtmlForCommentID($comment_ID) {
$post_ID = get_comment($comment_ID) -> comment_post_ID;
genArticleHtml($post_ID);
}
}
if( !function_exists('delArticleHtml') ){
function delArticleHtml($post_ID) {
$date = get_post($id) -> post_modified;
$catime = strtotime($date);
$dirPath = "../article/" . date("Y_m_d", $catime) . "/";
$fileName = $post_ID . ".html";
$filePath = $dirPath . $fileName;
if (file_exists($filePath))unlink($filePath);
}
}
add_action('publish_post', 'genArticleHtml'); //发布/修改/从回收站恢复时重新生成缓存
add_action('wp_set_comment_status', 'genArticleHtmlForCommentID'); //评论发生变动时重新生成缓存
add_action('wp_trash_post', 'delArticleHtml'); //加入回收站时删除缓存
?>