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 ...
随机推荐
- shell脚本的桩
项目代码: alias book_search="/usr/local/mysql/bin/mysql -h 172.18.12.202 -uppstat -pstatpp book_sea ...
- 手把手教你清除WIN7的C盘垃圾
WIN7系统用着用着C盘会变得越来越大,可用空间变得越来越小,磁盘清理,和安全卫士怎么清也清不出这些系统深度的垃圾.我们可以手动删除,释放C盘空间. 这样一清理下来,结果我的C盘就释放了近10个GB的 ...
- 关于hash
http://rapheal.iteye.com/blog/1142955 关于javascript hash
- LeetCode_Container With Most Water
Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). ...
- java设计模式--创建型模式--抽象工厂
什么是抽象工厂,再次学习. 抽象工厂 概述 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 适用性 1.一个系统要独立于它的产品的创建.组合和表示时. 2.一个系统要由多个产品系 ...
- Php基本语法数据类型操作基础训练
<?php /* * Created on 2015年12月17日 * * To change the template for this generated file go to * Wind ...
- POJ3261-哈希
这个题让求至少出现K次的最大长度的子串,属于最大化最小值问题,首先应该想到二分求字串的长度,二分的过程是O(logN)的,注意judge的时候怎样判断是否满足情况以及满足情况后l,r的变化.可以给每一 ...
- WPF的数据绑定详细介绍
数据绑定:是应用程序 UI 与业务逻辑之间建立连接的过程. 如果绑定正确设置并且数据提供正确通知,则当数据的值发生更改时,绑定到数据的视觉元素会自动反映更改. 数据绑定可能还意味着如果视觉元素中数据的 ...
- NavMeshAgent 动态加载障碍物
如果你想让游戏人物绕开一些物体, 这些物体动态生成出来的.只需要给物体添加NavMeshObstacle组件即可 1. 绿色方块添加NavMeshObstacle组件 2. 红色方块没有添加NavMe ...
- Runtime运行时机制
Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的 我们需要了解的是 Objective-C 是一门动态语言, ...