首页 » 建站教程 » Blog教程 » Wordpress » 浏览内容
WordPress:将Blogroll 分为两栏(四)
经过前面几篇, 我们已经将想法作成了一个简单的插件, 先回顾一下吧:
将 Blogroll 分为两栏 (1)
将 Blogroll 分为两栏 (2)
将 Blogroll 分为两栏 (3)
插件的基本功能都实现了, 但它的不足也是显而易见的, 当链接超过 30 个的时候, widget 还是会变得很长. 可能你会想到限制显示数量并采用随机显示, 用公平的方式显示少量链接以达到界面的美观. 但很遗憾, 当你想找到某人的链接时, 可能刷新好几次页面都无法将你想要的显示出来. 所以我们还需要一个功能, 将所有链接都显示出来, 而我们显示所有时不需要重载页面. 翻页? 没必要吧. 我相信你不会有 100 个链接, 假如你有, 你一定会将他们进行分类的.
分析:
为了使用这个 “显示所有链接” 的功能, 我们追加一个叫 “show all” 的按钮. 大概你已经知道 show all 是干什么用的, 也知道在点击 show all 之后会发生些什么事情. 但在为插件添加 show all 之前, 我们还需要确定的几个问题:
WHEN? 什么时候显示 show all?
1. 插件是可以限制或者不限制显示数量的. 如果不限制显示数量, 那么所有链接都会被显示出来, 而无需显示 show all.
2. 如果限制显示数量了, 但限制的数量比当前链接总数还大, 那么所有的链接还是会被显示出来, 不需要显示 show all.
3. 可能有人觉得 show all 功能是多余的, 或者访客点击后会影响他的界面布局, 并不希望使用. 为此, 定义参数 navigator, 当 navigator 为 true 时才显示 show all.
也就是说, 当且仅当显示数量有限制, 限制的数量小于当前链接总数, 并且参数 navigator 为 true 的时候, show all 才会被显示出来.
WHERE? 在哪里显示显示 show all?
widget 的结构是 ul 里面放了很多个 li, 而每个 li 都是纵向排列的. 我们可以将 show all 放到最后一个 li 中. 而出于对用户习惯的考虑, 将它摆放在最后一个 li 的右边.
HOW? 点击 show all 后如何处理?
这个用文字很难解释清楚, 作了个不大规范的顺序图:
访客点击页面上的 show all 按钮, 浏览器显示 “Loading …”, 并从服务器获取包含全部链接的 widget 代码. 当响应返回的代码传输完毕, 将链接 widget 替换掉.
在访客点击按钮后, 浏览器接管了所有的工作, 浏览器会跟服务器打交道, 将生成的 widget 代码替换到原来的位置上.
编码:
追加 navigator 参数
navigator 默认为 ture, 即默认显示 show all 按钮.
// 默认参数
$defaults = array(
'columns' => 1, // 分栏数量
'limit' => 0, // 收藏数量
'category' => '', // 分类名称
'orderby' => 'name', // 排序对象
'order' => 'ASC', // 排序方法
'target' => 'false', // 是否应用 target 便签, true: 应用; false: 不应用
'navigator' => 'true' // 是否显示翻页的导航, true: 显示; false: 不显示
);
...
if ( $args['navigator'] != 'false' ) {
$args['navigator'] = 'true';
}
放置 show all 按钮
1. 判断是否需要显示
如果用户定义了限定长度, 将 limit 长度加 1, 判断是否在限定长度外还有更多的链接.
if ($args['limit'] > 0) {
// 准备多取一个, 以便获知是否有更多链接存在
$limit = ' LIMIT ' . ($args['limit'] + 1);
}
如果存在更多链接, 设置标志变量 $hasMore, 并去除最后那个多余的链接.
if ($args['limit'] > 0) {
// 如果能够获取多一个元组, 证明有更多链接存在
$hasMore = (count($links) - $args['limit'] > 0);
// 有更多链接存在时, 删除最后那个多余的
if ( $hasMore ) {
array_pop($links);
}
}
2. 根据前面的判断和 navigator 参数, 决定是否处理 show all
如果需要显示, 将它加到 widget 的最后. 按钮的 href 设为 javascript:void(0);, 以免用户直接看到参数信息. onclick 调用 JavaScript 方法 mlChange 对 widget 进行处理, 该方法将在本文的后面提到.
// 当需要显示 Show all 按钮时才显示这一栏
if ( $hasMore && $args['navigator'] == 'true' ) {
// Show all 按钮
$showAll = '<a href="javascript:void(0);" onclick="mlChange(\'' . get_bloginfo('wpurl') . '\',\'' . $argsf . '\',\'' . __('Loading', 'wp-multicollinks') . '\');">' . __('Show all »', 'wp-multicollinks') . '</a>';
$result .= '<li id="ml_nav"><div>' . $showAll . '<div></div></div></li>';
}
为 show all 定义样式.
.ml_showall {
float:right;
}
创建 AJAX 处理
勉强算是用了 AJAX, 但这是最简单的应用了. 如果你还没看过相关资料, 你可以到网上找个 AJAX 的 Hello World 来看一下, 只要弄清楚在不同的浏览器中如何获取 XMLHttp 对象和 AJAX 在不同浏览器中的生命周期就足够了.
这里使用 GET 方式处理, 当参数长度不超过 255 的时候, GET 有它一定的优势, 有兴趣可以百度一下或 Google it.
var mlXmlHttp;
var mlLoadingText;
function mlGetXmlHttpObject() {
var xmlHttp = null;
// Firefox, Opera 8.0+, Safari
try {
xmlHttp = new XMLHttpRequest();
// Internet Explorer
} catch(e) {
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
function mlChange(wpurl, args, loading) {
// 检验 XMLHttp 对象
mlXmlHttp = mlGetXmlHttpObject();
if (mlXmlHttp == null) {
alert ("Oop! Browser does not support HTTP Request.")
return;
}
// loading 参数不存在时使用 "Loading"
mlLoadingText = (loading == undefined) ? "Loading" : loading;
// 使用博客的地址
var url = wpurl;
// action 参数
url += "?action=ml_ajax";
// 插件参数
url += "&args=" + args;
mlXmlHttp.onreadystatechange = runMlChange;
// GET 方式处理
mlXmlHttp.open("GET", url, true);
mlXmlHttp.send(null);
}
function runMlChange() {
// show all 所在容器
var navigator = document.getElementById("ml_nav");
// widget 的容器
var parent = navigator.parentNode;
// 完成之前的所有状态
if (mlXmlHttp.readyState < 4) {
// 鼠标指针变为漏洞状
document.body.style.cursor = 'wait';
// 显示 "加载中 ..."
navigator.innerHTML = mlLoadingText + " ..."
// 响应完成后
} else if (mlXmlHttp.readyState == 4 || mlXmlHttp.readyState=="complete") {
// 替换 widget
parent.innerHTML = mlXmlHttp.responseText;
// 鼠标指针恢复原状
document.body.style.cursor = 'auto';
}
}
为什么 mlChange 方法需要 loading 这个参数?
因为通过本地化处理后, 加载时显示的字符串是不统一的, 而处理本地化不能在纯 JavaScript 代码中实现, 所以需要作为参数传进来.
在 wp-multicollinks.php 处理 head 的方法中追加应用引用 JavaScript 的方法.
echo "\n" . '<script type="text/javascript" src="' . get_bloginfo('wpurl') . '/wp-content/plugins/wp-multicollinks/wp-multicollinks.js"></script>';
在 core.php 处理 create_multicollinks 方法里格式化参数串, 因为 “=” 和 “&” 两个符号与 URL 中参数段的字符冲突, 所以要进行转化处理. 这里将 “=” 转为 “–”, “&” 号转为 “—”.
// AJAX 翻页时用的参数
$argsf = str_replace('=', '--', $args);
$argsf = str_replace('&', '---', $argsf);
定义 AJAX 请求响应的方法, 并它注册到 WordPress 系统中.
function ml_ajax() {
if( $_GET['action'] == 'ml_ajax' ) {
$argsf = $_GET["args"];
// 参数还原
$args = str_replace('---', '&', $argsf);
$args = str_replace('--', '=', $args);
// 如果 limit 参数存在, 将它换为未知参数, 即使它失效, 显示全部链接
if ( strstr($args, 'limit=') ) {
$args = str_replace('limit=', 'unknown=', $args);
// 如果参数不存在, 将它置为 0, 即显示全部链接
} else {
$args .= '&limit=0';
}
// 向 response 输出新的 widget
echo create_multicollinks( $args );
// 退出脚本处理
die();
}
}
add_action('init', 'ml_ajax');
总结:
经过几个环节, 这个插件已经基本完成了.
这并不是一个复杂且强大的插件, 但我觉得它还是有一定实用性的, 这正是我选择它作为教程的原因. 目前并不支持 widget, 我觉得 “如何让插件支持 Widget” 应该是另一个问题, 不应混在一起讨论, 以后有机会我会再介绍一下的.
下载:
还不是正式版, 有兴趣可以试用一下. (如无意外, 正式版中只会加入对 Widget 的支持) ![]()
下载请点: wp-multicollinks_0.4


评论 共0条 (RSS 2.0) 发表评论