NetBeans

最后更新于:2022-04-01 11:04:39

找到项目定义文件:/nbproject/customs.json, 添加下面的代码,保存后,即可实现指令的自动提示 ~~~ { "elements": {}, "attributes": { "php-include": {}, "php-repeat": {}, "php-for": {}, "php-foreach": {}, "php-show": {}, "php-hide": {}, "php-switch": {}, "php-case": {}, "php-default": {}, "php-function": {}, "php-if": {}, "php-else": {}, "php-elseif": {}, "php-extends": {}, "php-block": {}, "php-literal": {}, "php-after": {}, "php-select": {}, "php-checked": {}, "php-model": {} } } ~~~
';

代码提示

最后更新于:2022-04-01 11:04:37

[NetBeans](NetBeans.md)
';

更新日志

最后更新于:2022-04-01 11:04:35

## 更新日志 #### 2018-04-24 * 兼容tp5.1 * 修复assign一个 cache_file 变量导致找不到模板和报错的问题 #### 2016-12-21 * 修复php-include变量支持问题 * 修复tp5中控制器大小写支持问题 #### 2016-10-17 * 增加 php-model指令, 方便做内容编辑功能,value会自动转移特殊字符(htmlentities), 保证 input的value正确输出 #### 2016-08-18 * 增加 php-selected 和 php-checked 指令, 方便后台做表单的自动选中功能 #### 2016-07-18 * 调整配置参数 `attr` 为 `directive_prefix` * 调整配置参数 `max_num` 为 `directive_max` * 指令规范 #### 2016-06-24 * 项目迁移到top-think下 * 增加命名空间支持 #### 2016-06-05 * 增加自定义扩展功能Angular::extend * 所有函数和属性改为public修饰, 方便扩展调用配置信息和解析规则 * thinkphp5驱动更新, 解决tp5部分常量不能使用的问题
';

ThinkPHP 6.0.x

最后更新于:2022-04-01 11:04:32

## 安装方法 `composer require topthink/think-angular:3.0.x` ### 模板配置 ``` // config/view.php return [ // 模板引擎类型 Angular 'type' => 'Angular', 'debug' => true, // 是否开启调试模式 'tpl_suffix' => '.html', // 模板后缀 'tpl_cache_suffix' => '.php', // 模板缓存文件后缀 'directive_prefix' => 'php-', // 指令前缀 'directive_max' => 10000, // 指令的最大解析次数 ]; ``` ### 模板输出和调用 ``` // 模板变量赋值 View::assign('name','ThinkPHP'); View::assign('email','thinkphp@qq.com'); // 或者批量赋值 View::assign([ 'name' => 'ThinkPHP', 'email' => 'thinkphp@qq.com' ]); // 模板输出, 模板路径不能为空, 必须写全路径 return View::fetch('index'); ``` > 注意, 只有开启调试模式, 修改模板才能实时看到效果, 线上修改模板后, 一定要清理一次模板缓存, 否则会导致模板不生效
';

ThinkPHP 5.1.x

最后更新于:2022-04-01 11:04:30

## 安装方法 ### tp5.1.x版本 ``` composer require topthink/think-angular:2.0.* ``` ### 模板配置 ``` // config/template.php return [ // 模板引擎类型 Angular 'type' => 'Angular', 'debug' => true, // 是否开启调试模式 'tpl_suffix' => '.html', // 模板后缀 'tpl_cache_suffix' => '.php', // 模板缓存文件后缀 'directive_prefix' => 'php-', // 指令前缀 'directive_max' => 10000, // 指令的最大解析次数 ]; ``` > 注意, 只有开启调试模式, 修改模板才能实时看到效果, 线上修改模板后, 一定要清理一次模板缓存, 否则会导致模板不生效
';

ThinkPHP 5.0.x

最后更新于:2022-04-01 11:04:28

## 安装方法 ### tp5.0.x版本 <code>composer require topthink/think-angular:1.0.*</code> ### 模板配置 ``` // 修改模板配置: /application/config.php 'template' => [ // 模板引擎类型 Angular 'type' => 'Angular', 'debug' => true, // 是否开启调试模式 'tpl_suffix' => '.html', // 模板后缀 'tpl_cache_suffix' => '.php', // 模板缓存文件后缀 'directive_prefix' => 'php-', // 指令前缀 'directive_max' => 10000, // 指令的最大解析次数 ], ``` > 注意, 只有开启调试模式, 修改模板才能实时看到效果, 线上修改模板后, 一定要清理一次模板缓存, 否则会导致模板不生效
';

结合框架使用

最后更新于:2022-04-01 11:04:26

[ThinkPHP 5.0.x](ThinkPHP%205.0.x.md) [ThinkPHP 5.1.x](ThinkPHP5.1.x.md) [ThinkPHP 6.0.x](ThinkPHP6.0.x.md)
';

数据列表输出

最后更新于:2022-04-01 11:04:23

> 最常用的列表输出, 这里提供一个参考案例, 具体项目可就该对应的dom结构 ## 控制器代码 ``` <?php // 总页数 $view->assign('pagecount', 100); // 模拟用户列表 $data = [ 'title' => 'Hello PHP Angular', 'list' => [ ['id' => 1, 'name' => 'user_1', 'email' => 'email_1@qq.com', 'status' => 1], ['id' => 2, 'name' => 'user_2', 'email' => 'email_2@qq.com', 'status' => 0], ['id' => 3, 'name' => 'user_3', 'email' => 'email_3@qq.com', 'status' => -1], ['id' => 4, 'name' => 'user_4', 'email' => 'email_4@qq.com', 'status' => 1], ['id' => 5, 'name' => 'user_5', 'email' => 'email_5@qq.com', 'status' => 1], ], ]; // 向模板引擎设置数据 $view->assign($data); // 解析显示 $view->display('index'); ``` ## 模板文件 ``` <!DOCTYPE html> <html> <head> <title>列表</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.css" /> <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <script type="text/javascript" src="http://apps.bdimg.com/libs/bootstrap/3.3.4/js/bootstrap.min.js"></script> </head> <body> <table class="table table-bordered"> <tr> <th>编号</th> <th>用户名</th> <th>邮箱</th> <th>状态</th> <th>操作</th> </tr> <tr php-if="$list" php-repeat="$list as $user"> <td>{$user.id}</td> <td>{$user.name}</td> <td>{$user.email}</td> <td> <php php-switch="$user['status']"> <span php-case="1">正常</span> <span php-case="0">已禁用</span> <span php-case="-1">已删除</span> </php> </td> <td> <a php-show="$user['status'] === 1" php-after="echo ' '" href="javascript:void(0);" class="btn btn-xs btn-warning">禁用</a> <a php-show="$user['status'] === 0" php-after="echo ' '" href="javascript:void(0);" class="btn btn-xs btn-primary">启用</a> <a php-show="$user['status'] >= 0" php-after="echo ' '" href="javascript:void(0);" class="btn btn-xs btn-danger">删除</a> <a php-show="$user['status'] == -1" php-after="echo ' '" href="javascript:void(0);" class="btn btn-xs btn-primary">恢复</a> </td> </tr> <tr php-else=""> <td colspan="3" class="text-center">没有数据</td> </tr> </table> </body> </html> ``` ## 最终效果 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-05_572a316adfe34.png)
';

无限级菜单生成

最后更新于:2022-04-01 11:04:21

> 无限级菜单和分类也是经常用到的功能, 这里提供一个参考案例, 具体项目可就该对应的dom结构 ## 控制器代码 ``` <?php // 树状结构 $menus = [ [ 'title' => '菜单1', 'sub' => [ ['title' => '菜单1.1'], ['title' => '菜单1.2'], ['title' => '菜单1.3'], ['title' => '菜单1.4'], ] ], [ 'title' => '菜单2', 'sub' => [ ['title' => '菜单2.1'], ['title' => '菜单2.2'], ['title' => '菜单2.3'], ['title' => '菜单2.4'], ] ], [ 'title' => '菜单3', 'sub' => [ [ 'title' => '菜单3.1', 'sub' => [ ['title' => '菜单3.1.1'], ['title' => '菜单3.1.2'], [ 'title' => '菜单3.1.3', 'sub' => [ ['title' => '菜单3.1.3.1'], ['title' => '菜单3.1.3.2'], ] ], ] ], ['title' => '菜单3.2'], ['title' => '菜单3.3'], ['title' => '菜单3.4'], ] ], ]; // 赋值给模板 $view->assign('menus', $menus); $view->display('index'); ``` ## 模板文件 ``` <!DOCTYPE html> <html> <head> <title>无限级菜单</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.css" /> <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <script type="text/javascript" src="http://apps.bdimg.com/libs/bootstrap/3.3.4/js/bootstrap.min.js"></script> </head> <body> <ul php-init="echo_menu($menus)" php-function="echo_menu($menus)"> <li php-repeat="$menus as $menu"> {$menu.title} <ul php-if="isset($menu['sub'])" php-call="echo_menu($menu['sub'])"></ul> </li> </ul> </body> </html> ``` ## 最终效果 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-05_572a316a951fb.png)
';

分页

最后更新于:2022-04-01 11:04:19

> 分页是数据输出后经常用到的功能, 这里提供一个参考案例, 具体项目可就该对应的dom结构 ## 控制器代码 ``` // 总页数 $view->assign('pagecount', 100); // 当前页 $view->assign('p', isset($_GET['p']) ? $_GET['p'] : 1); // url生成, 可在闭包函数中生成复杂的url $view->assign('page', function ($p) { return '/test/index.php?p=' . $p; }); $view->display('index'); ``` ## 模板文件 ``` <!DOCTYPE html> <html> <head> <title>分页效果</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.css" /> <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <script type="text/javascript" src="http://apps.bdimg.com/libs/bootstrap/3.3.4/js/bootstrap.min.js"></script> </head> <body> <!-- 这里可以做成单独的模板文件, 然后用 php-include="common/page" 的方式引入 --> <nav php-show="$pagecount > 1"> <ul class="pagination"> <li php-show="$p > 1"> <a href="{:$page(1)}">首页</a> </li> <li php-show="$p > 1"> <a href="{:$page($p - 1)}">上一页</a> </li> <li php-show="$p - 4 > 2"> <!-- 这里是 往前十页, 如果第一页显示了, 就隐藏这个'...' 按钮 --> <a href="{:$page($p - 10 < 1 ? 1 : $p - 10)}"><span>...</span></a> </li> <li php-for="$i = $p - 4; $i <= $p + 4; $i++" php-show="$i > 0 && $i <= $pagecount" class="{$p == $i ?= 'disabled'}"> <a php-show="$p != $i" href="{:$page($i)}">{$i}</a> <span php-show="$p == $i">{$i}</span> </li> <li php-show="$p + 4 < $pagecount"> <!-- 这里是 后十页, 如果最后一页显示了, 就隐藏这个'...' 按钮 --> <a href="{:$page($p + 10 > $pagecount ? $pagecount : $p + 10)}"><span>...</span></a> </li> <li php-show="$p < $pagecount"> <a href="{:$page($p + 1)}">下一页</a> </li> <li php-show="$p < $pagecount"> <a href="{:$page($pagecount)}">尾页 {$pagecount}</a> </li> </ul> </nav> </body> </html> ``` ## 最终效果 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-05_572a316a5979f.png)
';

常用实例

最后更新于:2022-04-01 11:04:17

[分页](%E5%88%86%E9%A1%B5.md) [无限级菜单生成](%E6%97%A0%E9%99%90%E7%BA%A7%E8%8F%9C%E5%8D%95%E7%94%9F%E6%88%90.md) [数据列表输出](%E6%95%B0%E6%8D%AE%E5%88%97%E8%A1%A8%E8%BE%93%E5%87%BA.md)
';

附录

最后更新于:2022-04-01 11:04:14

[常用实例](%E5%B8%B8%E7%94%A8%E5%AE%9E%E4%BE%8B.md) [结合框架使用](%E7%BB%93%E5%90%88%E6%A1%86%E6%9E%B6%E4%BD%BF%E7%94%A8.md) [更新日志](%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97.md) [代码提示](%E4%BB%A3%E7%A0%81%E6%8F%90%E7%A4%BA.md)
';

自定义扩展

最后更新于:2022-04-01 11:04:12

> 如果系统自带的解析规则不能满足需求, 可以使用 Angular::extend()方法进行扩展, 此方法有两个参数, 详细请看下面实例. ## 入口文件: /test/index.php ``` <?php use think\angular\Angular; require '../src/Angular.php'; // 自定义扩展, 打印变量的值 Angular::extend('dump', function ($content, $param, $angular) { $old = $param['html']; $new = '<pre>'; unset($param[0], $param[1], $param[2], $param[3], $param[4], $param[5]); $new .= '<?php var_dump(' . $param['value'] . '); ?>'; $new .= '<pre>'; return str_replace($old, $new, $content); }); // 自定义扩展, 变量+1 Angular::extend('inc', function ($content, $param, $angular) { $old = $param['html']; $new = '<?php ' . $param['value'] . '++; ?>'; $new .= Angular::removeExp($old, $param['exp']); return str_replace($old, $new, $content); }); // 自定义扩展, 变量-1 Angular::extend('dec', function ($content, $param, $angular) { $old = $param['html']; $new = '<?php ' . $param['value'] . '--; ?>'; $new .= Angular::removeExp($old, $param['exp']); return str_replace($old, $new, $content); }); / 配置 $config = [ 'debug' => true, // 是否开启调试, 开启调试会实时生成缓存 'tpl_path' => './view/', // 模板根目录 'tpl_suffix' => '.html', // 模板后缀 'tpl_cache_path' => './cache/', // 模板缓存目录 'tpl_cache_suffix' => '.php', // 模板缓存后缀 'directive_prefix' => 'php-', // 指令前缀 'directive_max' => 10000, // 指令的最大解析次数 ]; // 实例化 $view = new Angular($config); // 输出解析结果 $view->display('index'); ``` ## 模板文件: /text/view/index.html ``` <!DOCTYPE html> <html> <head> <title>diy test</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <div php-dump="$navs"></div> <div php-init="$i = 0" php-inc="$i" php-inc="$i">{$i}</div> <div php-dec="$i">{$i}</div> </body> </html> ``` ## 解析后 ``` <!DOCTYPE html> <html> <head> <title>diy test</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <pre><?php var_dump($navs); ?><pre> <?php $i = 0; $i++; $i++; ?> <div><?php echo $i; ?></div> <?php $i--; ?> <div><?php echo $i; ?></div> </body> </html> ```
';

model

最后更新于:2022-04-01 11:04:09

> model指令专门用来解决数据在输入框中编辑的问题, 自动转移特殊字符(htmlentities), 保证 input的value正确输出 `版本要求: v1.0.8+` ~~~ // 模版赋值中带有双引号 $view->assign('name', '"php" and "think-angular"'); ~~~ ## 解析前 ~~~ <input type="text" name="name" php-model="$name" /> <input type="submit" value="提交"> ~~~ ## 解析后 ~~~ <input type="text" name="name" value="&quot;thinkphp&quot; vs &quot;angular&quot;" /> <input type="submit" value="提交"> ~~~ ## 显示 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/6b0728d4a2bda016f5eab0db60932f8c_237x52.png)
';

checked

最后更新于:2022-04-01 11:04:06

> checked指令专门用来解决复选框和单选的自动选中问题, 可省去多个if判断 ~~~ <div class="form-control" php-init="$all_hobby = ['html','css','js','php', 'mysql', 'linux']" php-init="$user_hobby = ['linux','css','js','php']"> 技能: <label class="checkbox-inline" php-repeat="$all_hobby as $hobby"> <input type="checkbox" name="hobby" value="{$hobby}" php-checked="in_array($hobby, $user_hobby)" /> {$hobby} </label> </div> <br /> <div class="form-control" php-init="$user_sex = 1"> 性别: <label class="radio-inline"> <input type="radio" name="sex" value="0" php-checked="$user_sex === 0" /> 女 </label> <label class="radio-inline"> <input type="radio" name="sex" value="1" php-checked="$user_sex === 1" /> 男 </label> </div> ~~~ 解析后: ~~~ <?php $all_hobby = ['html','css','js','php', 'mysql', 'linux']; $user_hobby = ['linux','css','js','php']; ?> <div class="form-control"> 技能: <?php foreach ($all_hobby as $hobby) { ?> <label class="checkbox-inline"> <?php if (in_array($hobby, $user_hobby)) { ?> <input type="checkbox" name="hobby" value="<?php echo $hobby; ?>" checked="checked" /> <?php } else { ?> <input type="checkbox" name="hobby" value="<?php echo $hobby; ?>" /> <?php } echo $hobby; ?> </label> <?php } ?> </div> <br /> <?php $user_sex = 1; ?> <div class="form-control"> 性别: <label class="radio-inline"> <?php if ($user_sex === 0) { ?> <input type="radio" name="sex" value="0" checked="checked" /> <?php } else { ?> <input type="radio" name="sex" value="0" /> <?php } ?> 女 </label> <label class="radio-inline"> <?php if ($user_sex === 1) { ?> <input type="radio" name="sex" value="1" checked="checked" /> <?php } else { ?> <input type="radio" name="sex" value="1" /> <?php } ?> 男 </label> </div> ~~~
';

selected

最后更新于:2022-04-01 11:04:04

> selected指令专门用来解决选择框的自动选中问题, 可省去多个if判断 ~~~ <select class="form-control" php-init="$p = isset($_GET['p']) ? $_GET['p'] : 1"> <option php-for="$i = 1; $i <= 50; $i++" php-selected="$p == $i" value="{$i}">第{$i}页</option> </select> ~~~ 解析后: ~~~ <?php $p = isset($_GET['p']) ? $_GET['p'] : 1; ?> <select class="form-control"> <?php for ($i = 1; $i <= 50; $i++) { if ($p == $i) { ?> <option selected="selected" value="<?php echo $i; ?>">第<?php echo $i; ?>页</option> <?php } else { ?> <option value="<?php echo $i; ?>">第<?php echo $i; ?>页</option> <?php } } ?> </select> ~~~
';

literal

最后更新于:2022-04-01 11:04:01

> literal指令可以实现代码的原样输出 ~~~ <div php-literal="" class="name">{$name}</div> ~~~ 解析后: ~~~ <div class="name">{$name}</div> ~~~ 如果想输出原始代码,可以使用php-literal="code" , 这样可以在页面上显示div的源代码,其实,只是把左尖括号替换成了实体。 ~~~ <div php-literal="code" class="name">{$name}</div> ~~~ 解析后: ~~~ &lt;div class="name">{$name}&lt;/div> ~~~
';

extends

最后更新于:2022-04-01 11:03:59

> extends为继承指令,一般项目中, 我们的网页框架是一样的, 比如新闻介绍页, 文章介绍页, 文章列表页, 等等 都是公用的头部底部和侧边栏, 又或者做后台的时候, 都是统一的导航菜单和底部, 这时候我们可以使用模板继承方便的实现代码的重用和结构的划分 ## 1. base.html ``` <!DOCTYPE html> <html> <head> <title>base</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <div php-block="left">这里是left, 会被替换</div> <div php-block="right">这里是right, 会被替换</div> <div php-block="bottom">这里是bottom, 会被替换</div> </body> </html> ``` ## 2. index.html ``` <div php-extends="common/base"></div> <div php-block="left"> 网页主体 </div> <div php-block="right"> 侧边栏推荐 <ul> <li php-repeat="[1,2,3,4,5] as $i">列表 {$i}</li> </ul> </div> <div php-block="bottom"> 版权所有 {$username} </div> ``` > 这样模板引擎调用解析 index.html的时候会把对应的block合并到base.html中, 实现模板的继承 ## 解析结果 ``` <!DOCTYPE html> <html> <head> <title>base</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <div > 网页主体 </div> <div > 侧边栏推荐 <ul> <?php foreach ([1,2,3,4,5] as $i) { ?><li >列表 <?php echo $i; ?></li><?php } ?> </ul> </div> <div > 版权所有 <?php echo $username; ?> </div> </body> </html> ```
';

function

最后更新于:2022-04-01 11:03:57

> function指令可以把指定的标签定义为一个函数, 在需要的地方调用 ~~~ <div class="menu"> <ul php-function="echo_ul($list)"> <li php-foreach="$list as $cate"> <a href="/category/{$cate.name}">{$cate.title}</a> <ul php-if="isset($cate['_child'])" php-call="echo_ul($cate['_child'])"></ul> </li> </ul> <ul php-call="echo_ul($list)"></ul> </div> ~~~ 解析后 ~~~ <div class="menu"> <?php function echo_ul($list) { ?><ul > <?php foreach ($list as $cate) { ?><li > <a href="/category/<?php echo $cate["name"]; ?>"><?php echo $cate["title"]; ?></a> <?php if (isset($cate['_child'])) { echo_ul($cate['_child']); } ?> </li><?php } ?> </ul><?php } echo_ul($list); ?> </div> ~~~ > 此示例本身就是一个无限级菜单展示的案例, php-call为调用函数传入数据
';

exec

最后更新于:2022-04-01 11:03:54

> exec目前和init功能相同 ~~~ <div class="name" php-exec="$name='shuai'">{$name}</div> ~~~ 解析后: ~~~ <?php $name='shuai'; ?><div class="name" ><?php echo $name; ?></div> ~~~
';