[TOC]
## 靜態文件引用
系統全局給大家準備了2個變量:
```
$root // 訪問到public的相對根域名 比如:/ /npadmin/public/
$absroot // 訪問到public的絕對根域名 比如:http://www.npadmin.com/ http://127.0.0.1/npadmin/public/
```
引入所有public目錄里面的靜態文件都可以類型這樣訪問到它們了:
```
<img src="{$root}static/images/xx.png">
<link type="text/css" rel="stylesheet" href="{$root}static/cms/css/index.css"/>
<script src="{$absroot}static/js/common.js"></script>
```
所有的靜態文件只需要自行設置好public目錄后面的路徑即可。
## 模板變量和模板渲染
```
$this->assign('變量名', 值) // 控制中傳遞變量到頁面 用法同TP6 View::assign
return $this->fetch();// 默認模板是 當前控制器小寫+下劃線/當前方法小寫形式.html 用法同TP6 View::fetch
return $this->fetch('xx');// 自定義模板名
```
當然你也可以直接按TP6的文檔來...
## 控制器添加css文件
控制器中可以調用`addCss`來指定當前請求需要的css文件路徑:
~~~
// 單條引入:
$this->addCss('/pear/admin/css/other/login.css');
~~~
~~~
// 批量引入:
$this->addCss([
'/layui/css/layui',
'/pear/component/pear/css/pear.css',
'/pear/admin/css/loader.css',
'/pear/admin/css/admin.css',
'np.css',
'admin/global',
'admin/common'
]);
~~~
已添加的css文件可以使用控制器方法`removeCss`(和addCss路徑字符串,前后寫法要一致才能準確刪除)方法來刪除。
一個控制器方法(操作)對應一個模板頁面:
僅當前頁面需要的css文件就在當前方法中引入;
當前控制器的每個頁面都有一個相同的css文件,可以在當前控制器的初始化方法中引入;
如果是當前應用的每個頁面都需要的css文件,可以在當前應用的核心控制器的初始化方法中引入(比如:admin應用都需要的css文件,系統就在`app\common\controller\Admin::initialize`中引入的)。
說明:
1、所有的靜態文件都應該在`項目/public/static`下,所以只需定義static以后的路徑即可
2、css文件默認放置到`項目/public/static/css`目錄中,所以`np.css`定義的css文件其實找的是`項目/public/static/css/np.css`
3、如果沒有在css目錄下的文件,就必須以`/`開頭直接定義static以后的全部路徑
4、`.css`后綴名可寫可不寫,如果沒有后綴自動補齊
5、css文件都引入到head標簽中
## 控制器添加js文件
控制器中可以調用`addJs`來指定當前請求需要的js文件路徑:
~~~
// 單條引入
// $this->addJs('jquery-3.4.1.min');// 這樣就body內容結尾引入
$this->addJs('jquery-3.4.1.min', false);// 這樣就head中引入
~~~
~~~
// 批量引入
$this->addJs([
'/layui/layui.js',
'/pear/component/pear/pear.js',
'/sortable/Sortable.min.js',
'np.js',
'admin/admin.js',
'admin/common'
]);
~~~
已添加的css文件可以使用控制器方法`removeJs`(和addJs路徑字符串,前后寫法要一致才能準確刪除)方法來刪除。
一個控制器方法(操作)對應一個模板頁面:
僅當前頁面需要的js文件就在當前方法中引入;
當前控制器的每個頁面都有一個相同的js文件,可以在當前控制器的初始化方法中引入;
如果是當前應用的每個頁面都需要的js文件,可以在當前應用的核心控制器的初始化方法中引入(比如:admin應用都需要的js文件,系統就在`app\common\controller\Admin::initialize`中引入的)。
說明:
1、所有的靜態文件都應該在`項目/public/static`下,所以只需定義static以后的路徑即可
2、js文件默認放置到`項目/public/static/js`目錄中,所以`'jquery-3.4.1.min`定義的js文件其實找的是`項目/public/static/js/jquery-3.4.1.min.js`
3、如果沒有在js目錄下的文件,就必須以`/`開頭直接定義static以后的全部路徑
4、`.js`后綴名可寫可不寫,如果沒有后綴自動補齊
5、JS文件默認在body內容結尾中引入,如果需要在head中引入,第二個參數設置為false。
## 控制器傳遞js數據到頁面
我們知道控制中通過assign傳遞數據到模板中,模板中的直接寫JS代碼是可以使用這些變量值得。但是獨立的JS文件中不可以使用assign的值(獨立JS文件沒有經過模板引擎,所以不會被編譯)。系統也給大家準備了一種方案,方便你在獨立JS文件中動態的獲取控制器中處理的值。
假如控制中傳遞了一個mya的變量,值為'aaaa':
```
// 假如控制器中傳遞變量
$this->assign('mya', 'aaaa');
// 模板view目錄下的xx.hmtl模板文件中:
var a = '{$mya}';// 最終傳輸到瀏覽器的結果已經是 var a = 'aaaa';
// 單獨的js文件中,肯定就不能不行了......
```
因此:JS中需要的數據,我們在控制器中利用`assignJsData`方法傳出:
~~~
$this->assignJsData('變量名', 值);
$this->assignJsData('root', $this->request->realRoot());
~~~
然后,在任意的JS代碼中,就可以通過`globalJsData.變量名`來獲取到對應的數據了。
```
<script>
var globalJsData = {"root":"\/","absroot":"http:\/\/www.npadmin.com\/","approot":"\/run"};
</script>
```
系統默認已經給你在JS準備好的值有:
`globalJsData.root` : 訪問到public的相對根域名 可用于JS中進行路徑、靜態文件路徑的拼接等
`globalJsData.absroot`:訪問到public的絕對根域名
`globalJsData.approot`:訪問到當前應用的根域名 可用于JS中進行請求路徑的拼接等
舉一個例子:假如我們在后臺應用中,現在需要利用aJax發送一個請求(比如aritcle的delete方法模擬文件刪除請求)
```
$.get('/run/article/delete', {"id":5}) // 不推薦這樣,雖然這個地址默認是正常的,但是我們知道訪問當然應用的根域名是可以在`congig/app.php`配件文件中修改的(`app_map`、`domain_bind`配置都可以改變當前應用的訪問方式),如果一改,你這個請求不就掛了嗎?
// JS文件中,這樣寫才可以保證隨便你配置怎么變,這個請求路徑都是正確的:
$.get(globalJsData.approot + '/article/delete', {"id":5})
// globalJsData.approot + '/控制器名/方法名',
// globalJsData.approot + '/二級目錄.控制器名/方法名',
// 當然如果js代碼是在模板中,你也可以直接用url函數 $.get('{:url('article/delete')}', {"id":5})
```
**注意:如果你的模板中,沒有做對應數據的輸出,上面講的css文件、js文件、js數據這些功能肯定也是不好使的。可參考下文**
## 推薦的主模板
~~~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{if !empty($meta.title)}{:implode(' - ', $meta.title)}{/if}</title>
<meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"/>
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"/>
<meta name="renderer" content="webkit"/>
<meta name="HandheldFriendly" content="true"/>
<meta name="format-detection" content="telephone=no, email=no"/>
<meta name="keywords" content="{:implode(',', $meta.keywords)}"/>
<meta name="description" content="{:implode(',', $meta.description)}"/>
{:create_css_link($css, true)}
<script>
var globalJsData = {$globalJsData | raw};
</script>
{:create_js_link($js, true)}
{block name="headscript"}{/block}
</head>
<body class="{if empty($is_index)}pear-container {else}layui-layout-body pear-admin {/if}">
{block name="hearder"}{/block}
{block name="content"}{/block}
{block name="footer"}{/block}
{:create_js_link($deferJs, true)}
{block name="script"}{/block}
</body>
</html>
~~~
當然并不是后臺控制器封裝了addCSS、addJs、設置meta等方法,其他應用(比如你自己開發的應用)就可以自動有文件引入和動態渲染了,肯定還是需要模板中進行配合。addCSS、addJs他們的封裝代碼本身很簡單,僅僅是收集數據。真正的輸出和渲染,還是在模板文件中獲取到對應數據進行輸出渲染:
```
<title>{if !empty($meta.title)}{:implode(' - ', $meta.title)}{/if}</title> 網頁標題輸出
<meta name="keywords" content="{:implode(',', $meta.keywords)}"/> 網站關鍵詞輸出
<meta name="description" content="{:implode(',', $meta.description)}"/> 網站描述輸出
```
`create_css_link`:輸出引入css的link標簽
`create_js_link`:輸出引入js的script標簽
輸出所有控制器傳遞到js中的數據:
```
<script>
var globalJsData = {$globalJsData | raw};
</script>
```
這個模板只是給你一個大致的參考,你可以自由發揮......