本书未发布

34. 前台布局模板

未匹配的标注

简介

在本小节里,我们将完成前台模块的布局模板开发。

需求分解

Laravel 教程 - Web 开发实战进阶 一样,我们前台模块也将基于 Bootstrap 4.0FontFont Awesome 来开发。由于 Bootstrap 4.0FontFont Awesome 加载的资源文件比较多,在项目里我们使用 BootCDN 上的资源文件路径,在接下来开发过程中我们只介绍自定义的 CSS 样式或 JS 方法,想了解更多关于 Bootstrap 4.0FontFont Awesome 的信息请查看它们官方文档,这里就不在细述。

在开发前台布局模板时,我们还要求:

  1. 所有资源文件存储规则和后台模块保持一致;
  2. 和后台布局模板一样,把布局的头部和底部拆分成局部模板,避免模板文件太长影响代码可读性;
  3. 在模板里为页面正文和可变内容预留区块( block );
  4. 在布局模板里读取后台设置的 站点名称、站点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
  1. 主文件

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>
  1. 顶部导航

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>
  1. 底部导航

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>
  1. 消息组件

消息组件页面我们暂时使用不到,所以这个文件保留为空即可。

代码解读

  • 首先我们通过使用 include 标签把布局模板拆分成多个文件,这样使得文件结构清晰更有条理,另外我们使用 block 标签预留了一些代码块,其中还给 title 这个block块设置了默认值;
  • 在主文件( layout/main.html )里,输出页面 titledescriptionkeyword 这三项信息时,我们使用了 default 函数给元素设置了默认值。default 这个函数之后我们在表单页面经常使用到;
  • 因为在视图页面输出变量时默认会对变量值进行转义过滤,所以在输出 site.tongjisite.copyrightsite.icp 时我们使用 raw 函数让该变量值不转义输出;
  • 因为 CDN 服务器上的资源文件不存在更新问题,所以在布局模板里我们使用 jscss 这两个内置标签加载 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 "前端布局模板"

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~