因为做了一个统计图的关系,所以用了下highcarts的图表,这是个很棒的的东西,只是不太好直接在wordpress中引用。
如果要写一段JS代码肯定不会有多少人愿意,所以,直接用了一个短标签来实现,看起来还是很酷的。
主要实现了两个功能,其一就是加载外部数据的配置文件,其二就是直接将配置文件写在短标签的参数中,当然这个中间也或多或少遇到了些许小坑,还好我够聪明解决了,不得不赞美下自己。先看看效果,用的是官方的例子。
highcarts 官方天气数据
图表加载中....
整个表格加载的步骤,不用任何JS代码,当然这里将需要的js配置文件base64压缩了一下,相对来说还是略有不同的。
[charts name="highcarts 官方天气数据" cfg="eyJ0aXRsZSI6eyJ0ZXh0IjoiTW9udGhseSBBdmVyYWdlIFRlbXBlcmF0dXJlIiwieCI6LTIwfSwic3VidGl0bGUiOnsidGV4dCI6IlNvdXJjZTogV29ybGRDbGltYXRlLmNvbSIsIngiOi0yMH0sInhBeGlzIjp7ImNhdGVnb3JpZXMiOlsiSmFuIiwiRmViIiwiTWFyIiwiQXByIiwiTWF5IiwiSnVuIiwiSnVsIiwiQXVnIiwiU2VwIiwiT2N0IiwiTm92IiwiRGVjIl19LCJ5QXhpcyI6eyJ0aXRsZSI6eyJ0ZXh0IjoiVGVtcGVyYXR1cmUgKMKwQykifSwicGxvdExpbmVzIjpbeyJ2YWx1ZSI6MCwid2lkdGgiOjEsImNvbG9yIjoiIzgwODA4MCJ9XX0sInRvb2x0aXAiOnsidmFsdWVTdWZmaXgiOiLCsEMifSwibGVnZW5kIjp7ImxheW91dCI6InZlcnRpY2FsIiwiYWxpZ24iOiJyaWdodCIsInZlcnRpY2FsQWxpZ24iOiJtaWRkbGUiLCJib3JkZXJXaWR0aCI6MH0sInNlcmllcyI6W3sibmFtZSI6IlRva3lvIiwiZGF0YSI6WzcsNi45LDkuNSwxNC41LDE4LjIsMjEuNSwyNS4yLDI2LjUsMjMuMywxOC4zLDEzLjksOS42XX0seyJuYW1lIjoiTmV3IFlvcmsiLCJkYXRhIjpbLTAuMiwwLjgsNS43LDExLjMsMTcsMjIsMjQuOCwyNC4xLDIwLjEsMTQuMSw4LjYsMi41XX0seyJuYW1lIjoiQmVybGluIiwiZGF0YSI6Wy0wLjksMC42LDMuNSw4LjQsMTMuNSwxNywxOC42LDE3LjksMTQuMyw5LDMuOSwxXX0seyJuYW1lIjoiTG9uZG9uIiwiZGF0YSI6WzMuOSw0LjIsNS43LDguNSwxMS45LDE1LjIsMTcsMTYuNiwxNC4yLDEwLjMsNi42LDQuOF19XX0"][/charts]
如何实现这样的效果呢,其一你得去http://www.highcharts.com/download下载个合适的版本,然后放在指定的地方,并且在自己的系统中添加几段这样的代码。
/**
* 添加图表的短标签
* @param array $attr
* @return string
*/
function wpr_charts($attr, $content){
/**
* @var string $name 图表名称
* @var string $width DIV宽度
* @var string $height DIV 高度
* @var string $style 自定义样式
* @var string $src 配置文件加载地址路径
* @var string $cfg Base64编码后的配置文件,需base64_decode然后json_decode,优先级比$src高
*/
$hash = md5(serialize($attr));//计算一个唯一值
extract(shortcode_atts(array(
"name" => '',
"width" => '100%',
"height" => '',
"style" => '',
"src" => '',
"cfg" => ""
), $attr));
$name_p = trim(htmlspecialchars($name));
$name_p = !empty($name_p) ? "<p class='charts_title'><strong>{$name_p}</strong></p>" : "";
$height = is_numeric($height) ? "{$height}px" : $height;
$height = empty($height) ? "" : ";height:{$height}";
if(!is_single() && !is_paged()){
return empty($name) ? $content : $name;
}
static $index = 0;
if(!isset($GLOBALS['wpr_charts_map'])){
//如果未定义图表数据则创建一个全局对象
$GLOBALS['wpr_charts_map'] = [];
}
if(!empty($content)){
$content = "<p>{$content}</p>";
}
$html = <<<HTML
<div class="charts_box" style="{$style}">
<div class="charts_show ChartsContainer-{$hash}" style="width: {$width}{$height}">
{$name_p}
<p class="charts_loading">图表加载中....</p>
{$content}
</div>
</div>
HTML;
if($index == 0){
//初次加载,导入js文件,并添加底部执行文件
wp_enqueue_script('highcharts', get_template_directory_uri() . '/js/highcharts.js', array('jquery'), CDN_VERSION_JS, true);
add_action('wp_footer', function (){
/**
* @var array $wpr_charts_map
*/
global $wpr_charts_map;
if(empty($wpr_charts_map)){
return;
}
$code = "";
foreach($wpr_charts_map as $hash => $data){
$src = $data['src'];
$cfg = $data['cfg'];
if(!empty($cfg)){
//使用自定义的配置文件
$cfg = base64_decode($data['cfg']);
$_code = <<<js
$('.ChartsContainer-{$hash}').each(function(i,elem){
$(elem).highcharts({$cfg});
});
js;
} else{
$_code = <<<js
$.get("{$src}", function(cfg){
$(".ChartsContainer-{$hash}").each(function(i,elem){
$(elem).highcharts(cfg);
});
});
js;
}
if(empty($src) && empty($data['cfg'])){
$_code = <<<js
$(".ChartsContainer-{$hash}").html("<p style='color:red'>配置错误。</p>");
js;
}
$code .= "if($(".ChartsContainer-{$hash}").length>0){\n{$_code}\n}";
}
echo "<script type='text/javascript'>jQuery(function($){
{$code}
});</script>";
});
}
if(!isset($GLOBALS['wpr_charts_map'][$hash])){
//如果重复了,说明被多次解析。取最后一次
$GLOBALS['wpr_charts_map'][$hash] = array(
'src' => $src,
'cfg' => $cfg
);
}
$index++;
return $html;
}
//注册下短标签
add_shortcode("charts", "wpr_charts");
* 添加图表的短标签
* @param array $attr
* @return string
*/
function wpr_charts($attr, $content){
/**
* @var string $name 图表名称
* @var string $width DIV宽度
* @var string $height DIV 高度
* @var string $style 自定义样式
* @var string $src 配置文件加载地址路径
* @var string $cfg Base64编码后的配置文件,需base64_decode然后json_decode,优先级比$src高
*/
$hash = md5(serialize($attr));//计算一个唯一值
extract(shortcode_atts(array(
"name" => '',
"width" => '100%',
"height" => '',
"style" => '',
"src" => '',
"cfg" => ""
), $attr));
$name_p = trim(htmlspecialchars($name));
$name_p = !empty($name_p) ? "<p class='charts_title'><strong>{$name_p}</strong></p>" : "";
$height = is_numeric($height) ? "{$height}px" : $height;
$height = empty($height) ? "" : ";height:{$height}";
if(!is_single() && !is_paged()){
return empty($name) ? $content : $name;
}
static $index = 0;
if(!isset($GLOBALS['wpr_charts_map'])){
//如果未定义图表数据则创建一个全局对象
$GLOBALS['wpr_charts_map'] = [];
}
if(!empty($content)){
$content = "<p>{$content}</p>";
}
$html = <<<HTML
<div class="charts_box" style="{$style}">
<div class="charts_show ChartsContainer-{$hash}" style="width: {$width}{$height}">
{$name_p}
<p class="charts_loading">图表加载中....</p>
{$content}
</div>
</div>
HTML;
if($index == 0){
//初次加载,导入js文件,并添加底部执行文件
wp_enqueue_script('highcharts', get_template_directory_uri() . '/js/highcharts.js', array('jquery'), CDN_VERSION_JS, true);
add_action('wp_footer', function (){
/**
* @var array $wpr_charts_map
*/
global $wpr_charts_map;
if(empty($wpr_charts_map)){
return;
}
$code = "";
foreach($wpr_charts_map as $hash => $data){
$src = $data['src'];
$cfg = $data['cfg'];
if(!empty($cfg)){
//使用自定义的配置文件
$cfg = base64_decode($data['cfg']);
$_code = <<<js
$('.ChartsContainer-{$hash}').each(function(i,elem){
$(elem).highcharts({$cfg});
});
js;
} else{
$_code = <<<js
$.get("{$src}", function(cfg){
$(".ChartsContainer-{$hash}").each(function(i,elem){
$(elem).highcharts(cfg);
});
});
js;
}
if(empty($src) && empty($data['cfg'])){
$_code = <<<js
$(".ChartsContainer-{$hash}").html("<p style='color:red'>配置错误。</p>");
js;
}
$code .= "if($(".ChartsContainer-{$hash}").length>0){\n{$_code}\n}";
}
echo "<script type='text/javascript'>jQuery(function($){
{$code}
});</script>";
});
}
if(!isset($GLOBALS['wpr_charts_map'][$hash])){
//如果重复了,说明被多次解析。取最后一次
$GLOBALS['wpr_charts_map'][$hash] = array(
'src' => $src,
'cfg' => $cfg
);
}
$index++;
return $html;
}
//注册下短标签
add_shortcode("charts", "wpr_charts");
这个时候,你就可以实现部分功能,就是利用cfg文件加载配置文件,同时我实现了一种直接利用外部数据的方法,就是直接利用api获取数据并加载,当然这里是从服务器读取整个配置文件,相对于官方的例子可能有些不一样。
第一步,来实现一个API接口,在wordpress上面,实现这一的接口还是超级简单的,如果你要求不高的话,比如下面这一段,实现一个简单的API接口。
//添加一个api页面的处理程序,这段必须放在functuions.php的最后
do_action("api_page_process", two_heart_api_url());
//注册几个api处理程序
add_action('api_page_process', function ($api){
if($api === "get_my_weight"){
header("Content-Type: application/json; charset=utf-8");
$weight = new MyWeightView();
$list = $weight->get_charts_list();
echo json_encode(create_highcharts_obj("最近体重记录|来源:每日计算平均值", "Kg", $list), JSON_UNESCAPED_UNICODE);
exit;
}
});
/**
* 获取当前的API地址
* @return string|false
*/
function two_heart_api_url(){
if(!defined('MY_API_PATH')){
//没定义API路径,无效功能
return false;
}
$url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : "";
if(empty($url)){
return false;
}
$urls = explode("?", $url);
$url = $urls[0];
$index = strpos($url, MY_API_PATH);
if($index !== 0){
return false;
}
$api = substr($url, strlen(MY_API_PATH));
if(empty($api)){
return false;
}
return $api;
}
do_action("api_page_process", two_heart_api_url());
//注册几个api处理程序
add_action('api_page_process', function ($api){
if($api === "get_my_weight"){
header("Content-Type: application/json; charset=utf-8");
$weight = new MyWeightView();
$list = $weight->get_charts_list();
echo json_encode(create_highcharts_obj("最近体重记录|来源:每日计算平均值", "Kg", $list), JSON_UNESCAPED_UNICODE);
exit;
}
});
/**
* 获取当前的API地址
* @return string|false
*/
function two_heart_api_url(){
if(!defined('MY_API_PATH')){
//没定义API路径,无效功能
return false;
}
$url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : "";
if(empty($url)){
return false;
}
$urls = explode("?", $url);
$url = $urls[0];
$index = strpos($url, MY_API_PATH);
if($index !== 0){
return false;
}
$api = substr($url, strlen(MY_API_PATH));
if(empty($api)){
return false;
}
return $api;
}
第二步,在文章中添加一段短标签,比如我这里是获取体重的数据,写出代码就可以了,就不在具体展示数据了,可以去上一篇文章喵喵。
[charts src="/api/get_my_weight"][/charts]
最后,wordpress还是很强大的,绝对不要小看,添加各种功能再简单不过。虽然很臃肿,但某一天这些都不会是问题。
哪一天,wp不会再是臃肿 ?
某一天,上更好的配置就行了,功能强大又不是错