Html 助手(Html)

2018-02-24 15:40 更新

Html 幫助類

任何一個(gè) web 應(yīng)用程序會生成很多 HTMl 超文本標(biāo)記。如果超文本標(biāo)記是靜態(tài)的, 那么將 PHP 和 HTML 混合在一個(gè)文件里?這種做法是非常高效的。但是,如果這些超文本標(biāo)記是動態(tài)生成的,那么如果沒有額外的輔助工具,這個(gè)過程將會變得復(fù)雜。 Yii 通過 HTML 幫助類來提供生成超文本標(biāo)記的方法。這個(gè)幫助類包含有一系列的用于處理通用的 HTML 標(biāo)簽和其屬性以及內(nèi)容的靜態(tài)方法。

注意:如果你的超文本標(biāo)記接近靜態(tài)的,那么最好是直接使用 HTML。 沒有必要把所有的超文本標(biāo)記都用 HTML 輔助類來生成。

基礎(chǔ)

由于通過字符串連接來生成動態(tài)的 HTML 會很容易變得凌亂, Yii 提供了一系列的靜態(tài)方法來操作標(biāo)簽配置并基于這些配置來創(chuàng)建對應(yīng)的標(biāo)簽。

生成標(biāo)簽

生成一個(gè)標(biāo)簽的代碼類似如下:

<?= Html::tag('p', Html::encode($user->name), ['class' => 'username']) ?>

這個(gè)方法的第一個(gè)參數(shù)是標(biāo)簽名稱。第二個(gè)是要裝入到開始和結(jié)束標(biāo)簽間的內(nèi)容。 注意到我們使用?Html::encode?。那是因?yàn)閮?nèi)容不會被自動的轉(zhuǎn)碼以允許在有需要的時(shí)候嵌套 HTML。 第三個(gè)參數(shù)是一個(gè) HTML 配置數(shù)組,或者換言之,標(biāo)簽屬性。在這個(gè)數(shù)組中,數(shù)組的下標(biāo)是屬性名稱, 比如?class,href?或者?target,而值則是對應(yīng)屬性的值。

以上代碼會生成如下 HTML :

<p class="username">samdark</p>

如果你只需要開啟一個(gè)標(biāo)簽或者關(guān)閉一個(gè)標(biāo)簽,你可以使用?Html::beginTag()?和?Html::endTag()?方法。

標(biāo)簽屬性( Options )在 Html 幫助類很多方法和大量的小部件中都有使用。在這些情況下, 有一些額外的處理我們需要知道:

  • 如果一個(gè)值為 null ,那么對應(yīng)的屬性將不會被渲染。
  • 如果是布爾類型的值的屬性,將會被當(dāng)做?布爾屬性?來處理。
  • 屬性的值將會用 yii\helpers\Html::encode() 方法進(jìn)行 HTML 轉(zhuǎn)碼處理。
  • 如果一個(gè)屬性的值是一個(gè)數(shù)組,那么它將會被如下處理:

    • 如果這個(gè)屬性是一個(gè)如 yii\helpers\Html::$dataAttributes 所列的數(shù)據(jù)屬性, 比如?data?或者?ng,一系列的屬性列表將會被渲染,每個(gè)代表值數(shù)組中的元素。 比如:?'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"。 注意后者 中,一個(gè)子數(shù)組被輸出為 JSON 。
    • 如果這個(gè)屬性不是一個(gè)數(shù)據(jù)屬性,那么值將會被 JSON-encoded。比如:['params' => ['id' => 1, 'name' => 'yii']?生成?params='{"id":1,"name":"yii"}'。

生成 CSS 類和樣式

當(dāng)開始構(gòu)造一個(gè) HTML 標(biāo)簽的屬性時(shí),我們經(jīng)常需要對默認(rèn)的屬性進(jìn)行修改。 為了添加或者刪除 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']);

當(dāng)使用 yii\helpers\Html::addCssStyle() 方法時(shí),你可以指定一個(gè)和 CSS 屬性相關(guān)的名值對的數(shù)組, 也可以直接是一個(gè)類似?width: 100px; height: 200px;?的字符串。這些格式將會自動的被 yii\helpers\Html::cssStyleFromArray() 和yii\helpers\Html::cssStyleToArray() 方法進(jìn)行轉(zhuǎn)換。方法 yii\helpers\Html::removeCssStyle() 接收一個(gè)包含要被移除的屬性數(shù)組作為參數(shù)。 如果只想移除一個(gè)屬性,你可以直接傳遞一個(gè)字符串。

標(biāo)簽內(nèi)容的轉(zhuǎn)碼和解碼

為了讓內(nèi)容能夠正確安全的顯示,一些 HTML 特殊字符應(yīng)該被轉(zhuǎn)碼。在 PHP 中, 這個(gè)操作由?htmlspecialchars?和htmlspecialchars_decode?完成。 直接使用這些方法的問題是,你總是需要指定轉(zhuǎn)碼所需的額外標(biāo)志。由于標(biāo)志一般總是不變的,而內(nèi)容轉(zhuǎn)碼的過程為了避免一些安全問題, 需要和應(yīng)用的默認(rèn)過程匹配, Yii 提供了兩個(gè)簡單可用的對 PHP 原生方法的封裝:

$userName = Html::encode($user->name);
echo $userName;

$decodedUserName = Html::decode($userName);

表單

處理表單標(biāo)簽是大量的重復(fù)性勞動并且易錯(cuò)。因此, Yii 也提供了一系列的方法來輔助處理表單標(biāo)簽。

注意: 考慮在處理 models 以及需要驗(yàn)證的情形下,使用 yii\widgets\ActiveForm 組件。

創(chuàng)建表單

表單可以用類似如下代碼,使用 yii\helpers\Html::beginForm() 方法開啟:

<?= Html::beginForm(['order/update', 'id' => $id], 'post', ['enctype' => 'multipart/form-data']) ?>

方法的第一個(gè)參數(shù)為表單將要被提交的 URL 地址。它可以以 Yii 路由的形式被指定,并由 yii\helpers\Url::to() 來接收處理。 第二個(gè)參數(shù)是使用的方法,默認(rèn)為?post?方法。第三個(gè)參數(shù)為表單標(biāo)簽的屬性數(shù)組。在上面的例子中, 我們把編碼 POST 請求中的表單數(shù)據(jù)的方式改為?multipart/form-data。 如果是上傳文件,這個(gè)調(diào)整是必須的。

關(guān)閉表單標(biāo)簽非常簡單:

<?= Html::endForm() ?>

按鈕

你可以用如下代碼生成按鈕:

<?= Html::button('Press me!', ['class' => 'teaser']) ?>
<?= Html::submitButton('Submit', ['class' => 'submit']) ?>
<?= Html::resetButton('Reset', ['class' => 'reset']) ?>

上述三個(gè)方法的第一個(gè)參數(shù)為按鈕的標(biāo)題,第二個(gè)是標(biāo)簽屬性。標(biāo)題默認(rèn)沒有進(jìn)行轉(zhuǎn)碼,如果標(biāo)題是由終端用輸入的,那么請自行用 yii\helpers\Html::encode() 方法進(jìn)行轉(zhuǎn)碼。

輸入欄

input 相關(guān)的方法有兩組:以?active?開頭的被稱為 active inputs,另一組則不以其開頭。 active inputs 依據(jù)指定的模型和屬性獲取數(shù)據(jù),而普通 input 則是直接指定數(shù)據(jù)。

一般用法如下:

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 在方法的聲明上有一點(diǎn)點(diǎn)不同:

<?= 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')) ?>

第一個(gè)參數(shù)是 input 的名稱,第二個(gè)是當(dāng)前選中的值,第三個(gè)則是一個(gè)下標(biāo)為列表值, 值為列表標(biāo)簽的名值對數(shù)組。

如果你需要使用多項(xiàng)選擇, checkbox list 應(yīng)該能夠符合你的需求:

<?= 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 也提供了兩個(gè)方法用于生成表單 label 。 帶 ative 方法用于從 model 中取數(shù)據(jù),另外一個(gè)則是直接接收數(shù)據(jù)。

<?= Html::label('User name', 'username', ['class' => 'label username']) ?>
<?= Html::activeLabel($user, 'username', ['class' => 'label username'])

為了從一個(gè)或者一組 model 中顯示表單的概要錯(cuò)誤,你可以使用如下方法:

<?= Html::errorSummary($posts, ['class' => 'errors']) ?>

為了顯示單個(gè)錯(cuò)誤:

<?= Html::error($post, 'title', ['class' => 'error']) ?>

Input 的名和值

Yii 提供了方法用于從 model 中獲取 input 的名稱,ids,值。這些主要用于內(nèi)部調(diào)用, 但是有時(shí)候你也需要使用它們:

// 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]');

在上面的例子中,第一個(gè)參數(shù)為模型,而第二個(gè)參數(shù)是屬性表達(dá)式。 在最簡單的表單中,這個(gè)屬性表達(dá)式就是屬性名稱,但是在一些多行輸入的時(shí)候, 它也可以是屬性名以數(shù)組下標(biāo)前綴或者后綴(也可能是同時(shí))。

  • [0]content?代表多行輸入時(shí)第一個(gè) model 的 content 屬性的數(shù)據(jù)值。
  • dates[0]?代表 dates 屬性的第一個(gè)數(shù)組元素。
  • [0]dates[0]?代表多行輸入時(shí)第一個(gè) model 的 dates 屬性的第一個(gè)數(shù)組元素。

為了獲取一個(gè)沒有前綴或者后綴的屬性名稱,我們可以如下做:

// dates
echo Html::getAttributeName('dates[0]');

樣式表和腳本

Yii 提供兩個(gè)方法用于生成包含內(nèi)聯(lián)樣式和腳本代碼的標(biāo)簽。

<?= 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>

如果你想要外聯(lián) css 樣式文件,可以如下做:

<?= Html::cssFile('@web/css/ie5.css', ['condition' => 'IE 5']) ?>

generates

<!--[if IE 5]>
    <link  rel="external nofollow" target="_blank"  />
<![endif]-->

第一個(gè)參數(shù)是 URL。第二個(gè)參數(shù)是標(biāo)簽屬性數(shù)組。比普通的標(biāo)簽配置項(xiàng)額外多出的是,你可以指定:

  • condition?來讓?<link?被條件控制注釋包裹( IE hacker )。 希望你在未來不再需要條件控制注釋。
  • noscript?可以被設(shè)置為?true?,這樣?<link就會被?<noscript>包裹,如此那么這段代碼只有在瀏覽器不支持 JavaScript 或者被用戶禁用的時(shí)候才會被引入進(jìn)來。

為了外聯(lián) JavaScript 文件:

<?= Html::jsFile('@web/js/main.js') ?>

這個(gè)方法的第一個(gè)參數(shù)同 CSS 一樣用于指定外聯(lián)鏈接。第二個(gè)參數(shù)是一個(gè)標(biāo)簽屬性數(shù)組。 同?cssFile?一樣,你可以指定?condtion配置項(xiàng)。

超鏈接

有一個(gè)方法可以用于便捷的生成超鏈接:

<?= Html::a('Profile', ['user/view', 'id' => $id], ['class' => 'profile-link']) ?>

第一個(gè)參數(shù)是超鏈接的標(biāo)題。它不會被轉(zhuǎn)碼,所以如果是用戶輸入數(shù)據(jù), 你需要使用?Html::encode()?方法進(jìn)行轉(zhuǎn)碼。第二個(gè)參數(shù)是<a?標(biāo)簽的?href?屬性的值。 關(guān)于該參數(shù)能夠接受的更詳細(xì)的數(shù)據(jù)值,請參閱?Url::to()。第三個(gè)參數(shù)是標(biāo)簽的屬性數(shù)組。

在需要的時(shí)候,你可以用如下代碼生成?mailto?鏈接:

<?= Html::mailto('Contact us', 'admin@example.com') ?>

圖片

為了生成圖片標(biāo)簽,你可以如下做:

<?= Html::img('@web/images/logo.png', ['alt' => 'My logo']) ?>

generates

<img src="https://atts.w3cschool.cn/attachments/image/cimg/logo.png" alt="My logo" />

除了?aliases?之外,第一個(gè)參數(shù)可以接受 路由,查詢,URLs。 同?Url::to()?一樣。

列表

無序列表可以如下生成:

<?= Html::ul($posts, ['item' => function($item, $index) {
    return Html::tag(
        'li',
        $this->render('post', ['item' => $item]),
        ['class' => 'post']
    );
}]) ?>

有序列表請使用?Html::ol()?方法。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號