0 关注者

Html 助手

每个 Web 应用程序都会生成大量的 HTML 标记。如果标记是静态的,可以通过 在一个文件中混合使用 PHP 和 HTML 来有效地完成,但当它动态生成时,如果没有额外的帮助,处理它就会变得很棘手。Yii 以 Html 助手形式提供了这种帮助,它提供了一组静态方法来处理常用的 HTML 标签、其选项及其内容。

注意:如果您的标记几乎是静态的,最好直接使用 HTML。没有必要将所有东西都包装在 Html 助手调用中。

基础

由于通过字符串连接来构建动态 HTML 很快就会变得很混乱,Yii 提供了一组方法来操作标签选项并根据这些选项构建标签。

生成标签

生成标签的代码如下所示

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

第一个参数是标签名称。第二个是包含在开始标签和结束标签之间的内容。请注意,我们正在使用 Html::encode - 这是因为内容不会自动编码,以允许在需要时使用 HTML。第三个是一个 HTML 选项数组,或者换句话说,标签属性。在这个数组中,键是属性的名称(例如 classhreftarget),而值是它的值。

上面的代码将生成以下 HTML

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

如果您只需要一个开始标签或结束标签,可以使用 Html::beginTag()Html::endTag() 方法。

选项在 Html 助手的许多方法和各种小部件中使用。在所有这些情况下,有一些额外的处理需要了解

  • 如果一个值为 null,则相应的属性将不会被渲染。
  • 值为布尔类型属性将被视为 布尔属性
  • 属性的值将使用 Html::encode() 进行 HTML 编码。
  • 如果属性的值是一个数组,它将按如下方式处理

    • 如果属性是 yii\helpers\Html::$dataAttributes 中列出的数据属性,例如 datang,则会渲染一个属性列表,每个元素对应于值数组中的一个元素。例如,'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 编码。例如,['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);

// if the value of $type is 'success' it will render
// <div class="btn btn-success">Pwede na</div>

您也可以使用数组样式来指定多个 CSS 类

$options = ['class' => ['btn', 'btn-default']];

echo Html::tag('div', 'Save', $options);
// renders '<div class="btn btn-default">Save</div>'

您也可以在添加或删除类时使用数组样式

$options = ['class' => 'btn'];

if ($type === 'success') {
    Html::addCssClass($options, ['btn-success', 'btn-lg']);
}

echo Html::tag('div', 'Save', $options);
// renders '<div class="btn btn-success btn-lg">Save</div>'

Html::addCssClass() 可以防止重复,因此您不必担心同一个类出现两次

$options = ['class' => 'btn btn-default'];

Html::addCssClass($options, 'btn-default'); // class 'btn-default' is already present

echo Html::tag('div', 'Save', $options);
// renders '<div class="btn btn-default">Save</div>'

如果 CSS 类选项使用数组样式指定,则可以使用命名键来标记类的逻辑用途。在这种情况下,Html::addCssClass() 将忽略数组样式中具有相同键的类

$options = [
    'class' => [
        'btn',
        'theme' => 'btn-default',
    ]
];

Html::addCssClass($options, ['theme' => 'btn-success']); // 'theme' key is already taken

echo Html::tag('div', 'Save', $options);
// renders '<div class="btn btn-default">Save</div>'

CSS 样式可以使用 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']);

使用 addCssStyle() 时,您可以指定一个键值对数组,对应于 CSS 属性名和值,或者一个字符串,例如 width: 100px; height: 200px;。可以使用 cssStyleFromArray()cssStyleToArray() 将这些格式从一种转换为另一种。removeCssStyle() 方法接受一个要删除的属性数组。如果它是一个单个属性,则可以将其指定为字符串。

编码和解码内容

为了使内容在 HTML 中正确安全地显示,应该对内容中的特殊字符进行编码。在 PHP 中,这可以通过 htmlspecialcharshtmlspecialchars_decode 来完成。直接使用这些方法的问题是,您必须始终指定编码和额外的标志。由于这些标志始终相同,并且编码应该与应用程序的编码匹配以防止安全问题,因此 Yii 提供了两种简洁易用的方法

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

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

表单

处理表单标记非常重复且容易出错。因此,有一组方法可以帮助处理它们。

注意:如果您正在处理模型并需要验证,请考虑使用 ActiveForm

创建表单

可以使用 beginForm() 方法打开表单,如下所示

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

第一个参数是表单将提交到的 URL。它可以以 Yii 路由和 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']) ?>

所有三种方法的第一个参数是按钮标题,第二个参数是选项数组。标题不会被编码,因此,如果您要显示来自最终用户的數據,请使用 Html::encode() 对其进行编码。

输入字段

有两组输入方法。以 active 开头的那些被称为活动输入,而那些不以 active 开头的。活动输入从模型和指定的属性获取数据,而在常规输入的情况下,数据是直接指定的。

最通用的方法是

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]) ?>

如果您事先知道输入类型,则使用快捷方法更方便

单选按钮和复选框在方法签名方面略有不同

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

下拉列表和列表框可以像下面这样渲染

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

第一个参数是输入的名称,第二个参数是当前选择的 value,第三个参数是键值对数组,其中数组键是列表 value,数组值是列表标签。

如果希望选择多个选项,可以使用复选框列表

<?= Html::checkboxList('roles', [16, 42], ArrayHelper::map($roleModels, 'id', 'name')) ?>
<?= Html::activeCheckboxList($user, 'role', ArrayHelper::map($roleModels, 'id', 'name')) ?>

否则,使用单选按钮列表

<?= Html::radioList('roles', [16, 42], ArrayHelper::map($roleModels, 'id', 'name')) ?>
<?= Html::activeRadioList($user, 'role', ArrayHelper::map($roleModels, 'id', 'name')) ?>

标签和错误

与输入一样,还有两种方法用于生成表单标签。Active,它从模型中获取数据,非 Active,它直接接受数据

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

为了将模型或模型中的表单错误作为摘要显示,您可以使用

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

要显示单个错误

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

输入名称和值

有一些方法可以根据模型获取输入字段的名称、ID 和值。这些主要在内部使用,但有时可能很方便

// 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 用于表格数据输入,以表示表格输入中第一个模型的 content 属性;
  • dates[0] 表示 dates 属性的第一个数组元素;
  • [0]dates[0] 表示表格输入中第一个模型的 dates 属性的第一个数组元素。

为了获取没有后缀或前缀的属性名,可以使用以下方法

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

样式和脚本

有两种方法可以生成包含嵌入式样式和脚本的标签

<?= Html::style('.danger { color: #f00; }', ['media' => 'print']) ?>

Gives you

<style media="print">.danger { color: #f00; }</style>


<?= Html::script('alert("Hello!");') ?>

Gives you

<script>alert("Hello!");</script>

如果您想在 CSS 文件中使用外部样式

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

generates

<!--[if IE 5]>
    <link href="https://example.com/css/ie5.css" />
<![endif]-->

第一个参数是 URL。第二个参数是选项数组。除了常规选项外,您还可以指定

  • condition 以使用指定的条件在条件注释中包装 <link。希望您永远不需要使用条件注释;)
  • noscript 可以设置为 true 以将 <link 包装在 <noscript> 标签中,以便只有在浏览器不支持 JavaScript 或被用户禁用时才会包含它。

链接 JavaScript 文件

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

与 CSS 一样,第一个参数指定要包含的文件的 URL。选项可以作为第二个参数传递。在选项中,您可以像 cssFile 的选项中一样指定 condition

有一个方法可以方便地生成超链接

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

第一个参数是标题。它不会被编码,因此,如果您使用的是用户输入的数据,则需要使用 Html::encode() 对其进行编码。第二个参数是 <a 标签的 href 属性中的内容。有关它接受哪些值的详细信息,请参见 Url::to()。第三个参数是标签属性数组。

如果您需要生成 mailto 链接,可以使用以下代码

<?= Html::mailto('Contact us', '[email protected]') ?>

图像

为了生成图像标签,请使用以下方法

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

generates

<img src="https://example.com/images/logo.png" alt="My logo" />

除了 别名 之外,第一个参数可以接受路由、参数和 URL,与 Url::to() 一样。

列表

无序列表可以像下面这样生成

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

为了获取有序列表,请使用 Html::ol() 代替。

发现错别字或您认为此页面需要改进?
在 github 上编辑它 !