ThinkPHP6.0学习笔记-视图模版

视图模板

引擎驱动

MVC中,M模型-V视图-C控制器;View就是视图;

composer require topthink/think-view
namespace app\controller;
use think\facade\View;
class Show
{
    // 模块引擎测试控制器
    public function index()
    {  
        return View::fetch('index');
    }
}

模板使用,文件目录默认在View目录中,二级目录和当前类名一致

模板配置

默认情况下config/view.php是默认模板引擎的配置文件


不使用模板引擎,可以在控制器类中通过require()方法引入PHP文件混编

class Show
{
    // 模块引擎测试控制器
    public function index()
    {
        $name = 'mirror';
        // 混编模式
        // 需要配置完整的文件路径
        require 'static/index.php';
    }
}

如果需要给PHP文件传参并调用,可以在控制器进行;由于控制器类引入文件,PHP文件也就可以引用控制器类方法中的方法参数。

模板变量

assign() 方法

进行全局模板变量的赋值;设置向模板提供赋值操作:

// 支持字符串设置
assign('变量名','变量名');
// 支持数组设置
assign([
    '变量名1'	=>	'变量名1',
    '变量名2'	=>	'变量名2',
    ......
]);
namespace app\controller;
use think\facade\View;
class Show
{
    // 模块引擎测试控制器
    public function index()
    {  
        View::assign('name','mirror');
        return View::fetch('index');
    }
}

在模块中只需要通过{变量名}方法来获取控制器中的值;

<body>
<h1>
    ThinkPHP_V6.0.2 . <?php echo $name;?>
    ThinkPHP_V6.0.2 . {$name}
</h1>
</body>

支持使用filter()方法对模块的变量赋值进行过滤操作

fetch()方法

fetch()方法的第二参数,可以直接用数组形式给模板传递变量;

return View::fetch('index',[
    'name'=>'mirror',
    'age'   =>  100
]);

助手函数view()

View::fetch()同样效果


模板路径

默认情况下,自动定位模板文件路径(优先定位应用目录下view目录)。

不过也可以采用一种分离view的方法,在系统目录下创建一个view目录

  • 单应用模式

    ├─app
    │   └─view(视图目录)
    │     ├─index            index控制器目录
    │     │  └─index.html    index模板文件
    │     └─ ...             更多控制器目录
    
  • 多应用模式

    ├─app
    │  ├─app1 (应用1)
    │  │   └─view(应用视图目录)
    │  │   	 ├─index            index控制器目录
    │  │     │  └─index.html    index模板文件
    │  │ 	 └─ ...             更多控制器目录
    │  │ 
    │  └─ app2... (更多应用)
    
    

如果你需要自定义view目录名称,可以通过设置view_dir_name配置参数。

'view_dir_name'    =>    'template',


模板渲染

模板渲染的典型方法是fetch();系统会按照默认规则自动定位视图目录下的模板文件

控制器名(小写+下划线)/ 操作名.html|.php

配置auto_rule参数的值来改变当前操作的自动渲染规则。

auto_rule配置 自动定位规则
1 操作方法的小写+下划线
2 操作方法全部转换小写
3 保持和操作方法一致

除了在配置文件中修改意外,可以在控制端动态修改配置

// 修改默认的视图模板目录
View::config(['view_dir_name'=>'view'])

默认情况下,调用的是本控制器的模板文件,但也可以调用其他控制器的模板文件;

如果是多模块多应用模式,可以实现跨模块调用模板文件

View::fetch('admin@User/index');

如果想调用public公共目录的模板文件,可以用../public/***来实现:

View::fetch('../public/test/index.php');

视图模板的目录结构只是为了命名规范,无乱是怎样的目录、文件名都可以实现调用;如果不指定目录,只表明模块文件名,就会调用当前控制器模板目录下的模板文件。

第二种原生 PHP 执行方式:在 return 之前设置的变量或者模版变量均无效; 而是把所有的要传递的变量,通过 fetch()的第二个参数传递;

return View::engine('php')->fetch('index', [
	'name' => 'Mr.Lee', 'age' => 100 
]);

直接渲染内容 display

namespace app\index\controller;

use think\facade\View;

class Index 
{
    public function index()
    {
        // 直接渲染内容
        $content = '{$name}-{$email}';
        return View::display($content, ['name' => 'thinkphp', 'email' => '[email protected]']);
    }
}


模板变量输出

当程序运行的时候会在runtime/temp目录下生成一个编译文件;默认情况下,输出的模板变量会自动进行过滤:

<?php echo htmlentities($name)?>

传递的是数组:在模板区域可以使用$data.name形式输出:

class Show
{
    // 模块引擎测试控制器
    public function index()
    {
        $arr = ['name'=>'Mirror','age'=>100];
        return View::fetch('output',[
            'arr'   =>  $arr 
        ]);
    }
}

<body>
<h1>
    ThinkPHP_V6.0.2 . {$arr.name}
<hr>
    ThinkPHP_V6.0.2 . {$arr.age}
</h1>
</body>

temp临时编译文件:

<body>
<h1>
 ThinkPHP_V6.0.2 . <?php echo htmlentities($arr['name']); ?>
<hr>
 ThinkPHP_V6.0.2 . <?php echo htmlentities($arr['age']); ?>
</h1>
</body>

这里明显的对输出的变量进行了函数过滤

传递的是对象:$obj->name $obj::PI

class Show
{
    public $name = 'Mirror';
    public $age  = '100';
    const  PI    = 3.14;
    // 模块引擎测试控制器
    public function index()
    {
        return View::fetch('index',[
            'obj'   =>  $this
        ]);
    }
}

<body>
<h1>
    ThinkPHP_V6.0.2 . {$obj->name}
<hr>
    ThinkPHP_V6.0.2 . {$obj->age}
<hr>
    ThinkPHP_V6.0.2 . {$obj::PI}

</h1>
</body>

<body>
<h1>
 ThinkPHP_V6.0.2 . <?php echo htmlentities($obj->name); ?>
<hr>
 ThinkPHP_V6.0.2 . <?php echo htmlentities($obj->age); ?>
<hr>
 ThinkPHP_V6.0.2 . <?php echo htmlentities($obj::PI); ?>

</h1>
</body>

变量为空时输出默认值:

{$obj->age|default=100}

<?php
    echo htmlentities((isset($obj->age) && ($obj->age !== '')?$obj->age:100)); 
?>


系统变量:

$_SERVER $_ENV $_GET $_POST $_REQUEST $_SESSION $_COOKIE

对于注入Request对象,可以直接在模板输出

{$Request.get.id}
{$Request.host}


模块函数和运算符

使用函数

MD5加密:

{$password|md5}

不进行htmlentities转义,可以使用|raw

{$user['email']|raw}

系统内置了下面几个固定的过滤规则(不区分大小写)

过滤方法 描述
date 日期格式化(支持各种时间类型)
format 字符串格式化
upper 转换为大写
lower 转换为小写
first 输出数组的第一个元素
last 输出数组的最后一个元素
default 默认值
raw 不使用(默认)转义

多个参数调用,可以用逗号隔开;

支持多个函数进行操作,用|隔开即可,左优先;

在模板中也可以直接使用PHP的语法模式,使用:开头即可;

运算符

在模块中可以使用运算符:+ - * / % ++ --

在模块中也支持使用三元运算符;


模块的循环标签

{foreach}循环

首先在控制端中通过模型类把数据库的数据给拿出来,然后在模型端使用{foreach}闭合标签把数据实现循环;这里需要注意的是:foreach是属于对象调用,用->.均可以实现数据调用。

public function index()
{
    $list = User::select();
    return View::fetch('index',[
        'list' => $list
    ]);
}

<table>
	{foreach $list as $key=>$obj}
    <tr>
        <td>{$key}/{$obj->id}</td>
        <td>{$obj->username}</td>
        <td>{$obj->gender}</td>
        <td>{$obj->email}</td>
        <td>{$obj->price}</td>
        <td>{$obj->create_time}</td>
    </tr>
	{/foreach}
</table>

{volist}循环

volist也是可以将数据集通过循环方式输出:

<table>
{volist name="list" id="obj"}
    <tr>
        <td>{$key}/{$obj->id}</td>
        <td>{$obj->username}</td>
        <td>{$obj->gender}</td>
        <td>{$obj->email}</td>
        <td>{$obj->price}</td>
        <td>{$obj->create_time}</td>
    </tr>
{/volist}
</table>

volist中的name属性表示数据总集,id属性表示当前循环的单条数据集;offset属性设置数据起始位置,length属性设置数据结束位置

使用eq比较标签:

{volist name="list" id="obj" mod="2"}
{eq name='mod' value='0'}

mod=2表示索引除以2得到的余数是否等于0或1;eq标签中设置了value属性为0,也就是说需要得到的余数为0,那么可以被输出的都是偶数数据集;

使用empty标签:当没有索引数据集为空时输出

{volist name="list" id="obj" empty="Null"}


{for}循环

for循环就是通过起始和结束值的设定,按照指定的步长实现循环:

{for start='1' end='10' comparison='lt' step='2' name="list"}
{$list}
{/for}

模板的比较标签

系统支持的比较标签以及所表示的含义分别是:

标签 含义
eq或者 equal 等于
neq 或者notequal 不等于
gt 大于
egt 大于等于
lt 小于
elt 小于等于
heq 恒等于
nheq 不恒等于

{eq}

{eq}...{/eq}标签:比较两个值是否相同,相同则输出标签包含的内容;

{eq name="name" value="Mirror"}
	I am Mirror.
{/eq}

属性name里是一个变量,可以选择性添加$符号;而value里是一个字符串,如果value是一个变量的化,那么就需要加上$符号使其成为一个变量。

{eq}标签支持{else/}操作:

{eq name="name" value="Mirror"}
	I am Mirror.
{else/}
	I not Mirror
{/eq}


所有的比较标签都可以统一为{compare}标签使用,设置type属性即可:

{compare name="name" value="Mirror" type='eq'}
	......
{/compare}

模板的定义标签

变量定义{assign}

如果想在模板文件中定义一个变量,可以使用{assgin}标签

{assgin name='var' value='123'}
{$var}

常量定义{define}

{define name='PI' value='3.14'}
{$PI}

原生定义{php}

可以采用{php}标签编写原生PHP代码

{php}
	echo "ThinkPHPV6.0.2";
{/php}

标签之间支持嵌套功能


模板的条件判断标签

{switch}

{switch number}
    {case 1}1{/case}
    {case 2}2{/case}
    {case 3}3{/case}
	{default/}Not
{/switch}

{if}

{if $number > 10}大于10{/if}

支持and、or等语法的使用;支持{else/}语法、{elseif}语法等多级嵌套;

{if}标签支持PHP原生语法

范围判断标签

{in}/{notin} 判断值是否存在或不存在指定数据列表中:

{in name='list' value='10,20,30,40,50,60'}存在{/in}

{in name='list' value='10,20,30,40,50,60'}
    ......
{else/}
    ......
{/in}

{between}/{notbetween}判断值是否存在或不存在数据区间

{present}/{notpresent}判断变量是否已经定义赋值

{empty}/{notempty}判断是否为空

{defined}/{notdefined}判断是否定义常量

上述各类的判断标签均支持多级嵌套,同时也支持{else/}标签的嵌套


模板的加载包含输出

包含文件{include}

{include file='模版文件1,模版文件2,...' [其它参数传递]/}

可用来加载公用重复的文件,比如头部、尾部、导航部分;

可以包含一个完整的路径;

模板的参数也可以通过固定的语法进行传递:在执行包含操作中将参数一同向被包含文件传递,在被包含文件中用[变量名]的方式来调用被一传递过来的参数:

{include file='public/header' title='$title' key='$name'}

输出替换

项目中有时需要调用静态文件,比如css和js等;写路径比较繁琐,可以路径整理打包:(在view.php中添加配置)

// 模板替换输出
'tpl_replace_string'	=>[
    '__JS__'	=>	'../static/js',
    '__CSS__'	=>	'../static/css'
]

配置添加后,在html文件端直接调用__CSS__/__JS__(魔术方法)即可

<link rel="stylesheet" type='text/css' href="__CSS__/layui.css">

需要重新编译程序

文件加载

传统的调用css/js文件,采用link和script标签实现调用;think系统提供了一个独特的加载方式;

使用{load}标签和href属性来链接加载,不需要设置其他任何参数:

{load href='__CSS__/layui.css'}
{load href='__JS__/jquery.js'}

{load href='__CSS__/layui.css , __JS__/jquery.js'}
// 为了方便理解 还有如下别名识别
{css href='__CSS__/layui.css'}
{js href='__JS__/jquery.js'}

模板布局

方法一:(不推荐)

6.0版本 默认情况下,不支持模板布局功能,需要在配置文件view.php中开启;

'layout_on'	=> true,

发现报错提示“模板文件不存在: tp6\view\layout.html”;缺少layout.html模板;

'layout_name'   =>  'public/layout'

这个时候就开启了相当于全局的模板布局,我们之前的block在访问的时候就会讨厌该html文件的布局进行显示;只需要执行如下:

{__CONTENT__}

就可以把文件套用到当前布局文件中

个人表示这种方式非常的不灵活,不推荐该方法

方法二:(推荐)

无需在配置文件中设置模板布局文件了!只需要在文件的首部引入:

{layout name="[模板布局文件位置]" replace='魔术方法'}

view/block/index.html

{layout name="public/layout" replace="[__blockIndex__]"}

<h1>
    Block.html - {$title}
</h1>

view/public/layout.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
	[__blockIndex__]
</body>
</html>

这个方法比方法一更加灵活!

模板继承

模板继承是另一种灵活的HTML布局方式!

view/block/index.html

{extend name="../view/public/base.html"}

{block name="haeder"}block-test{/block}

view/public/base.html:模板布局-基模板

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>{$title}</title>
</head>
<body>

{block name="haeder"}base-test{/block}

{block name="nav"}base-test{/block}

</body>
</html>

在base中添加{block}标签即是一个可被替换的块域;

而index.html中继承base同时也会使用{block}标签来替换base中的块域

杂项

{literal} 原生输出

可以将{}内容原样输出,使其不被模板解析

模板注释

使用{//} {/*..*/} 等两种注释方式

表单令牌

参考官方文档:thinkphp6-表单令牌


猜你喜欢

转载自www.cnblogs.com/wangyuyang1016/p/12769758.html