Yii2—檢視(View)
阿新 • • 發佈:2019-01-06
檢視(View)
檢視(View)這一部分比較多,總共包括11個知識點:
- 基本定義
- 部件(Widget)
- 安全
- 模板引擎
- 在模板中使用檢視物件
- 設定頁面標題
- 新增meta標籤
- 註冊連線標籤
- 註冊CSS
- 註冊指令碼
- 註冊asset bundles
- 佈局(Layout)
- 區域性(Partial)
- 訪問上下文
- 靜態頁面
- 快取區塊
- 自定義檢視元件
檢視基本上就是我們所說的在views資料夾中的顯示前臺頁面的模板。另外還有一個對應的檢視類(yii\web\view)這個是在Yii2中新增加的,我們在views中的模板檔案中看到的$this物件就是Yii2中的檢視物件。 我們下面就用模板來稱呼前臺view中的檢視,以便和yii\web\view這個檢視類混淆。
預設情況下,Yii使用php語言來解析模板,也就是說在views中的模板裡面直接用php程式碼來輸出資料。
在模板頁面最好不要包含複雜的php邏輯程式碼,應該儘可能的把它們放到控制器或者部件裡面去實現。
模板一般在控制器中的動作(Action)裡執行render()
- public function actionIndex()
- {
- return $this->render('index', ['username' => 'samdark']);
- }
在這裡只需要新增模板的檔名就可以了,不用加路徑以及字尾。Yii會在當前控制器的ID(如site)目錄下搜尋這個模板檔案。
如當前控制器是SiteController,那個將會在views/site目錄下面搜尋index檔案。
如果想知道Yii是怎樣查詢檢視檔案的可以檢視yii\base\Controller::render()
第二個引數是一個name-value的陣列。這個陣列會直接傳遞到views目錄中的模板檔案裡面,並且name可直接作為php變數來引用,value就是對應的變數的值。如上面的index檢視檔案為views/site/index.php
- <p>Hello, <?= $username ?>!</p>
除了上面說的render()方法外,在yii\web\Controller中還有幾種載入檢視的方法:
- render():渲染一個模板,然後對渲染的結果應用佈局檔案。這個是通常用來渲染一個完整的頁面。
- renderPartial():僅僅渲染一個模板,不對渲染的結果使用佈局檔案。通常用來渲染頁面的區域性。
- renderAjax():也是隻渲染模板,不使用佈局檔案,但會載入所有註冊的js/css等指令碼檔案。通常把渲染的html程式碼作為Ajax請求的響應。
- renderFile()渲染一個模板檔案,基本和renderPartial()功能一樣,只不過這裡要求的是檔案的路徑而不是檔案的名稱。
部件是檢視中的獨立的區塊,用來把一些複雜的邏輯、頁面顯示及相應的功能實到一個獨立的元件中。
Yii內建很多常用的部件,如表單(active form),麵包屑(breadcrumbs),選單(menu)以及對bootstrap的包裝。另外在某些擴充套件元件中也提供了部件,如官方的jQueryUI元件。
下面是在檢視檔案中使用部件的例子:
- // Note that you have to "echo" the result to display it
- //輸出部件Menu中的內容
- echo \yii\widgets\Menu::widget(['items' => $items]);
- // Passing an array to initialize the object properties
- //可往部件中傳遞引數來初始化部件
- $form = \yii\widgets\ActiveForm::begin([
- 'options' => ['class' => 'form-horizontal'],
- 'fieldConfig' => ['inputOptions' => ['class' => 'input-xlarge']],
- ]);
- ... form inputs here ...
- \yii\widgets\ActiveForm::end();
3、安全
最主要的安全規則之一就是對所有的輸出進行編碼,如果違反這一規則將會導致指令碼執行漏洞,最大可能會導致XSS跨域站點攻擊以到管理員密碼。
Yii提供了一系列的工具來幫助你實現對輸出的編碼。最基本的過濾標籤的程式碼如下:
- <?php
- use yii\helpers\Html;
- ?>
- <div class="username">
- <?= Html::encode($user->name) ?>
- </div>
- <?php
- use yii\helpers\HtmlPurifier;
- ?>
- <div class="post">
- <?= HtmlPurifier::process($post->text) ?>
- </div>
4、模板引擎
我們還提供了2個官方的模板引擎Smarty和Twig,想了解更多情況可以檢視這裡使用模板引擎(Using template engines )
5、在模板中使用檢視物件
yii\web\View元件的物件可以在模板裡面直接使用,即模板檢視中的$this變數。有了這個變數可以進行更多的操作,如設定頁面的標題、meta資訊、指令碼和訪問當前的上下文物件。
1、設定頁面標題
- $this->title = 'My page title';
meta標籤如encoding、keywords、description等
- $this->registerMetaTag(['encoding' => 'utf-8']);
- <meta encoding="utf-8">
- $this->registerMetaTag(['name' => 'description', 'content' => 'This is my cool website made with Yii!'], 'meta-description');
- $this->registerMetaTag(['name' => 'description', 'content' => 'This website is about funny raccoons.'], 'meta-description');
- <meta name="description" content="This website is about funny raccoons.">
<link>標籤在很多情況下都很有用,如自定義favicon、RSS等等
- $this->registerLinkTag([
- 'title' => 'Lives News for Yii Framework',
- 'rel' => 'alternate',
- 'type' => 'application/rss+xml',
- 'href' => 'http://www.yiiframework.com/rss.xml/',
- ]);
- <link title="Lives News for Yii Framework" rel="alternate" type="application/rss+xml" href="http://www.yiiframework.com/rss.xml/" />
4、註冊CSS
還可以用檢視物件中的registerCss()或registerCssFile()來註冊CSS。registerCss()方法用來註冊CSS程式碼段,registerCssFile()用來註冊一個外部CSS檔案。
- $this->registerCss("body { background: #f00; }");
- <style>
- body { background: #f00; }
- </style>
- $this->registerCssFile("http://example.com/css/themes/black-and-white.css", [BootstrapAsset::className()], ['media' => 'print'], 'css-print-theme');
- 第一個引數指定要新增的css檔案
- 第二個引數指定這個css檔案依賴的BootstrapAsset。意思是說在BootstrapAsset裡面的css檔案載入完成之後才載入剛才指定的css檔案。如果沒有指定依賴項那麼這個css檔案和BootstrapAsset裡面的css檔案的將沒有先後順序。
- 第三個引數設定<link>標籤的其它屬性的值。
- 最後一個引數用來唯一標識這個css檔案。如果沒有指定的話將會用這個css的URL連線。
5、註冊指令碼
利用yii\web\View 還可以註冊指令碼檔案。註冊指令碼也有2個方法,registerJs()用來註冊內部js程式碼,registerJsFile()用來註冊外部Js檔案。內部js程式碼可用於配置或者動態生成程式碼的時候,
- $this->registerJs("var options = ".json_encode($options).";", View::POS_END, 'my-options');
第二個引數指定js指令碼新增到頁面的位置。
- View::POS_HEAD 在頭部新增
- View::POS_BEGIN 在[color=Red]<body>[/color]標籤開始之後
- View::POS_END 在[color=Red]</body>[/color]標籤結束之前
- View::POS_READY 在document [color=Red]ready[/color] event 準備好之後,這個會自動註冊並使用jQuery。
- View::POS_LOAD 在 document [color=Red]load[/color] event 準備好之後, 這個會自動註冊並使用jQuery。
外部Js程式碼新增如下
- $this->registerJsFile('http://example.com/js/main.js', [JqueryAsset::className()]);
和registerCssFile()一樣,我們也建議你使用asset bundles來註冊外部js檔案而不是使用registerJsFile()。
6、註冊asset bundles
如先前所提到的,在頁面中最好使用asset bundles,而不是直接在頁面中使用css和javascript。關於asset bundles的相關資訊可以檢視asset manager。
使用已經定義的asset bundles程式碼如下
- \frontend\assets\AppAsset::register($this);
在一個應用中如果大部分的頁面顯示的內容基本相同,那麼使用全域性佈局檔案無疑是最好的選擇。
佈局檔案中一般包括頭部、尾部、主選單以及其它在所有頁面公共的部分。下面這個是最基本的一個佈局檔案。
- <?php
- use yii\helpers\Html;
- ?>
- <?php $this->beginPage() ?>
- <!DOCTYPE html>
- <html lang="<?= Yii::$app->language ?>">
- <head>
- <meta charset="<?= Yii::$app->charset ?>"/>
- <title><?= Html::encode($this->title) ?></title>
- <?php $this->head() ?>
- </head>
- <body>
- <?php $this->beginBody() ?>
- <div class="container">
- <?= $content ?>
- </div>
- <footer class="footer"> 2013 me :)</footer>
- <?php $this->endBody() ?>
- </body>
- </html>
- <?php $this->endPage() ?>
在程式碼的開始,我們使用php的方法use來引入Html幫助類。這個類主要功能就是用於對輸出的結果進行編碼。
另外還有一些特殊的方法如beginPage()/endPage(), head(), beginBody()/endBody() 這些在渲染頁面的時候都觸發相應的事件。你可以在這些事件裡面註冊指令碼、連線以及處理頁面等等。
7、區域性檢視(Partial)
有時候一些Html程式碼需要在多個檢視頁面使用,大多部情況下這些Html程式碼太簡單了以至於建立部件(Widget)有點浪費。
區域性檢視也是檢視檔案,它也存在於views目錄下面並且檔名以“_”開頭。例如我們要顯示所有使用者資訊的列表,同時還在其它地方顯示一個單獨使用者的資訊。
首先定義使用者資訊的區域性檔案_profile.php
- <?php
- use yii\helpers\Html;
- ?>
- <div class="profile">
- <h2><?= Html::encode($username) ?></h2>
- <p><?= Html::encode($tagline) ?></p>
- </div>
- <div class="user-index">
- <?php
- foreach ($users as $user) {
- echo $this->render('_profile', [
- 'username' => $user->name,
- 'tagline' => $user->tagline,
- ]);
- }
- ?>
- </div>
- echo $this->render('_profile', [
- 'username' => $user->name,
- 'tagline' => $user->tagline,
- ]);
另外也可以在路徑中使用別名,如@app/views/common/_profile
除了另外還可以使用絕對路徑加上檢視的名稱如/user/_profile、 //user/_profile。絕對路徑要以“/”或者"//"開頭。如果以“/”開頭將會從當前模組的view路徑裡面查詢,如果以"//"開頭,前者會從應用程式的view路徑中查詢
8、訪問上下文
檢視檔案一般由控制器或者部件來呼叫,在這兩種情況下我們都可以通過檢視物件的$this->context來得到相應的控制器或者部件。例如想在當前的檢視中得到路由資訊可以用
- echo $this->context->getRoute();
9、靜態頁面
如果需要渲染一個靜態頁面可以使用ViewAction類。它會根據使用者的設定呼叫這個action來顯示相應的檢視檔案。
首先在控制器裡面的actions裡面
- class SiteController extends Controller
- {
- public function actions()
- {
- return [
- 'static' => [
- 'class' => '\yii\web\ViewAction',
- ],
- ];
- }
- //...
- }
- //index.php
- <h1>Hello, I am a static page!</h1>
預設情況下是通過GET引數中的view變數來顯示相應的靜態檔案的。如果URL為/index.php?r=site/static?&view=about那麼將會顯示@app/views/site/pages/about.php靜態檔案。
靜態檔案預設按照如下順序來顯示
- 獲取GET引數:view
- 如果沒有指定view引數,將使用預設的index.php靜態檔案。
- 在靜態檔案的目錄中查詢相應的檔案(viewPrefix):pages為目錄
- 使用相應的佈局檔案。
10、快取區塊
關於對區塊的快取可以檢視快取章節
11、自定義檢視元件
由於view也是一個應用程式元件,所以你可以替換為你自己自定義的元件。自定義的檢視元件一般從yii\base\View或者yii\web\View繼承。可以在應用程式的配置檔案(如config/web.php)中進行設定:
- return [
- // ...
- 'components' => [
- 'view' => [
- 'class' => 'app\components\View',
- ],
- // ...
- ],
- ];