概述
用模板對頁面進行渲染,這是比較經典的一種設計方式了。主要目的是在服務器端進行頁面渲染,以使客戶端瀏覽器可以直接拿到頁面 html 的代碼,這樣對搜索引擎對網站的收錄比較友好。如果是前后端分離的形式,由于前后端交互是用 js 進行,搜索引擎無法對頁面渲染后進行 js 代碼的執行,導致無法獲取最終的 html 頁面結構。所以這種方式對網站的 seo 很不友好,對主要依賴自然搜索流量的站點來說,不要采取前后端分離方式。
Swoft 的這個 View 組件,就是針對服務器端渲染的一個組件。可以自定義網頁公共模板,布局文件。對頁面拆分提供幫助。
詳細說明
@View 注解
-
template:用來標注訪問路由和view 模板的綁定關系
標注了綁定關系,在 Controller/action 執行結束后,才會找此控制器對應的模板,如果 RequestMapping 綁定的 class/method 和 View 組件綁定的模板路徑是同一個,則會自動解析此模板。
-
layout:指定的模板路徑,如果不設置,則會使用 view 組件的默認模板
控制器配置模板
/*** @RequestMapping(route="[/|index.html]", method={"GET"})* @View("home/index")** @param Request $request* @param Response $response* @return Response*/
配置了 @view 注解后,無需在 Controller 的方法中在手動進行 render,方法執行完后,會自動進行頁面渲染。
這個機制是通過自定義的 Middleware 實現的。具體可以參見 vendor/swoft/view/src/Middleware
中的 ViewMiddleware.php
查看源代碼。只要在項目中引入了這個中間件,在處理客戶端請求時候,就會實現 view 的自動加載。
配置 ViewMiddleware
配置 ViewMiddleware 主要有以下幾種方式:
全局配置
可以在 bean.php 定義文件中,配置 httpServer 的 httpDispatcher 全局 Middleware。
所謂全局配置,也就是說,請求沒有異常,所有的請求都會執行完所有的全局配置中間件。
以下這種配置方式,可以看到,會在用戶自定義 UserMiddleware::class
執行后執行 ViewMiddleware,具體,可以參見之前的教程:Middlewares 優先級,里面有關于中間件配置優先級的詳細說明,所有的規則都是來自于對源代碼的了解。
'httpDispatcher' => ['middlewares' => [\Swoft\Http\Session\SessionMiddleware::class,\Swoft\Http\Server\Middleware\ValidatorMiddleware::class,],'afterMiddlewares' => [\Swoft\View\Middleware\ViewMiddleware::class,]],
通過 @Middleware 注解進行配置 ViewMiddleware 中間件
首先我們知道 @Middleware 注解的可配置對象為:“CLASS”, “METHOD”, “ANNOTATION”,如下源碼:
/*** Class Middleware** @since 2.0** @Annotation* @Target({"CLASS", "METHOD", "ANNOTATION"})* @Attributes({* @Attribute("name", type="string"),* })*/
final class Middleware
配置類注解
也就是說,這個注解可以配置針對一個類的所有方法,比如配置到 TestController 類注解上,表示 TestController 中的任何一個方法執行時候,都會在 UserMiddleware::class
級別自動將指定的中間件動態添加(詳見 Middlewares 優先級說明)。這樣,只有訪問到這個控制器的請求才會執行到對應的中間件。
配置方法注解
如題,將 @Middleware 注解配置到方法上,只有請求指定控制器的綁定了 @Middleware 注解的方法,才會執行對應的中間件邏輯。
配置注解的注解
/*** Class AuthRoleController** @since 2.0* @Controller("auth/role")* @Middlewares({* @Middleware(ViewMiddleware::class),* @Middleware(AuthMiddleware::class)* })*/
@Middleware 注解可以配置到 @Middlewares 注解之中。@Middlewares 注解,如其名字,就是可以綁定多個中間件,執行順序按照綁定的順序從上往下執行。
模板代碼使用
當指定的方法或者類已經綁定了 ViewMiddleware::class
中間件,一旦控制器中的邏輯執行完畢,后續就會自動執行當前方法綁定的模板頁面。
以下示例中這個方法就是訪問網站首頁時候,會在 resource/views
(默認模板存放路徑)下尋找 home/index.php
,如果有這個文件,就會執行渲染。
/*** @RequestMapping(route="[/|index.html]", method={"GET"})* @View("home/index")** @param Request $request* @param Response $response* @return Response*/
代碼渲染類 Renderder::class
// 此段代碼摘自 ViewMiddleware 中間件 process 方法中
$actionId = $route->getHandler();
if (!$info = ViewRegister::findBindView($actionId)) {return $response;
}// Get layout and template
[$template, $layout] = $info;// Accept list
$allowedAccepts = $request->getHeader('accept');
$currentAccept = current($allowedAccepts);
$contentType = ContentType::HTML;if ($template && false !== strpos($currentAccept, $contentType)) {$data = $response->getData();if (is_object($data) && $data instanceof Arrayable) {$data = $data->toArray();}/* @var Renderer $view */$renderer = bean('view'); // 此處為獲取模板渲染的對象$content = $renderer->render($template, $data, $layout);return $response->withContent($content)->withContentType($contentType);
}
由以上代碼可見,最終調用了 Renderer::class->render
渲染的模板。模板中使用的為控制器傳遞過來的 data 參數數組。
// 在控制器執行完畢時候,將要渲染的變量傳遞給模板,這里的 data 就是渲染到模板中的參數集合。
$data = ['test' => 'this is a test.'
];
return $response->withData($data);
在模板中使用 $this
變量是可以的,這個指向了 Renderer 對象實例。使用參數時候可以直接調用 $data['test']
中的參數。也可以直接使用 $data
變量中的一級鍵名作為變量名(也就是直接用 $test
)。因為在模板渲染時候,render 方法中使用了以下代碼:
protected function protectedIncludeScope($file, array $data): void
{extract($data, EXTR_OVERWRITE);include $file; // 特別注意:千萬不要在 data 中放入 file 鍵,會將此處模板名給覆蓋掉。
}
剩下的就是在模板中進行 php html 混編了,這個都是基礎,不在贅述。
PHP Swoft2 開源框架系列教程專欄推薦
Swoft2 框架精華教程:Validator 校驗器詳解
Swoft 框架精華教程:Devtool 詳解
Swoft2 框架精華教程:Controller 組件解析,使用說明
Swoft2 框架精華教程:Config 配置解析,使用說明
Swoft2 框架精華教程:CLog 使用篇
Swoft2 框架精華教程:數據庫 Migration
Swoft2 框架精華教程:數據庫操作
Swoft2 框架精華教程: Swoft 組件開發單元測試
Swoft2 框架精華教程:面向切面編程(Aspect)
Swoft2 框架精華教程:Annotation 注解機制詳解
Swoft 框架精華教程:Bean 定義的實例化
Swoft2 框架精華教程:Swoft 的視圖組件
Swoft2 框架精華教程:Swoft 的啟動過程與核心源代碼解析
Swoft2 框架精華教程:Middlewares 優先級