Write the Code. Change the World.

2月 20

安装好了 bootstrap,我们先确定好主题色,然后开始创建网站的公用模块(头部和底部)。

前奏

路由调整,功能连贯

我们先删掉默认的 welcome.blade.php 文件和 HomeController 文件。

再创建一个默认的页面控制器,我喜欢叫 PageController,并且是放在 web 文件夹下的。后边会有 api 的控制器,所以才这样分开。

php artisan make:controller web/PageController

# 在里边添加一个方法,输出一个前端页面
/**
 * Show the application dashboard.
 *
 * @return \Illuminate\Contracts\Support\Renderable
 */
public function home()
{
    return view('home');
}

这里,不需要构造器。在之前删除的构造器中有构造器 ,并指定了 auth 的中间件。这样用户只要不是登录态访问页面,都会默认跳转到登录页面。

修改路由文件 web.php

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\web\PageController;

Route::get('/', [PageController::class, 'home'])->name('home');

Auth::routes();

在浏览器访问 http://xr.com 就可以看到顶部带有注册登录按钮的页面了。

本地化(多语言)

这个时候,注册和登录是英文的。是多语言功能没配置好。可以在 resources 下创建 lang 目录,lang 下创建 en 和 zh-CN 目录。里边分别创建 messages.php。然后填充下边的内容。

# en/messages.php
<?php

return [
    'login' => 'Login',
    'register' => 'Register',
    'logout' => 'Logout',
];

# zh-CN/messages.php
<?php

return [
    'login' => '登录',
    'register' => '注册',
    'logout' => '登出',
];

然后 修改 app.blade.php 中的 __('Login') 为 __('messages.login'),再打开站点。

发现英文的已经变成了中文了。

默认,lang 是直接在项目根目录下的,也就是和 resources 同级。个人不喜欢在根目录放太多玩意,就放在 resources 下。
多语言还可以使用 json 文件,还可以配置传参,也可以配置安装包的多语言。更多信息请看官方文档。
https://laravel.com/docs/10.x/localization

这里站点是纯中文的,后边也不考虑英文。就直接删除 lang。以及在 blade 中直接使用中文,不使用多语言调用了。

基本构成(思路)

经过前边的一些调整。我们来好好处理下 app.blade.php 文件。这个是整个站点的灵魂和基础。传统的网站,头部和底部都是公用的,中间区域随着页面不同而不同。这里就单独把头部和底部抽离出来。中间部分定义好插槽即可。这个插槽和 vue 项目中又有不同。理解为占坑就可。可以为 style 样式位置占坑,可以为 html 位置占坑,也可以为 js 占坑。

一点一点的来。

还有一个细节。上述所描述的一个容器,如果遇到页面高度比浏览器窗口的高度小很多的情况呢。页面那么多,看过有的网站在这种情况下。底部之后,会有很大一片空白(页面是从上到下的平面)。这样很难看。在这里,约定父容器的最小高度就是 100vh。页面减去顶部和中间部分的,就是底部的。想办法让顶部和中间撑开到自适应不就看可以了吗。这样会好看一点。后边出一个图。

头部

  1. 头部我喜欢用抽屉式(Offcanvas)。
  2. 头部我预想有一个 logo,几个主菜单,还有搜索框登录注册按钮构成。就是三部分。其实,这里实例中已经给出了结构。

底部

  1. 底部放一列友情链接
  2. 底部放一列联系方式
  3. 底部放一列二维码(最多两个)

上边就是心中所想。然后得用 bootstrap 的结构来表达,并且是融入 laravel 的 blade 中的。

基本构成(文件)

  1. app.blade.php
  2. header.blade.php
  3. footer.blade.php

header.blade.php

这样算比较简洁。因为是官网,不是论坛博客性质的,还是去掉搜索相关功能。还有多语言,也要准备起来。

<header class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
    <div class="container-fluid px-5">
        <a class="navbar-brand" href="{{ url('/') }}">
            Logo
        </a>

        <button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavbar"
            aria-controls="offcanvasNavbar">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasNavbar" aria-labelledby="offcanvasNavbarLabel">
            <div class="offcanvas-body">
                <ul class="navbar-nav flex-grow-1 px-3 main-nav">
                    <li class="nav-item active">
                        <a class="nav-link" aria-current="page" href="#">首页</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">约拍</a>
                    </li>

                    <li class="nav-item">
                        <a class="nav-link" href="#">瞬间</a>
                    </li>

                    <li class="nav-item">
                        <a class="nav-link" href="#">关于我们</a>
                    </li>
                </ul>

                <ul class="navbar-nav pe-3">
                @guest
                    @if (Route::has('login'))
                        <li class="nav-item">
                            <a class="nav-link" href="{{ route('login') }}">登录</a>
                        </li>
                    @endif

                    @if (Route::has('register'))
                        <li class="nav-item">
                            <a class="nav-link" href="{{ route('register') }}">注册</a>
                        </li>
                    @endif
                @else
                    <li class="nav-item dropdown">
                        <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button"
                            data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                            {{ Auth::user()->name }}
                        </a>

                        <div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
                            <a class="dropdown-item" href="{{ route('logout') }}"
                                onclick="event.preventDefault();
                                             document.getElementById('logout-form').submit();">
                                登出
                            </a>

                            <form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
                                @csrf
                            </form>
                        </div>
                    </li>
                @endguest
                </ul>
            </div>
        </div>
    </div>
</header>

header.blade.php

这里先空着,占个位置

<footer>

</footer>

app.blade.php

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    @vite(['resources/sass/app.scss', 'resources/js/app.js'])
</head>
<body>
    <div id="app">
        <main>
            @include('layouts.header')
            @yield('content')
        </main>
        @include('layouts.footer')
    </div>
</body>
</html>

当然,对应的 css 也要的。

我们先在 resources/sass/app.scss 中添加。

# 定义你的主题色
$primary-color: #ECB34D;

html,
body {
    height: 100%;
    color: #000000;
    background: #f4f4f4;
    font-family: "PingFang SC", "微软雅黑", "Microsoft YaHei", Helvetica,
        "Helvetica Neue", Tahoma, Arial, sans-serif;
    font: 14px "PingFang SC", "微软雅黑", "Microsoft YaHei", Helvetica,
        "Helvetica Neue", Tahoma, Arial, sans-serif;
}

a,
a:link,
a:active,
a:hover,
a:visited,
a:focus {
    text-decoration: none;
    list-style: none;
    outline: none;
    cursor: pointer;
}

ul {
    list-style: none;
    list-style-type: none;
}

button:focus,
button:active:focus,
button.active:focus,
button.focus,
button:active.focus,
button.active.focus {
    outline: none;
}

.btn-primary {
    color: #fff !important;
}

#app {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    height: 100%;

    main {
        display: flex;
        flex-direction: column;
        flex: 1 0 auto;
    }
}

header {
    height: 72px;

    // 导航
    .main-nav {
        .nav-item {
            display: flex;
            padding: 7px 16px;
            border-radius: 4px;
            color: #383838;
            margin-right: 16px;

            .nav-link {
                padding: 0 !important;
                background-color: inherit !important;
                font-weight: 300 !important;
                font-size: 16px !important;
                line-height: 20px !important;
                color: #383838;
            }
        }

        .nav-item.active {
            background-color: $primary-color;
        }

        .nav-item.active>.nav-link {
            color: #fff;
        }

        .nav-item:not(.active):hover {
            background-color: $primary-color;
        }

        .nav-item:not(.active):hover>.nav-link {
            color: #fff;
        }
    }
}

footer {
    width: 100%;
    height: 220px;
    background-color: #383838;
}

最后,修改下 home.blade.php

@extends('layouts.app')

@section('content')

<div class="container pt-4">
    <div class="row justify-content-center">
        <h2>home</h2>
    </div>
</div>
@endsection

然后,在打开首页看看。

一些说明

域名其实我自己配置的是 ypb2.com。所以看到的是截图上的样子。 然后访问是 http,上服务器是要配置成 https 的。还有 favicon 也没有配置。以及看代码 keywords 等都没有处理。后边都会要完善的。以及页面的 loading 也没处理。虽然那么多年过去了,还是喜欢用 nprogress 那样的方式。

提交代码

git add .
git commit  -m '处理页面的连接以及基本配置'