# Html 幫助類
任何一個 web 應用程序會生成很多 HTMl 超文本標記。如果超文本標記是靜態的, 那么[將 PHP 和 HTML 混合在一個文件里](http://php.net/manual/en/language.basic-syntax.phpmode.php)?這種做法是非常高效的。但是,如果這些超文本標記是動態生成的,那么如果沒有額外的輔助工具,這個過程將會變得復雜。 Yii 通過 HTML 幫助類來提供生成超文本標記的方法。這個幫助類包含有一系列的用于處理通用的 HTML 標簽和其屬性以及內容的靜態方法。
> 注意:如果你的超文本標記接近靜態的,那么最好是直接使用 HTML。 沒有必要把所有的超文本標記都用 HTML 輔助類來生成。
## 基礎
由于通過字符串連接來生成動態的 HTML 會很容易變得凌亂, Yii 提供了一系列的靜態方法來操作標簽配置并基于這些配置來創建對應的標簽。
### 生成標簽
生成一個標簽的代碼類似如下:
~~~
<?= Html::tag('p', Html::encode($user->name), ['class' => 'username']) ?>
~~~
這個方法的第一個參數是標簽名稱。第二個是要裝入到開始和結束標簽間的內容。 注意到我們使用?`Html::encode`?。那是因為內容不會被自動的轉碼以允許在有需要的時候嵌套 HTML。 第三個參數是一個 HTML 配置數組,或者換言之,標簽屬性。在這個數組中,數組的下標是屬性名稱, 比如?`class`,`href`?或者?`target`,而值則是對應屬性的值。
以上代碼會生成如下 HTML :
~~~
<p class="username">samdark</p>
~~~
如果你只需要開啟一個標簽或者關閉一個標簽,你可以使用?`Html::beginTag()`?和?`Html::endTag()`?方法。
標簽屬性( Options )在 Html 幫助類很多方法和大量的小部件中都有使用。在這些情況下, 有一些額外的處理我們需要知道:
* 如果一個值為 null ,那么對應的屬性將不會被渲染。
* 如果是布爾類型的值的屬性,將會被當做?[布爾屬性](http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes)?來處理。
* 屬性的值將會用 yii\helpers\Html::encode() 方法進行 HTML 轉碼處理。
* 如果一個屬性的值是一個數組,那么它將會被如下處理:
* 如果這個屬性是一個如 yii\helpers\Html::$dataAttributes 所列的數據屬性, 比如?`data`?或者?`ng`,一系列的屬性列表將會被渲染,每個代表值數組中的元素。 比如:?`'data' => ['id' => 1, 'name' => 'yii']`?將會生成?`data-id="1" data-name="yii"`;?`'data' => ['params' => ['id' => 1, 'name' => 'yii'], 'status' => 'ok']`?生成?`data-params='{"id":1,"name":"yii"}' data-status="ok"`。 注意后者 中,一個子數組被輸出為 JSON 。
* 如果這個屬性不是一個數據屬性,那么值將會被 JSON-encoded。比如:`['params' => ['id' => 1, 'name' => 'yii']`?生成?`params='{"id":1,"name":"yii"}'`。
### 生成 CSS 類和樣式
當開始構造一個 HTML 標簽的屬性時,我們經常需要對默認的屬性進行修改。 為了添加或者刪除 CSS 類,你可以使用如下代碼:
~~~
$options = ['class' => 'btn btn-default'];
if ($type === 'success') {
Html::removeCssClass($options, 'btn-default');
Html::addCssClass($options, 'btn-success');
}
echo Html::tag('div', 'Pwede na', $options);
// in case of $type of 'success' it will render
// <div class="btn btn-success">Pwede na</div>
~~~
基于同樣的目的,針對?`style`?屬性:
~~~
$options = ['style' => ['width' => '100px', 'height' => '100px']];
// gives style="width: 100px; height: 200px; position: absolute;"
Html::addCssStyle($options, 'height: 200px; position: absolute;');
// gives style="position: absolute;"
Html::removeCssStyle($options, ['width', 'height']);
~~~
當使用 yii\helpers\Html::addCssStyle() 方法時,你可以指定一個和 CSS 屬性相關的名值對的數組, 也可以直接是一個類似?`width: 100px; height: 200px;`?的字符串。這些格式將會自動的被 yii\helpers\Html::cssStyleFromArray() 和yii\helpers\Html::cssStyleToArray() 方法進行轉換。方法 yii\helpers\Html::removeCssStyle() 接收一個包含要被移除的屬性數組作為參數。 如果只想移除一個屬性,你可以直接傳遞一個字符串。
### 標簽內容的轉碼和解碼
為了讓內容能夠正確安全的顯示,一些 HTML 特殊字符應該被轉碼。在 PHP 中, 這個操作由?[htmlspecialchars](http://www.php.net/manual/en/function.htmlspecialchars.php)?和[htmlspecialchars_decode](http://www.php.net/manual/en/function.htmlspecialchars-decode.php)?完成。 直接使用這些方法的問題是,你總是需要指定轉碼所需的額外標志。由于標志一般總是不變的,而內容轉碼的過程為了避免一些安全問題, 需要和應用的默認過程匹配, Yii 提供了兩個簡單可用的對 PHP 原生方法的封裝:
~~~
$userName = Html::encode($user->name);
echo $userName;
$decodedUserName = Html::decode($userName);
~~~
## 表單
處理表單標簽是大量的重復性勞動并且易錯。因此, Yii 也提供了一系列的方法來輔助處理表單標簽。
> 注意: 考慮在處理 models 以及需要驗證的情形下,使用 yii\widgets\ActiveForm 組件。
### 創建表單
表單可以用類似如下代碼,使用 yii\helpers\Html::beginForm() 方法開啟:
~~~
<?= Html::beginForm(['order/update', 'id' => $id], 'post', ['enctype' => 'multipart/form-data']) ?>
~~~
方法的第一個參數為表單將要被提交的 URL 地址。它可以以 Yii 路由的形式被指定,并由 yii\helpers\Url::to() 來接收處理。 第二個參數是使用的方法,默認為?`post`?方法。第三個參數為表單標簽的屬性數組。在上面的例子中, 我們把編碼 POST 請求中的表單數據的方式改為?`multipart/form-data`。 如果是上傳文件,這個調整是必須的。
關閉表單標簽非常簡單:
~~~
<?= Html::endForm() ?>
~~~
### 按鈕
你可以用如下代碼生成按鈕:
~~~
<?= Html::button('Press me!', ['class' => 'teaser']) ?>
<?= Html::submitButton('Submit', ['class' => 'submit']) ?>
<?= Html::resetButton('Reset', ['class' => 'reset']) ?>
~~~
上述三個方法的第一個參數為按鈕的標題,第二個是標簽屬性。標題默認沒有進行轉碼,如果標題是由終端用輸入的,那么請自行用 yii\helpers\Html::encode() 方法進行轉碼。
### 輸入欄
input 相關的方法有兩組:以?`active`?開頭的被稱為 active inputs,另一組則不以其開頭。 active inputs 依據指定的模型和屬性獲取數據,而普通 input 則是直接指定數據。
一般用法如下:
~~~
type, input name, input value, options
<?= Html::input('text', 'username', $user->name, ['class' => $username]) ?>
type, model, model attribute name, options
<?= Html::activeInput('text', $user, 'name', ['class' => $username]) ?>
~~~
如果你知道 input 類型,更方便的做法是使用以下快捷方法:
* yii\helpers\Html::buttonInput()
* yii\helpers\Html::submitInput()
* yii\helpers\Html::resetInput()
* yii\helpers\Html::textInput(), yii\helpers\Html::activeTextInput()
* yii\helpers\Html::hiddenInput(), yii\helpers\Html::activeHiddenInput()
* yii\helpers\Html::passwordInput() / yii\helpers\Html::activePasswordInput()
* yii\helpers\Html::fileInput(), yii\helpers\Html::activeFileInput()
* yii\helpers\Html::textarea(), yii\helpers\Html::activeTextarea()
Radios 和 checkboxes 在方法的聲明上有一點點不同:
~~~
<?= Html::radio('agree', true, ['label' => 'I agree']);
<?= Html::activeRadio($model, 'agree', ['class' => 'agreement'])
<?= Html::checkbox('agree', true, ['label' => 'I agree']);
<?= Html::activeCheckbox($model, 'agree', ['class' => 'agreement'])
~~~
Dropdown list 和 list box 將會如下渲染:
~~~
<?= Html::dropDownList('list', $currentUserId, ArrayHelper::map($userModels, 'id', 'name')) ?>
<?= Html::activeDropDownList($users, 'id', ArrayHelper::map($userModels, 'id', 'name')) ?>
<?= Html::listBox('list', $currentUserId, ArrayHelper::map($userModels, 'id', 'name')) ?>
<?= Html::activeListBox($users, 'id', ArrayHelper::map($userModels, 'id', 'name')) ?>
~~~
第一個參數是 input 的名稱,第二個是當前選中的值,第三個則是一個下標為列表值, 值為列表標簽的名值對數組。
如果你需要使用多項選擇, checkbox list 應該能夠符合你的需求:
~~~
<?= Html::checkboxList('roles', [16, 42], ArrayHelper::map($roleModels, 'id', 'name')) ?>
<?= Html::activeCheckboxList($user, 'role', ArrayHelper::map($roleModels, 'id', 'name')) ?>
~~~
否則,用 radio list :
~~~
<?= Html::radioList('roles', [16, 42], ArrayHelper::map($roleModels, 'id', 'name')) ?>
<?= Html::activeRadioList($user, 'role', ArrayHelper::map($roleModels, 'id', 'name')) ?>
~~~
### Labels 和 Errors
如同 inputs 一樣,Yii 也提供了兩個方法用于生成表單 label 。 帶 ative 方法用于從 model 中取數據,另外一個則是直接接收數據。
~~~
<?= Html::label('User name', 'username', ['class' => 'label username']) ?>
<?= Html::activeLabel($user, 'username', ['class' => 'label username'])
~~~
為了從一個或者一組 model 中顯示表單的概要錯誤,你可以使用如下方法:
~~~
<?= Html::errorSummary($posts, ['class' => 'errors']) ?>
~~~
為了顯示單個錯誤:
~~~
<?= Html::error($post, 'title', ['class' => 'error']) ?>
~~~
### Input 的名和值
Yii 提供了方法用于從 model 中獲取 input 的名稱,ids,值。這些主要用于內部調用, 但是有時候你也需要使用它們:
~~~
// Post[title]
echo Html::getInputName($post, 'title');
// post-title
echo Html::getInputId($post, 'title');
// my first post
echo Html::getAttributeValue($post, 'title');
// $post->authors[0]
echo Html::getAttributeValue($post, '[0]authors[0]');
~~~
在上面的例子中,第一個參數為模型,而第二個參數是屬性表達式。 在最簡單的表單中,這個屬性表達式就是屬性名稱,但是在一些多行輸入的時候, 它也可以是屬性名以數組下標前綴或者后綴(也可能是同時)。
* `[0]content`?代表多行輸入時第一個 model 的 content 屬性的數據值。
* `dates[0]`?代表 dates 屬性的第一個數組元素。
* `[0]dates[0]`?代表多行輸入時第一個 model 的 dates 屬性的第一個數組元素。
為了獲取一個沒有前綴或者后綴的屬性名稱,我們可以如下做:
~~~
// dates
echo Html::getAttributeName('dates[0]');
~~~
## 樣式表和腳本
Yii 提供兩個方法用于生成包含內聯樣式和腳本代碼的標簽。
~~~
<?= Html::style('.danger { color: #f00; }') ?>
Gives you
<style>.danger { color: #f00; }</style>
<?= Html::script('alert("Hello!");', ['defer' => true]);
Gives you
<script defer>alert("Hello!");</script>
~~~
如果你想要外聯 css 樣式文件,可以如下做:
~~~
<?= Html::cssFile('@web/css/ie5.css', ['condition' => 'IE 5']) ?>
generates
<!--[if IE 5]>
<link href="http://example.com/css/ie5.css" />
<![endif]-->
~~~
第一個參數是 URL。第二個參數是標簽屬性數組。比普通的標簽配置項額外多出的是,你可以指定:
* `condition`?來讓?`<link`?被條件控制注釋包裹( IE hacker )。 希望你在未來不再需要條件控制注釋。
* `noscript`?可以被設置為?`true`?,這樣?`<link`就會被?`<noscript>`包裹,如此那么這段代碼只有在瀏覽器不支持 JavaScript 或者被用戶禁用的時候才會被引入進來。
為了外聯 JavaScript 文件:
~~~
<?= Html::jsFile('@web/js/main.js') ?>
~~~
這個方法的第一個參數同 CSS 一樣用于指定外聯鏈接。第二個參數是一個標簽屬性數組。 同?`cssFile`?一樣,你可以指定?`condtion`配置項。
## 超鏈接
有一個方法可以用于便捷的生成超鏈接:
~~~
<?= Html::a('Profile', ['user/view', 'id' => $id], ['class' => 'profile-link']) ?>
~~~
第一個參數是超鏈接的標題。它不會被轉碼,所以如果是用戶輸入數據, 你需要使用?`Html::encode()`?方法進行轉碼。第二個參數是`<a`?標簽的?`href`?屬性的值。 關于該參數能夠接受的更詳細的數據值,請參閱?[Url::to()](http://www.yiichina.com/doc/guide/2.0/helper-url)。第三個參數是標簽的屬性數組。
在需要的時候,你可以用如下代碼生成?`mailto`?鏈接:
~~~
<?= Html::mailto('Contact us', 'admin@example.com') ?>
~~~
## 圖片
為了生成圖片標簽,你可以如下做:
~~~
<?= Html::img('@web/images/logo.png', ['alt' => 'My logo']) ?>
generates
<img src="/docs/guide/2.0/http://example.com/images/logo.png" alt="My logo" />
~~~
除了?[aliases](http://www.yiichina.com/doc/guide/2.0/concept-aliases)?之外,第一個參數可以接受 路由,查詢,URLs。 同?[Url::to()](http://www.yiichina.com/doc/guide/2.0/helper-url)?一樣。
## 列表
無序列表可以如下生成:
~~~
<?= Html::ul($posts, ['item' => function($item, $index) {
return Html::tag(
'li',
$this->render('post', ['item' => $item]),
['class' => 'post']
);
}]) ?>
~~~
有序列表請使用?`Html::ol()`?方法。
- 介紹(Introduction)
- 關于 Yii(About Yii)
- 從 Yii 1.1 升級(Upgrading from Version 1.1)
- 入門(Getting Started)
- 安裝 Yii(Installing Yii)
- 運行應用(Running Applications)
- 第一次問候(Saying Hello)
- 使用 Forms(Working with Forms)
- 玩轉 Databases(Working with Databases)
- 用 Gii 生成代碼(Generating Code with Gii)
- 更上一層樓(Looking Ahead)
- 應用結構(Application Structure)
- 結構概述(Overview)
- 入口腳本(Entry Scripts)
- 應用(Applications)
- 應用組件(Application Components)
- 控制器(Controllers)
- 模型(Models)
- 視圖(Views)
- 模塊(Modules)
- 過濾器(Filters)
- 小部件(Widgets)
- 前端資源(Assets)
- 擴展(Extensions)
- 請求處理(Handling Requests)
- 運行概述(Overview)
- 引導(Bootstrapping)
- 路由引導與創建 URL(Routing and URL Creation)
- 請求(Requests)
- 響應(Responses)
- Sessions and Cookies
- 錯誤處理(Handling Errors)
- 日志(Logging)
- 關鍵概念(Key Concepts)
- 組件(Components)
- 屬性(Properties)
- 事件(Events)
- 行為(Behaviors)
- 配置(Configurations)
- 別名(Aliases)
- 類自動加載(Class Autoloading)
- 服務定位器(Service Locator)
- 依賴注入容器(Dependency Injection Container)
- 配合數據庫工作(Working with Databases)
- 數據庫訪問(Data Access Objects): 數據庫連接、基本查詢、事務和模式操作
- 查詢生成器(Query Builder): 使用簡單抽象層查詢數據庫
- 活動記錄(Active Record): 活動記錄對象關系映射(ORM),檢索和操作記錄、定義關聯關系
- 數據庫遷移(Migrations): 在團體開發中對你的數據庫使用版本控制
- Sphinx
- Redis
- MongoDB
- ElasticSearch
- 接收用戶數據(Getting Data from Users)
- 創建表單(Creating Forms)
- 輸入驗證(Validating Input)
- 文件上傳(Uploading Files)
- 收集列表輸入(Collecting Tabular Input)
- 多模型同時輸入(Getting Data for Multiple Models)
- 顯示數據(Displaying Data)
- 格式化輸出數據(Data Formatting)
- 分頁(Pagination)
- 排序(Sorting)
- 數據提供器(Data Providers)
- 數據小部件(Data Widgets)
- 操作客戶端腳本(Working with Client Scripts)
- 主題(Theming)
- 安全(Security)
- 認證(Authentication)
- 授權(Authorization)
- 處理密碼(Working with Passwords)
- 客戶端認證(Auth Clients)
- 安全領域的最佳實踐(Best Practices)
- 緩存(Caching)
- 概述(Overview)
- 數據緩存(Data Caching)
- 片段緩存(Fragment Caching)
- 分頁緩存(Page Caching)
- HTTP 緩存(HTTP Caching)
- RESTful Web 服務
- 快速入門(Quick Start)
- 資源(Resources)
- 控制器(Controllers)
- 路由(Routing)
- 格式化響應(Response Formatting)
- 授權驗證(Authentication)
- 速率限制(Rate Limiting)
- 版本化(Versioning)
- 錯誤處理(Error Handling)
- 開發工具(Development Tools)
- 調試工具欄和調試器(Debug Toolbar and Debugger)
- 使用 Gii 生成代碼(Generating Code using Gii)
- TBD 生成 API 文檔(Generating API Documentation)
- 測試(Testing)
- 概述(Overview)
- 搭建測試環境(Testing environment setup)
- 單元測試(Unit Tests)
- 功能測試(Functional Tests)
- 驗收測試(Acceptance Tests)
- 測試夾具(Fixtures)
- 高級專題(Special Topics)
- 高級應用模版(Advanced Project Template)
- 從頭構建自定義模版(Building Application from Scratch)
- 控制臺命令(Console Commands)
- 核心驗證器(Core Validators)
- 國際化(Internationalization)
- 收發郵件(Mailing)
- 性能優化(Performance Tuning)
- 共享主機環境(Shared Hosting Environment)
- 模板引擎(Template Engines)
- 集成第三方代碼(Working with Third-Party Code)
- 小部件(Widgets)
- Bootstrap 小部件(Bootstrap Widgets)
- jQuery UI 小部件(jQuery UI Widgets)
- 助手類(Helpers)
- 助手一覽(Overview)
- Array 助手(ArrayHelper)
- Html 助手(Html)
- Url 助手(Url)