typecho中的Widget設計文檔

組成系統的最基本元素

什么是Widget

Widget是組成Typecho的最基本元素,除了已經抽象出來的類庫外,其它幾乎所有的功能都會通過Widget來完成。在實踐中我們發現,在博客這種小型但很靈活的系統中實施一些大型框架的思想是不合適的,它會使系統靈活性降低并且維護成本增高。因此為了達到功能和抽象的統一,我們將系統中所有的功能單元都看作一個Widget,它們都繼承自一個超類''TypechoWidget''。

如何調用Widget

Widget有兩種調用方法,它們分別是
1、顯式地初始化一個Widget實例

class Foo extends Typecho_Widget
{public function test(){echo 'hello world';}public function render($a, $b){echo $a  $b;}
}$widget = new Foo();

2、使用工廠函數**factory**初始化Widget,并運行入口函數。

Typecho_API::factory('Foo', 6, 8);
//outputs: 14

在系統中,我們通常使用后者來實例化一個Widget -> Typecho::widget函數將直接返回一個實例化的Widget對象。它的第一個參數是Widget的絕對名稱,在Typecho系統中Widget有兩個存放的地方,他們分別是**./widget**目錄和**./var/plugins**目錄。Widget與其文件名保持一致且區分大小寫,比如一個Widget的名稱為TestMe那么它的文件名就是TestMe.php。

Widget文件可以按目錄存放,調用的時候用點分號分割目錄。比如存放路徑為**./widget/contents/TestPost.php**,調用方法就是

Typecho::widget('contents.TestPost');

在上面的解釋中,我們提到widget函數的作用是實例化一個Widget并運行它的入口函數。Widget的入口函數是render,這是一個公開函數,子類在繼承超類TypechoWidget時必須實現這一方法。因此widget函數后面的參數將傳遞給入口函數render,比如上例中的Typecho::widget('Foo',6,8),后面的兩個參數將傳遞給Foo::render($a, $b)。

何時調用

Widget通常在以下三個地方被調用。

1、默認組件。Typecho系統共有兩個入口(前臺和后臺),在這兩個入口初始化的時候分別會運行一些必要的默認組件,在index.php中有以下代碼

Typecho::widget('Options')->to($options);    //初始化配置組件
Typecho::widget('Access')->to($access);      //初始化權限組件

在./admin/header.php中有以下代碼

Typecho::widget('Options')->to($options);    //初始化配置組件
Typecho::widget('Access')->to($access);      //初始化權限組件
Typecho::widget('Menu')->to($menu);          //初始化菜單組件

這些Widget在系統初始化時被強制執行。

2、通過路由器默認執行的組件。[[develop:route|路由器]]是系統的重要組成部分,前臺的所有頁面都會通過路由器來展現,**路由器在默認組件執行之后被執行**。我們可以在路由表中設置默認執行的組件,這樣當頁面被導向這條路由記錄時,默認組件將被執行。下面是一個路由表的示例,你可以在./config.php中找到它的完整定義。

/** 定義路由結構 **/
global $route;$route = array('index' => array('/', 'index.php', NULL, NULL, array('contents.Posts')),   //最后的一個參數表示默認組件'index_page' => array('/page/([0-9])[/]?', 'index.php', array('page'), '/page/%d', array('contents.Posts')),'post' => array('/archives/([0-9])[/]?', 'post.php', array('cid'), '/archives/%d', array('contents.Post')),'rss' => array('/feed[/]?', '../../xml/rss.php', NULL, '/rss', NULL),'do' => array('/([_0-9a-zA-Z-])\.do?', array('DoWidget'), array('do'), '/%s.do'),'job' => array('/([_0-9a-zA-Z-])\.job?', array('JobWidget'), array('job'), '/%s.job'),'login' => array('/login[/]?', 'admin/login.php'),'admin' => array('/admin[/]?', 'admin/index.php'),'page' => array('/([_0-9a-zA-Z-])[/]?', 'page.php', array('slug'), '/%s', array('contents.Post')),);

3、在最終頁面中被執行的組件。最終頁面也就是開發者最常接觸到的模板之類的頁面,我們通過widget函數來調用我們需要的組件。

<html>
<head>
<title><?php $options->title(); ?></title>
</head>
<body><div>
<!-- 第一種調用方法,調用公開方法生成列表 -->
<?php Typecho::widget('contents.Posts')->output('li', '_blank', 'list', true, 10, '[...]'); ?><!-- 第二種調用方法,調用集成方法生成列表 -->
<?php Typecho::widget('contents.Posts')->parse('<li><a href="{permalink}">{title}</a></li>'); ?><!-- 第三種調用方法,每行輸出 -->
<?php Typecho::widget('contents.Posts')->to($posts); ?><?php while($posts->get()): ?><h2><a href="<?php $posts->permalink(); ?>"><?php $posts->title(); ?></a></h2><cite><?php $post->date('Y-m-d'); ?> | <?php $post->category(','); ?></cite><div><?php $post->content('...'); ?></div><?php endwhile; ?>
</div>
</body>
</html>

由于widget函數將直接返回實例化的組件(Widget)對象,因此我們可以通過返回值直接使用Widget的公開方法。其中一些比較特殊的方法將在后面被陸續介紹到。

一次執行規則

什么是一次執行規則

?當一個組件被實例化以后,它將被保存在對象堆棧中,當我們第二次使用這一組件時,它將被直接從堆棧中取出然后返回。這一規則可以在保證組件唯一性的同時節約服務器資源。

如何調用已經被實例化的組件

一般來說我們通過函數widget調用一個組件時,它會返回一個實例化組件,你不必擔心它是否是第一次被實例化。

Widget內部方法與接口

to方法

to方法是一個非常有用的偽方法,它的作用在于把一個實例化的Widget賦到一個變量中。我們可以通過以下代碼來展示。

Typecho::widget('Foo')->to($foo);
$foo->test();

在上面的代碼中我們通過to方法把實例化的Foo組件賦值給$foo。這樣我們在后面的代碼中可以用$foo變量來代表實例化的Foo對象,它等效于

$foo = Typecho::widget('Foo');

之所以不直接使用賦值語法,是因為賦值在模板中會經常用到,這一簡寫語法比較好理解,可以簡化模板語法。**to方法在超類TypechoWidget中被實現,通過繼承TypechoWidget可以自動具備這一方法**。

push以及相關方法

每個Widget都有一個內部隊列,用于存儲多行數據,這個堆棧的數據存取方法在超類TypechoWidget中被實現,我們通過繼承超類獲得對隊列的操作能力。每次執行push方法,都將把一行數據壓入隊列,并移動隊列的指針。數據壓入完畢后,我們可以通過get方法移動指針,并且通過直接訪問組建的內部屬性獲得某行的具體數據,我們通過如下代碼來展示這一過程。

class Foo extends TypechoWidget
{public function render(){//定義三行數據$row1 = array('name' => 'Mike', 'age' => 17, 'sex' => 'man');$row2 = array('name' => 'Lucy', 'age' => 27, 'sex' => 'woman');$row3 = array('name' => 'Clark', 'age' => 23, 'sex' => 'man');//按順序壓入隊列$this->push($row1);$this->push($row2);$this->push($row3);//從隊列中取出相應值while($this->get()){echo "My name is " . $this->name . ", I'm " . $this->age . " years old, I am a " . $this->sex . ".\r\n";}}
}/***
輸出:
My name is Mike, I'm 17 years old, I am a man.
My name is Lucy, I'm 27 years old, I am a woman.
My name is Clark, I'm 23 years old, I am a man.
***/

parse方法

parse方法實際上是對隊列內數據輸出的改善,以方便用戶在html視圖模板頁面中顯示列表,你不需要使用while之類的循環語法,直接指定一個列表模板即可,此函數會按照模板直接輸出列表。因此我們可以對上面的例子做一點改進,用更少的代碼達到同樣的效果。

class Foo extends TypechoWidget
{public function render(){//定義三行數據$row1 = array('name' => 'Mike', 'age' => 17, 'sex' => 'man');$row2 = array('name' => 'Lucy', 'age' => 27, 'sex' => 'woman');$row3 = array('name' => 'Clark', 'age' => 23, 'sex' => 'man');//按順序壓入隊列$this->push($row1);$this->push($row2);$this->push($row3);//使用parse輸出$this->parse("My name is {name}, I'm {age} years old, I am a {sex}.");}}/***
輸出:
My name is Mike, I'm 17 years old, I am a man.
My name is Lucy, I'm 27 years old, I am a woman.
My name is Clark, I'm 23 years old, I am a man.
***/

alt方法

在視圖中輸出widget列表內容時,可能產生如下隔行輸出不同風格的需求。

<ul>
<li class="style-one">hello world</li>
<li class="style-two">hello china</li>
<li class="style-one">hello earth</li>
<li class="style-two">hello moon</li>
</ul>

注意以上代碼中class的內容,也就是以2為界的循環輸出。我們可以通過調用alt方法達到目的。

<?php Typecho::widget('Hello')->to($hello); ?><?php while($hello->get()): ?>
<li class="<?php $hello->alt('style-one', 'style-two'); ?>"><?php $hello->word(); ?></li>
<?php endwhile; ?>

我們在上述代碼中使用了alt方法,alt方法接受不定數目的參數,也就是說你可以給它傳遞任意個數的參數,它將按照你傳遞參數的個數循環輸出這些參數。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/80209.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/80209.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/80209.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python序列Day3

序列 序列是一種數據存儲方式&#xff0c;用方括號標注&#xff0c;逗號分隔的一組值。在內存中&#xff0c;序列就是一塊用來存放多個值的連續的內存空間。 常見序列結構有&#xff1a;字符串、列表、元組、字典、集合 列表 用于存儲任意數目&#xff0c;任意類型的數據集…

私服與外掛:刑事法律風險的深度剖析

首席數據官高鵬律師團隊編著 在當今數字化時代&#xff0c;網絡游戲產業蓬勃發展&#xff0c;然而與之相伴的私服與外掛現象卻屢禁不止&#xff0c;且其背后隱藏著嚴重的刑事法律風險。作為一名律師&#xff0c;有必要在此對私服與外掛相關的刑事問題進行深入解讀&#xff0c;以…

Linux云計算訓練營筆記day04(Rocky Linux中的命令)

mv 移動(剪切) 源數據會消失 格式: mv 源文件 目標路徑 touch /opt/a.txt 創建文件 mv /opt/a.txt /root 移動文件&#xff0c;沒有改名 mkdir gongli 創建目錄 mv gongli /opt/ 移動目錄&#xff0c;沒有改名 mv /opt/gongli tedu 移動目錄&#xff0c;改名了 …

藍橋杯青少 圖形化編程——“星星”點燈

藍橋杯青少 圖形化編程——“星星”點燈 編程實現&#xff1a; 有10盞燈&#xff0c;從1到10按順序依次編號&#xff0c;初始時全部燈處于開啟狀態。有10個人也從1到10依次編號。第一個人&#xff08;1號&#xff09;將燈全部關閉&#xff0c;第二個人&#xff08;2號&#x…

conda配置好的pytorch在jupyter中如何配置

配置 其實不用再配置了 如下圖&#xff08;主要是激活pytorch環境&#xff0c;再jupyter notebook&#xff09; jupyter運行快捷鍵shiftenter 新建文件夾folder&#xff0c;新建notebook 使用 幫助文檔&#xff08;兩種方式&#xff09; ctrl/ 注釋

COLT_CMDB_aix_diskinfo.sh

#!/bin/ksh #IT_BEGIN #IT_TYPE3 #IT SYSTEM_AIX_AGENTDISKDISCOVER|discovery.diskInfo[disc] #原型指標 #IT_RULE SYSTEM_AIX_IP|ipAddress[{#DISKNAME}] #IT_RULE SYSTEM_AIX_AGENTDISKPATH|diskPath[{#DISKNAME}] #IT_RULE SYSTEM_AIX_DISKNAME|diskName[{#DISKNAME}] #IT_…

IBM BAW(原BPM升級版)使用教程第五講

結前篇&#xff01; 一、服務&#xff1a;外部服務 在 IBM Business Automation Workflow (BAW) 中&#xff0c;外部服務&#xff08;External Services&#xff09;是指在流程中調用和集成外部系統或服務的組件。外部服務允許IBM BAW與其他業務系統、應用程序或第三方服務進行…

如何用更少的顯存訓練 PyTorch 模型

文章目錄 1、引言 2、自動混合精度訓練 3、低精度訓練 4、梯度檢查點 5、通過梯度累積減小批量大小 6、張量分片與分布式訓練 7、高效數據加載 8、使用 In-Place 操作 9、Activation and Parameter Offloading 10、使用更精簡的優化器 11、高級策略 12、總結 1、引言 在訓練大…

極速輕量,Rust 網絡開發新選擇:Hyperlane 框架深度解析

極速輕量&#xff0c;Rust 網絡開發新選擇&#xff1a;Hyperlane 框架深度解析 在高性能網絡服務開發領域&#xff0c;Rust 憑借其內存安全與高效并發的特性備受青睞。今天&#xff0c;我們迎來一款專為現代 Web 服務打造的明星框架——Hyperlane&#xff0c;它以“輕量高效、…

單片機裸機環境下臨界區保護

目錄 1、直接中斷屏蔽法 2、嵌套計數優化法 3、BASEPRI寄存器應用 4、動態優先級調整策略 5、LDREX/STREX指令應用 6、位帶別名區原子訪問 7、上下文感知保護 8、中斷延遲優化技術 在嵌入式系統開發中&#xff0c;臨界區保護是確保系統可靠性的關鍵技術。本文以ARM Cor…

【deepseek教學應用】001:deepseek如何撰寫教案并自動實現word排版

本文講述利用deepseek如何撰寫教案并自動實現word高效完美排版。 文章目錄 一、訪問deepseek官網二、輸入教案關鍵詞三、格式轉換四、word進一步排版 一、訪問deepseek官網 官網&#xff1a;https://www.deepseek.com/ 進入主頁后&#xff0c;點擊【開始對話】&#xff0c;如…

springboot使用mybatisPlus進行數據庫增刪改查

springboot使用mybatisPlus進行數據庫增刪改查 提示&#xff1a;幫幫志會陸續更新非常多的IT技術知識&#xff0c;希望分享的內容對您有用。本章分享的是springboot的使用。前后每一小節的內容是存在的有&#xff1a;學習and理解的關聯性。【幫幫志系列文章】&#xff1a;每個…

基于SpringBoot的校園周邊美食探索及分享平臺的設計與實現

資源詳情&#xff1a; 私信我或點擊鏈接獲取&#xff1a; 基于SpringBoot的校園周邊美食探索及分享平臺的設計與實現資源-CSDN文庫 摘要 美食一直是與人們日常生活息息相關的產業。傳統的電話訂餐或者到店消費已經不能適應市場發展的需求。隨著網絡的迅速崛起&#xff0c;互聯…

到達最后一個房間的最少時間II 類似棋盤轉移規律查找

文章目錄 3342.到達最后一個房間的最少時間II 思路分析&#xff1a;最短路徑問題&#xff0c;當然&#xff0c;由于不同的格子之間的移動的代價不統一,所以這個最短路徑需要使用Dijkstra算法進行求解&#xff0c;對于直接使用Dijkstra算法模版的題目&#xff0c;大家可以先去做…

基于開源AI大模型AI智能名片S2B2C商城小程序源碼的私域流量穩定性構建研究

摘要&#xff1a;在私域流量時代&#xff0c;傳統實體零售的"時間積累"邏輯被直播電商等新業態顛覆。完美日記等新銳品牌通過構建私域流量池&#xff0c;實現了從0到1的指數級增長&#xff0c;而傳統品牌卻陷入"流量焦慮"。本文提出以開源AI大模型AI智能名…

做 iOS 調試時,我嘗試了 5 款抓包工具

日常做開發的人&#xff0c;特別是和客戶端接口打交道的同學&#xff0c;應該對“抓包”這件事不陌生。 調試登錄流程、分析接口格式、排查錯誤返回、分析網絡性能、甚至研究第三方 App 的數據通信……說到底&#xff0c;都繞不開“抓 HTTPS 包”這一步。 而這一步&#xff0…

Algolia - Docsearch的申請配置安裝【以踩坑解決版】

&#x1f468;?&#x1f393;博主簡介 &#x1f3c5;CSDN博客專家 ??&#x1f3c5;云計算領域優質創作者 ??&#x1f3c5;華為云開發者社區專家博主 ??&#x1f3c5;阿里云開發者社區專家博主 &#x1f48a;交流社區&#xff1a;運維交流社區 歡迎大家的加入&#xff01…

nginx 配置后端健康檢查模塊

nginx自帶的針對后端節點健康檢查的功能比較簡單,通過默認自帶的ngx_http_proxy_module 模塊和ngx_http_upstream_module模塊中的參數來完成,當后端節點出現故障時,自動切換到健康節點來提供訪問。但是nginx不能事先知道后端節點狀態是否健康,后端即使有不健康節點,負載均…

平板收銀系統、國產系統,鴻蒙系統,小鍵盤的封裝與應用—仙盟創夢IDE

數字小鍵盤封裝 數組小鍵盤封裝是指將與數組小鍵盤相關的功能、操作、數據等進行整合&#xff0c;形成一個獨立的、可復用的模塊。封裝數組小鍵盤具有以下幾方面重要意義&#xff1a; 提高代碼可維護性 降低復雜度&#xff1a;數組小鍵盤在實際應用中&#xff0c;可能涉及到…

網工實驗——OSPF配置

網絡拓撲圖 配置 1.為每個路由器配置接口&#xff08;略&#xff09;&#xff08;詳細見RIP實驗&#xff09; 2.配置OSPF AR1 [AR1]ospf [AR1-ospf-1]area 1 [AR1-ospf-1-area-0.0.0.1]network 172.16.1.1 0.0.0.0 #精確配置網絡&#xff0c;也可以像下面那條命令那樣配置 …