typecho 1.0 利用独立页面实现自定义sidebar侧边栏,如友情链接
注意:这个是在typecho 1.0版本下测试的,看到typecho 0.9版本也是用的markdown实现,所以理论上typecho 0.9也可以用。
一、思路
先说动机...就是根本搜不到支持typecho 1.0的友情链接插件(实际上我是打算展示自己练手的小项目),所以无奈之下直接看PHP源码自己动手实现了。
实际上就是在后台建立一个独立页面,在独立页面中写链接名并添加链接(平常的markdown)方法;然后编辑主题源码中functions.php,增加正则表达式提取之前独立页面内容的链接名和链接函数,并输出为html元素;最后在主题源码中sidebar.php中增加一个widget,并调用刚才的函数。
效果就像我的博客这样了。
二、新建独立页面并写入内容
新建独立页面
很简单,进入后台,撰写->创建页面
大概像下面:
注意记住独立页面的自定义url字段,如我的是project
写入内容
内容大概如上图,即首先写名字,然后对其建立链接,需要注意:
- 此页面中只为sidebar中需要显示的内容建立超级链接,因为后面正则表达式会抓取所有有超级链接的;
- 后面如
[1]: http://xxx/xxx/xx.html
中,:
后有一个空格,URL最后面必须有空格或回车之类的符号; - 强调一下上面的,默认情况下整个独立页面markdown文档最后一个URL后直接是文件结束,此时需要自己在最后再加一个空格或回车符,避免正则表达式对最后一个解析失败。
tip:可以用如phpMyAdmin看到实际存储在数据库中独立页面的内容,在表typecho_contents
,slug
字段值为如我的是project
,其text
字段值就是markdown内容。
三、编辑正则表达式处理函数
该函数实现最核心的功能,需要写在functions.php中。
直接上代码:
function PageToLinks($slug = 'links')
{
$db = Typecho_Db::get();
$contents = $db->fetchObject($db->select('text')->from('table.contents')
->where('slug = ?', $slug)->limit(1));
if (!$contents) {
return;
}
$text = $contents->text;
$titles = $db->fetchObject($db->select('title')->from('table.contents')
->where('slug = ?', $slug)->limit(1));
$title=$titles->title;
echo "<h3 class='widget-title'>".$title."</h3>";
echo "<ul class='widget-list'>";
preg_match_all("/\[(.*?)\]\[(\d)\]/", $text,$r);
foreach ($r[1] as $key => $value) {
$num=$r[2][$key];
preg_match_all("/\[$num\]:\s(.*?)\s/", $text, $urls);
$href="<a href=".$urls[1][0].">".$value."</a>";
echo "<li>".$href."</li>";
}
echo "</ul>";
}
一个个解释:
$slug = 'links'
即独立页面的slug,如我的是project
,不指定的话就是links
$db = Typecho_Db::get();
用来获取数据库支持
$contents = $db->fetchObject($db->select('text')->from('table.contents')
->where('slug = ?', $slug)->limit(1));
在数据库中获取此slug页面内容,此时还不是内容本身
$text = $contents->text;
用来获取内容本身,实际上就是markdown文档
$titles = $db->fetchObject($db->select('title')->from('table.contents')
->where('slug = ?', $slug)->limit(1));
$title=$titles->title;
用来获取此slug页面的标题
echo "<h3 class='widget-title'>".$title."</h3>";
echo "<ul class='widget-list'>";
依照格式输出html格式的标题,和html中list的前缀
preg_match_all("/\[(.*?)\]\[(\d)\]/", $text,$r);
对内容用正则表达式获取链接名,和链接序号,如Flask设置返回json格式数据 1
$num=$r[2][$key];
取得序号
preg_match_all("/\[$num\]:\s(.*?)\s/", $text, $urls);
对内容用正则表达式,指定特定的需要,找出其链接URL
$href="<a href=".$urls[1][0].">".$value."</a>";
形成html格式的超级链接,$urls[1][0]
即URL,$value
即链接名
echo "<li>".$href."</li>";
将刚才形成的a
标签包裹到li
中并输出
echo "</ul>";
最后输出list后缀
注意:
- 最主要的问题在两个正则表达式中,可以需要根据实际情况修正
- 因为我好久没有接触php,代码也是匆匆写成,所以一定有更好的代码
四、在sidebar中添加widget并调用函数
关于填充在sidebar的哪个地方,就是看自己的意思了
sidebar由一个或多个section
组成,每个section
结构大概如下:
<section class="widget">
<h3 class="widget-title">THE TITLE</h3>
<ul class="widget-list">
<li>
<a href="THE-URL">THE-TITLE</a>
</li>
...
...
</section>
之前的函数已经填充了section
的内容,所以代码很容易了:
<section class="widget">
<?php PageToLinks('project'); ?>
</section>
需要将哪个独立页面内容展示到sidebar,函数参数就填哪个独立页面的slug
五、完成
编辑完成后只需要重新刷新页面就能看到效果了。
六、重新说下注意事项
- 独立页面内容实际上符合markdown规范就没啥问题,只是需要在最末尾加一个空格或者回车
- 正则表达式部分正常情况下不需要修改,但也不排除特殊情况
- sidebar新增的
section
如果和之前有的,如“最新文章”排版不匹配的话,考虑编辑输出函数,主要应该在html中class
上和h3
标题标签上。
七、后记
我觉得这样实现是很好的,不需要触及数据库部分,而且函数简单,不需要涉及很多改动,另外也没有什么副作用。
计划将其做成一个插件,不过也只是计划而已...
你好,分类文章的数量该怎么显示,虽然知道是调用这个
<?php $this->widget('Widget_Metas_Category_List')->listCategories('wrapClass=widget-list'); ?>,但是不太清楚怎么加上数量。能指点一下吗
抱歉回复晚了,拿到分类widget('Widget_Metas_Category_List')->to($category)后直接调用count()就拿到分类下的文章数目了。
不过看你已经实现了呢~
挺好的,学习下,希望博主有空多更新点typecho的文章
谢谢
Thanks...因为还有些博客比我写的好多了,所以更新typecho文章的计划就一拖再拖了,你可以先去看看他们写的咯(很容易搜到),感觉比我不知道高到哪去了
没搜索到,麻烦博主推荐下呀。
另外请问博主怎样把这个代码改为调用幻灯片的?我修改了下总有点问题解决不了。
http://www.typechodev.com/ 这个有很多typechodev开发的例子介绍
https://blog.phpgao.com/typecho_source_code_init.html 这个博主出了几篇typecho源码分析,还有他自己也开发了一些插件
我要是没理解错你的意思,是要把一个文章中的图片URL都提取出来,然后在首页贴成html的吧?就是把代码中的正则换成匹配markdown的图片标记的(应该就是链接的前面多了个“!”),然后用PHP把所有得到的图片URL循环生成html的元素,最后配合js实现前端显示咯。
http://yijile.com/log/365.html这里有个例子,但区别在于这个是typecho 0.9之前的实现方法,当时获取到的text是html格式的,现在换成markdown了,不过总体来说是一样的。
谢谢回复,博主有空的话直接在你这篇文章代码基础上修改下好嘛,或者修改下你推荐的那个也好,小白不太会php
抱歉回复晚了,这段时间有些忙,更新这个恐怕要过些时间。PHP挺简单的,照葫芦画瓢就好了,祝顺利~