沒有使用過 blade 開發專案,筆記一下摸索過程
文後附上學習資源
blade 樣板引擎
一般在做 muti-page 網站時,常常會遇到重複區塊的問題。舉例來說一個科技新聞網的 header、navbar、footer 是重複的內容,要改變的只有 page-content 區塊。
Laravel 透過 blade 解決這個問題。利用像是物件導向的方法,讓視圖可以「引用」重複的內容,並讓子視圖可以「擴充」父視圖。
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="csrf-token" value="{{ csrf_token() }}" />
<link href="{{ mix('css/app.css') }}" type="text/css" rel="stylesheet" />
<style>
<!-- 一堆 link -->
</style>
</head>
<body>
<nav class="navbar">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="{{ url('category/techonology') }}">科技</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('category/marketing') }}">行銷</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('category/management') }}">管理</a>
</li>
</ul>
</nav>
<div class="page-content flex-center position-ref full-height">
<!-- -->
</div>
<footer class="py-5 bg-dark">
<div class="container">
<p class="m-0 text-center text-white">Copyright © 科技新聞網 2020</p>
</div>
</footer>
</body>
</html>
@include
現在我們可以把剛剛的 HTML 重複的 navbar、footer 元件化,並在 master 組合(header 就直接寫在 master 裡)。
視圖透過 @include 引用其他視圖已經實作的 HTML。
檔案結構
resources
|-layouts
|---master
|---partials
|-----navboar
navbar
<nav class="navbar">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="{{ url('category/techonology') }}">科技</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('category/marketing') }}">行銷</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('category/management') }}">管理</a>
</li>
</ul>
</nav>
master
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="csrf-token" value="{{ csrf_token() }}" />
<link href="{{ mix('css/app.css') }}" type="text/css" rel="stylesheet" />
@yield('page-style')
</head>
<body>
@include('layouts.partials.navbar')
@yield('page-content')
<!-- 下一段解釋 -->
@include('layouts.partials.footer')
<script src="{{ mix('js/app.js') }}" type="text/javascript"></script>
</body>
</html>
@yield
(父)視圖可以使用 @yield 指令「預留」一個區塊給其他視圖擴充。
(子)視圖透過 @extends 指定要擴充的視圖、@section 包夾的區塊則必須實作 @yield 指令所預留的區塊。
master
@yield('page-content')
<!-- 預留一塊必須實作的區塊 -->
post
@extends('layouts.master')
<!-- 指定擴充 master -->
@section('page-content')
<!-- 實作內容 -->
@endsection
規劃檔案結構
layouts 放重複的共用程式、categories 裡有文章總覽(allpost)與單篇文章(post),因為文章總覽頁與單篇文章頁排版不同,所以是兩個樣板文件。
resources
|-layouts
|---master
|---partials
|-----navboar
|-----footer
|-categories
|---allpost
|---post
參考程式碼
master
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="csrf-token" value="{{ csrf_token() }}" />
<link href="{{ mix('css/app.css') }}" type="text/css" rel="stylesheet" />
@yield('page-style')
</head>
<body>
@include('layouts.partials.navbar')
@yield('page-content')
@include('layouts.partials.footer')
<script src="{{ mix('js/app.js') }}" type="text/javascript"></script>
</body>
</html>
allpost
@extends('layouts.master')
@section('page-style')
<link href="{{ asset('css/posts.css') }}" rel="stylesheet">
@endsection
@section('page-content')
<!-- Page Content -->
<div class="container">
<!-- Page Features -->
<div class="row text-center">
@foreach(range(1, 4) as $id)
<div class="col-lg-3 col-md-6 mb-4">
<div class="card h-100">
<img class="card-img-top" src="http://placehold.it/500x325" alt="">
<div class="card-body">
<h4 class="card-title">文章標題 {{ $id }}</h4>
<p class="card-text">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sapiente esse necessitatibus neque.
</p>
</div>
<div class="card-footer">
<a href="{{ url('posts/'.$id) }}" class="btn btn-primary">閱讀全文</a>
</div>
</div>
</div>
@endforeach
</div>
<!-- /.row -->
</div>
<!-- /.container -->
@endsection
post
@extends('layouts.master')
@section('page-style')
<link href="{{ asset('css/posts.css') }}" rel="stylesheet">
@endsection
@section('page-content')
<!-- Page Content -->
<div class="container">
<div class="row">
</div>
<!-- /.row -->
</div>
<!-- /.container -->
@endsection