typecho路由机制详解
本文介绍的是typecho的路由机制,引自 不烦恼
路由机制是typecho的核心,有很多功能都是基于路由功能设计的,理解并熟悉TE的路由机制将非常有助于插件的开发。
完整的路由表如下:
array (
0 =>
array (
'index' =>
array (
'url' => '/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^[/]?$|',
'format' => '/',
'params' =>
array (
),
),
'do' =>
array (
'url' => '/action/[action:alpha]',
'widget' => 'Widget_Do',
'action' => 'action',
'regx' => '|^/action/([_0-9a-zA-Z-]+)[/]?$|',
'format' => '/action/%s',
'params' =>
array (
0 => 'action',
),
),
'post' =>
array (
'url' => '/archives/[cid:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/archives/([0-9]+)[/]?$|',
'format' => '/archives/%s/',
'params' =>
array (
0 => 'cid',
),
),
'attachment' =>
array (
'url' => '/attachment/[cid:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/attachment/([0-9]+)[/]?$|',
'format' => '/attachment/%s/',
'params' =>
array (
0 => 'cid',
),
),
'category' =>
array (
'url' => '/category/[slug]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/category/([^/]+)[/]?$|',
'format' => '/category/%s/',
'params' =>
array (
0 => 'slug',
),
),
'tag' =>
array (
'url' => '/tag/[slug]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/tag/([^/]+)[/]?$|',
'format' => '/tag/%s/',
'params' =>
array (
0 => 'slug',
),
),
'author' =>
array (
'url' => '/author/[uid:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/author/([0-9]+)[/]?$|',
'format' => '/author/%s/',
'params' =>
array (
0 => 'uid',
),
),
'search' =>
array (
'url' => '/search/[keywords]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/search/([^/]+)[/]?$|',
'format' => '/search/%s/',
'params' =>
array (
0 => 'keywords',
),
),
'index_page' =>
array (
'url' => '/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/page/([0-9]+)[/]?$|',
'format' => '/page/%s/',
'params' =>
array (
0 => 'page',
),
),
'category_page' =>
array (
'url' => '/category/[slug]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/category/([^/]+)/([0-9]+)[/]?$|',
'format' => '/category/%s/%s/',
'params' =>
array (
0 => 'slug',
1 => 'page',
),
),
'tag_page' =>
array (
'url' => '/tag/[slug]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/tag/([^/]+)/([0-9]+)[/]?$|',
'format' => '/tag/%s/%s/',
'params' =>
array (
0 => 'slug',
1 => 'page',
),
),
'author_page' =>
array (
'url' => '/author/[uid:digital]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/author/([0-9]+)/([0-9]+)[/]?$|',
'format' => '/author/%s/%s/',
'params' =>
array (
0 => 'uid',
1 => 'page',
),
),
'search_page' =>
array (
'url' => '/search/[keywords]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/search/([^/]+)/([0-9]+)[/]?$|',
'format' => '/search/%s/%s/',
'params' =>
array (
0 => 'keywords',
1 => 'page',
),
),
'archive_year' =>
array (
'url' => '/[year:digital:4]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/([0-9]{4})[/]?$|',
'format' => '/%s/',
'params' =>
array (
0 => 'year',
),
),
'archive_month' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/([0-9]{4})/([0-9]{2})[/]?$|',
'format' => '/%s/%s/',
'params' =>
array (
0 => 'year',
1 => 'month',
),
),
'archive_day' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/[day:digital:2]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/([0-9]{4})/([0-9]{2})/([0-9]{2})[/]?$|',
'format' => '/%s/%s/%s/',
'params' =>
array (
0 => 'year',
1 => 'month',
2 => 'day',
),
),
'archive_year_page' =>
array (
'url' => '/[year:digital:4]/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/([0-9]{4})/page/([0-9]+)[/]?$|',
'format' => '/%s/page/%s/',
'params' =>
array (
0 => 'year',
1 => 'page',
),
),
'archive_month_page' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/([0-9]{4})/([0-9]{2})/page/([0-9]+)[/]?$|',
'format' => '/%s/%s/page/%s/',
'params' =>
array (
0 => 'year',
1 => 'month',
2 => 'page',
),
),
'archive_day_page' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/[day:digital:2]/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/([0-9]{4})/([0-9]{2})/([0-9]{2})/page/([0-9]+)[/]?$|',
'format' => '/%s/%s/%s/page/%s/',
'params' =>
array (
0 => 'year',
1 => 'month',
2 => 'day',
3 => 'page',
),
),
'comment_page' =>
array (
'url' => '[permalink:string]/comment-page-[commentPage:digital]',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^(.+)/comment-page-([0-9]+)[/]?$|',
'format' => '%s/comment-page-%s',
'params' =>
array (
0 => 'permalink',
1 => 'commentPage',
),
),
'feed' =>
array (
'url' => '/feed[feed:string:0]',
'widget' => 'Widget_Archive',
'action' => 'feed',
'regx' => '|^/feed(.*)[/]?$|',
'format' => '/feed%s',
'params' =>
array (
0 => 'feed',
),
),
'feedback' =>
array (
'url' => '[permalink:string]/[type:alpha]',
'widget' => 'Widget_Feedback',
'action' => 'action',
'regx' => '|^(.+)/([_0-9a-zA-Z-]+)[/]?$|',
'format' => '%s/%s',
'params' =>
array (
0 => 'permalink',
1 => 'type',
),
),
'page' =>
array (
'url' => '/[slug].html',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/([^/]+)\\.html[/]?$|',
'format' => '/%s.html',
'params' =>
array (
0 => 'slug',
),
),
),
'index' =>
array (
'url' => '/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'do' =>
array (
'url' => '/action/[action:alpha]',
'widget' => 'Widget_Do',
'action' => 'action',
),
'post' =>
array (
'url' => '/archives/[cid:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'attachment' =>
array (
'url' => '/attachment/[cid:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'category' =>
array (
'url' => '/category/[slug]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'tag' =>
array (
'url' => '/tag/[slug]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'author' =>
array (
'url' => '/author/[uid:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'search' =>
array (
'url' => '/search/[keywords]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'index_page' =>
array (
'url' => '/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'category_page' =>
array (
'url' => '/category/[slug]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'tag_page' =>
array (
'url' => '/tag/[slug]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'author_page' =>
array (
'url' => '/author/[uid:digital]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'search_page' =>
array (
'url' => '/search/[keywords]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'archive_year' =>
array (
'url' => '/[year:digital:4]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'archive_month' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'archive_day' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/[day:digital:2]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'archive_year_page' =>
array (
'url' => '/[year:digital:4]/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'archive_month_page' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'archive_day_page' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/[day:digital:2]/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'comment_page' =>
array (
'url' => '[permalink:string]/comment-page-[commentPage:digital]',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'feed' =>
array (
'url' => '/feed[feed:string:0]',
'widget' => 'Widget_Archive',
'action' => 'feed',
),
'feedback' =>
array (
'url' => '[permalink:string]/[type:alpha]',
'widget' => 'Widget_Feedback',
'action' => 'action',
),
'page' =>
array (
'url' => '/[slug].html',
'widget' => 'Widget_Archive',
'action' => 'render',
),
)
上面的数组分为两个部分:
$routingTable[0] 的作用是路由解析(反解析),以下称“路由解析数组”(一个数组$routingTable[0])
$routingTable['string'] 的作用是生成路由解析数组(当$routingTable[0] 不存在时生成routingTable[0]),以下称“路由生成数组”(多个数组$routingTable['string'],string 代表路由名称)
例:
先看路由表中评论页的路由生成数组:
$routingTable = array(
'comment_page' =
array (
'url' => '[permalink:string]/comment-page-[commentPage:digital]',
'widget' => 'Widget_Archive',
'action' => 'render',
)
);
数组中的内容代表什么:
$routingTable 中的 KEY 值 comment_page 是路由名称
$routingTable['comment_page'] 是一个数组,数组中 'url'、'widget'、 'action' 值的作用只是为了生成路由解析数组(见下面的代码,至于如何解析的,可以看 Typecho\Router\Parser.php 中的代码)
再看路由表中评论页的路由解析(反解析)数组(这个是重点,上面的了解就行):
$routingTable = array(
[0] = array(
'comment_page' => array (
'url' => '[permalink:string]/comment-page-[commentPage:digital]',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^(.+)/comment-page-([0-9]+)[/]?$|',
'format' => '%s/comment-page-%s',
'params' => array (
0 => 'permalink',
1 => 'commentPage',
),
),
),
);
数组中的内容代表什么:
$routingTable['0'] 中的 KEY 值 comment_page 是路由名称(可以在路由解析完成后用 Typecho_Router::$current 调用)
$routingTable['0']['comment_page'] 是一个数组,数组中键 'url' 的值是从路由生成数组过渡过来的,其作用是为了生成路由解析数组中的其他三个值,分别为:
一是生成键 'regx'(值的作用是解析 pathInfo 时的正则表达式规则);
二是生成键 'format'(值的作用是反解析路由时生成 pathInfo 的格式);
三是生成键 'params'(值的作用是pathInfo被路由解析后传递给widget的参数),键 'params' 的值是一个数组,数组内容与 'regx' 正则表达式中的子模式顺序值相对应;
键 'widget' 的值是路由解析后分发执行的组件(传递给“组件工厂”);键 'action' 的值是组件实例化后执行的方法。
组件工厂执行流程:
组件实例化(生成组件对象) —— 执行构造函数(将上述 'params' 传递给对象) —— 执行execute方法 —— 执行action方法
完整的例子(扩展讲解):
浏览器中文章评论页的URL:
http://www.bufannao.com/archives/__slide__top__gridLayout.html/comment-page-1
得到文章评论页的 pathInfo 为:
/archives/__slide__top__gridLayout.html/comment-page-1
搜索路由表得到文章评论页的路由为:
$routingTable = array(
[0] = array(
'comment_page' => array (
'url' => '[permalink:string]/comment-page-[commentPage:digital]',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^(.+)/comment-page-([0-9]+)[/]?$|',
'format' => '%s/comment-page-%s',
'params' => array (
0 => 'permalink',
1 => 'commentPage',
),
),
),
);
执行顺序:
Typecho_Widget::widget('Widget_Archive', NULL, array('permalink' => '/archives/__slide__top__gridLayout.html', 'commentPage' => 1));
// $responseObject = Typecho_Response::getInstance();
// $requestObject = new Typecho_Request();
// $requestObject->setParams(array('permalink' => '/archives/__slide__top__gridLayout.html', 'commentPage' => 1));
// 此时$requestObject附加两个属性
// $requestObject->permalink = '/archives/__slide__top__gridLayout.html';
// $requestObject->commentPage = 1;
// $widget = new Widget_Archive($requestObject, $responseObject , null);
// $widget->__construct();
// $widget->execute();
// $widget->render();
内容比较多,写得也比较乱,如果上述内容有误欢迎指正。
typecho路由机制详解的更多相关文章
- SPA路由机制详解(看不懂不要钱~~)
前言 总所周知,随着前端应用的业务功能起来越复杂,用户对于使用体验的要求越来越高,单面(SPA)成为前端应用的主流形式.而大型单页应用最显著特点之一就是采用的前端路由跳转子页面系统,通过改变页面的UR ...
- WebApi路由机制详解
随着前后端分离的大热,WebApi在项目中的作用也是越来越重要,由于公司的原因我之前一直没有机会参与前后端分离的项目,但WebApi还是要学的呀,因为这东西确实很有用,可单独部署.与前端和App交互都 ...
- 从mixin到new和prototype:Javascript原型机制详解
从mixin到new和prototype:Javascript原型机制详解 这是一篇markdown格式的文章,更好的阅读体验请访问我的github,移动端请访问我的博客 继承是为了实现方法的复用 ...
- 浏览器 HTTP 协议缓存机制详解
最近在准备优化日志请求时遇到了一些令人疑惑的问题,比如为什么响应头里出现了两个 cache control.为什么明明设置了 no cache 却还是发请求,为什么多次访问时有时请求里带了 etag, ...
- JVM的垃圾回收机制详解和调优
JVM的垃圾回收机制详解和调优 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc都 ...
- ThreadPoolExecutor运转机制详解
ThreadPoolExecutor运转机制详解 - 走向架构师之路 - 博客频道 - CSDN.NET 最近发现几起对ThreadPoolExecutor的误用,其中包括自己,发现都是因为没有仔细看 ...
- Linux 内存机制详解宝典
Linux 内存机制详解宝典 在linux的内存分配机制中,优先使用物理内存,当物理内存还有空闲时(还够用),不会释放其占用内存,就算占用内存的程序已经被关闭了,该程序所占用的内存用来做缓存使用,对于 ...
- PHP的垃圾回收机制详解
原文:PHP的垃圾回收机制详解 最近由于使用php编写了一个脚本,模拟实现了一个守护进程,因此需要深入理解php中的垃圾回收机制.本文参考了PHP手册. 在理解PHP垃圾回收机制(GC)之前,先了解一 ...
- Java 反射 设计模式 动态代理机制详解 [ 转载 ]
Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...
随机推荐
- Android DrawerLayout 点击事情穿透
今天使用DrawerLayout做网易4.4版本侧边栏发现点击DrawerLayout空白部分,下面部分content会获得点击事件.解决方法是在<!-- The navigation draw ...
- VBoxManage.exe: error: Resize hard disk operation for this format is not implemented yet!
VirtualBox虚拟磁盘空间不够了,默认10G.想扩大,图形界面下没有找到可操作菜单.Google了一下用 Vbox自带的命令工具VBoxManage即可解决. C:\Program Files\ ...
- rsyslog VS syslog-ng,日志记录哪家强?
还有慢慢摸索,NG的MYSQL配置,我始终没搞好. RSYSLOG则比较容易. 另外,也可以每个RSYSLOG直接入库,不需要经过LOG SERVER..如果有一个大内网的话... 配合LOGANAL ...
- 向着DJANGO奔跑!
这个项目明天上半年要弄好,就牛X了哈哈. 平台化运维.PYTHON,SVN,SALTSTACK,.....一锅端~~:) from django.contrib import admin # Regi ...
- 这样就算会了PHP么?-10
关于基本的文件读写内容: <?php echo "readfile function:<br>"; readfile("tm.txt"); e ...
- 解决Struts2.2.20版本的标签不支持style属性的问题
我先把Exception错误信息贴出来:org.apache.jasper.JasperException: /WEB-INF/jsp/topicAction/addUI.jsp (line: 40, ...
- 【POJ1581】A Contesting Decision(简单模拟)
没有什么弯路,直接模拟即可.水题. #include <iostream> #include <cstring> #include <cstdlib> #inclu ...
- ASP.net ListItem Attributes 属性回传丢失的解决方案
该方法为网上整理 1. 新继承一个列表控件 新控件中重写两个方法: using System; using System.Collections.Generic; using System.Linq; ...
- Atitit.软件guibuttonand面板---os区-----linux windows搜索文件 目录
Atitit.软件guibuttonand面板---os区-----搜索文件 1. Find 1 2. 寻找文件夹 1 3. 2. Locate// everything 1 4. 3. Wherei ...
- CDN云主机与传统虚拟主机功能对比
CDN云主机与传统虚拟主机功能对比 传统的虚拟主机都是单台服务器,一旦机器硬件损坏.IP被封.机房网络故障等,都将导致网站不能访问,严重的情况数据还无法及时取回,即使想换一家服务商也因为没有数据而无能 ...