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 ...
随机推荐
- Oracle ORA-03137: TTC protocol internal error : [12333] 故障分析
程序通过JDBC 连接数据库异常,报 ORA-03137[12333]的错误. 当前程序的JDBC 驱动版本:ojdbc16-11.2.0.1.0.jar 数据库版本: 11.2.0.3 一. Log ...
- RBL, UBL, Uboot的关系
RBL, UBL, Uboot的关系 1)RBL=ROM Bootloader,UBL=user Bootloader. 2)RBL为TI固化在芯片ROM中的bootloader,OMAP上电启动过后 ...
- HashMap和Hashtable的差别
1. HashMap 与 Hashtable继承自不同的类 1) HashMap 继承自AbstractMap,而AbstractMap实现了Map接口 2) Hashtable 继承自Dict ...
- <转载>linux gcc编译器中使用gdb单步调试程序,程序不是顺序执行的。
原文地址http://blog.csdn.net/abc78400123/article/details/6779108 在用gdb调试,使用s 或n单步执行程序时,发现程序不是按顺序运行的,有时莫名 ...
- c++之 数组
数组的定义 数组用于表示一组数值,例如: char arr[5]; 其中,arr称为"数组变量",简称"数组".它表示5个char型数据,我们把每一个数据称为一 ...
- Visual Studio 2015 使用ODP.net进行EF开发
刚转了新公司,以前公司都是用VS+MSSQL作为开发工具的 现在新公司由于数据库是Oracle,而且新公司比较小规模,开发团队也没有什么规范 访问数据库的方式一直使用ADO.net的DataTable ...
- 给定N个整数集合是否存在两个其和刚好为指定常数的元素
又一次学习一遍<算法导论>,看到了这个问题: 描写叙述一个执行时间为O(nlgn)的算法,使之能在给定一个由n个整数构成的集合S和还有一个整数 X 时,推断出S中是否存在有两个其和刚好等于 ...
- CAS原理与协议
SSO英文全称Single Sign On,单点登录. SSO是在多个应用系统中,用户仅仅须要登录一次就能够訪问全部相互信任的应用系统. SSO的解决方式非常多,比方收费的有UTrust.惠普灵动等, ...
- JS 点击复制Copy插件--Zero Clipboard
写博客就是一周工作中遇到哪些问题,一个优点就是能够进行一个总结,另外一个优点就是下次遇到相同的问题即使那你记不住,也能够翻看你的博客攻克了.相同也能够帮到别人遇到与你一样问题的人.或者别人有比你更好的 ...
- [Python学习笔记][第八章Python异常处理结构与程序调试]
1/30 第八章Python异常处理结构与程序调试 异常处理 try-except结构 try: try块 except Exception: except块 try-except-else结构 tr ...