34. 前台布局模板
简介
在本小节里,我们将完成前台模块的布局模板开发。
需求分解
和 Laravel 教程 - Web 开发实战进阶 一样,我们前台模块也将基于 Bootstrap 4.0 和 FontFont Awesome 来开发。由于 Bootstrap 4.0 和 FontFont Awesome 加载的资源文件比较多,在项目里我们使用 BootCDN 上的资源文件路径,在接下来开发过程中我们只介绍自定义的 CSS 样式或 JS 方法,想了解更多关于 Bootstrap 4.0 和 FontFont Awesome 的信息请查看它们官方文档,这里就不在细述。
在开发前台布局模板时,我们还要求:
- 所有资源文件存储规则和后台模块保持一致;
- 和后台布局模板一样,把布局的头部和底部拆分成局部模板,避免模板文件太长影响代码可读性;
- 在模板里为页面正文和可变内容预留区块(
block
); - 在布局模板里读取后台设置的 站点名称、站点SEO、备案信息和统计代码等内容。
静态资源文件
我们参照后台布局模板静态资源存储规则,创建前台静态资源目录和所有模板共用 CSS 和 JS 文件。
$ mkdir -p public/static/assets/index/css
// 前台共用 CSS
$ touch public/static/assets/index/css/app.css
$ mkdir -p public/static/assets/index/js
// 前台共用 JS
$ touch public/static/assets/index/js/app.js
因为目前我们暂时没有共用的JS方法,所以只需要定义页面共用的 CSS。
public/static/assets/index/css/app.css
body {
font-family: Helvetica, "Microsoft YaHei", Arial, sans-serif;
font-size: 14px;
}
/* header */
.navbar-static-top {
border-color: #e7e7e7;
background-color: #fff;
box-shadow: 0px 1px 11px 2px rgba(42, 42, 42, 0.1);
border-top: 4px solid #00b5ad;
border-bottom: 1px solid #e8e8e8;
margin-bottom: 40px;
margin-top: 0px;
}
/* Sticky footer styles */
html {
position: relative;
min-height: 100%;
}
body {
/* Margin bottom by footer height */
margin-bottom: 60px;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
/* Set the fixed height of the footer here */
height: 60px;
background-color: #000;
}
.footer .container {
padding-right: 15px;
padding-left: 15px;
}
.footer .container p {
margin: 19px 0;
color: #c1c1c1;
}
.footer .container p a {
color: inherit;
}
layout文件
为避免因为模板文件太长影响代码可读性,我们把整个模板文件拆分成以下四个文件,然后使用 包含文件 方法在主模板文件里包含局部模板。
以下是布局模板各文件说明信息,它们都存储在 application/index/view
目录里:
模板文件名 | 说明 |
---|---|
layout/main.html | 主文件名 |
layout/_header.html | 顶部导航 |
layout/_footer.html | 底部导航 |
widget/_message.html | 消息组件 |
按表格里的布局文件设计创建模板文件,并编写各文件代码。
$ touch application/index/view/layout/main.html
$ touch application/index/view/layout/_header.html
$ touch application/index/view/layout/_footer.html
$ touch application/index/view/widget/_message.html
- 主文件
application/index/view/layout/main.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>
{block name="title"}
{$site.title|default='ThinkPHP5.1开发实践教程'}
{/block}
</title>
<meta name="description" content="{$site.description|default='ThinkPHP5.1开发实践教程'}" />
<meta name="keyword" content="{$site.keywords|default='ThinkPHP5.1开发实践教程'}" />
<!-- Styles -->
{css href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css" /}
{css href="https://cdn.bootcss.com/font-awesome/5.10.0-11/css/all.min.css" /}
<link rel="stylesheet" type="text/css" href="<?php echo(asset_path('/static/assets/index/css/app.css')); ?>">
{block name="styles"}{/block}
{notempty name='site.tongji'}
{$site.tongji|raw}
{/notempty}
</head>
<body>
<div id="app" class="<?php echo(route_class()); ?>">
{include file="layout/_header" /}
<div class="container">
{include file="widget/_message" /}
{block name="content"}{/block}
</div>
{include file="layout/_footer" /}
</div>
<!-- Scripts -->
{js href="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js" /}
{js href="https://cdn.bootcss.com/popper.js/1.15.0/umd/popper.min.js" /}
{js href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/js/bootstrap.min.js" /}
<script type="text/javascript" src="/static/assets/index/js/app.js"></script>
{block name="scripts"}{/block}
</body>
</html>
- 顶部导航
application/index/view/layout/_header.html
<nav class="navbar navbar-expand-lg navbar-light bg-light navbar-static-top">
<div class="container">
<!-- Branding Image -->
<a class="navbar-brand " href="#')}">
ThinkBBS
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<!-- Left Side Of Navbar -->
<ul class="navbar-nav mr-auto">
</ul>
<!-- Right Side Of Navbar -->
<ul class="navbar-nav navbar-right">
<!-- Authentication Links -->
<li class="nav-item"><a class="nav-link" href="#">登录</a></li>
<li class="nav-item"><a class="nav-link" href="#">注册</a></li>
</ul>
</div>
</div>
</nav>
- 底部导航
application/index/view/layout/_footer.html
<footer class="footer">
<div class="container">
{notempty name='site.copyright'}
<p class="pull-left">
由 {$site.copyright|raw} 设计和编码 <span style="color: #e27575;font-size: 14px;">❤</span>
</p>
{/notempty}
{notempty name='site.icp'}
<p class="pull-right">
{$site.icp|raw}
</p>
{/notempty}
</div>
</footer>
- 消息组件
消息组件页面我们暂时使用不到,所以这个文件保留为空即可。
代码解读
- 首先我们通过使用
include
标签把布局模板拆分成多个文件,这样使得文件结构清晰更有条理,另外我们使用block
标签预留了一些代码块,其中还给title
这个block块设置了默认值; - 在主文件( layout/main.html )里,输出页面
title
、description
和keyword
这三项信息时,我们使用了 default 函数给元素设置了默认值。default
这个函数之后我们在表单页面经常使用到; - 因为在视图页面输出变量时默认会对变量值进行转义过滤,所以在输出
site.tongji
、site.copyright
和site.icp
时我们使用raw
函数让该变量值不转义输出; - 因为 CDN 服务器上的资源文件不存在更新问题,所以在布局模板里我们使用
js
和css
这两个内置标签加载 BootCDN上的资源文件,而我们定义的 JS 和 CSS 文件使用 HTML 原生标签和asset_path
函数来加载。
在 开发规范 里我们要求在视图里 应该 使用内置标签, 不应该 使用原生 PHP 语法,我们在加载自定义的 CSS/JS 资源文件时之所以使用原生的
<link>
和<script>
这两个标签是因为 ThinkPHP 提供的内置标签不能满足我们的开发需求。
另外,在使用助手函数route_class
时我们使用原生 PHP 语法是因为,可能由于这个函数调用时参数为空当使用 ThinkPHP 推荐的调用方法(格式如:{$site.tongji|raw})时会报错,所以才用原生 PHP 语法。
测试布局模板
修改前台默认控制器代码:
application/index/controller/index.php
<?php
namespace app\index\controller;
use tpadmin\model\Config as ConfigModel;
class Index extends Base
{
public function index()
{
$site = ConfigModel::where('name', ConfigModel::NAME_SITE_SETTING)->find();
$this->assign('site', $site);
return $this->fetch('index');
}
}
创建 index/index 视图模板文件:
application/index/view/index/index.html
{extend name="layout/main" /}
{block name="content"}
<h1>这里是首页</h1>
{/block}
效果预览
用浏览器打开项目 首页 截图。
Git 代码版本控制
下面把代码纳入到版本管理:
$ git add -A
$ git commit -m "前端布局模板"
推荐文章: