---
# System prepended metadata

title: '[Laravel入門]部落格從零開始實作攻略 #by Voyager'
tags: [Laravel教學已拍]

---

###### tags: `Laravel教學已拍`

# [Laravel入門]部落格從零開始實作攻略 #by Voyager
![](https://i.imgur.com/v3BZ7f9.jpg)


## 課程介紹

你是正在入門的Laravel新手還是還是喜愛VUE開發的前端工程師?
你是否有實作後台功能的問題需要解決呢?
我準備了第二支實戰影片來解決你們的問題，同樣地一點都不難!

這影片將示範
如何建立文章分類
如何製作部落格總覽頁
如何生成假資料
如何製作文章呈現頁
如何自動生成後台介面
如何動態從後台管理選單
如何動態從後台管理設定

仍在Laravel入門的你，從此不再需要再為後台開發除錯而充滿挫折
喜歡專注於VUE開發的你，從此升級為全棧工程師，自己搞定後台

這支影片花了我大量的時間，希望能透過實作的每個環節來讓你了解如何善用Voyager在項目中，足以作為付費課程內容，一段時間之後可能就會下架，如果有需要的話，可要趕緊在下架前學起來唷!

我知道你擔心自己跟不上，這支影片是一步步的帶著你作出部落格，再加上觀念說明，所以長度超過90分鐘，就算不熟PHP的你都做得到!

想要學習嗎? 告訴你個好消息，影片已經上架，趕緊在下架前搶個好位置來學習自動生成後台技術吧!

https://youtu.be/Jv7JPnWwxYg
## 腳本

### 導言

各位小夥伴大家好 我是哥布林工程師

有不少小夥伴希望能夠有Voyager的實戰教學
所以我從去年就規劃了Voyager實戰的系列教學
之前的第一支從零開始實戰影片也得到不錯的迴響
因此今天這個單元將繼續分享如何使用Voyager
來快速建構出一個帶後台的部落格

從這個教學裡頭你將學到Voyager套件的核心架構
以及如何結合Laravel來作部落格極速開發
如果你對於後台自動生成技術感興趣的話 
今天這個單元可千萬不要錯過

如果課程進行中有任何問題想詢問的話
歡迎透過Line官方帳號和我們聯繫
我們的官方帳號是@iax8678g
那麼就讓我們開始吧

---

### 專案準備

首先我們先來準備專案資料夾
如果你已經很熟悉專案準備環節可以跳到實作章節

課程是假設大家都已經擁有Laravel的開發環境
如果還沒有開發環境的小夥伴也沒關係
你可以參考我放在資訊欄的環境建置筆記

第一步 先建立一個新的專案
開啟Terminal 輸入以下指令

`laravel new webs`

webs 就是專案的名稱

> 建立新專案示範

第二步 要為專案建立資料庫
名稱同樣取為 webs
資料庫編碼請選擇utf8mb4
這樣才能支援表情符號

> 建立資料庫示範

第三步 確認專案的設定是否正確

第一個確認 config/app.php

第二個確認 .env 隱私設定檔

> 確認設定檔示範

第四步 下載 Voyager 套件

開啟Terminal 輸入以下指令

`composer require tcg/voyager`

> 下載套件示範

第五步 安裝 Voyager 套件

輸入以下指令

`php artisan voyager:install`

這一步其實可以加上--with-dummy選項就能安裝假資料 
但我今天的實作不會用到假資料
有需要的小夥伴你可以自己試試看

> 安裝Voyager套件示範影片

第六步 Voyager安裝完畢
代表後台已經生成了 但是我們還沒有帳號能夠登入
所以這一步 需要生成管理員帳號
輸入以下指令

`php artisan voyager:admin admin@admin.com --create`

這裡加上create選項是表示這個使用者還不存在需要新增

接著Terminal就會以互動的方式要求你輸入使用者相關的欄位資料

> 建立管理員帳號示範影片

最後完成管理者帳號的建立

第六步 最後我們確認看看後台能否正常登入與使用

開啟瀏覽器輸入專案網址並在後面加上/admin

http://webs.test/admin

在登入頁面輸入剛才設定的帳號與密碼
如果一切順利你應該就能看到Voyager的後台
後台的文字也應該都是繁體中文才對
如果你看到的是英文版本 就代表第三步確認設定出了問題 
請回去再看一次然後把資料庫清空再做一次

到這裡我們已經完成了部落格專案的前置準備

接下來是實作展示章節
我們只會直接用Laravel的機制示範如何實作
不會詳細說明每個機制
如果你想了解更多細節歡迎參考我在Hahow的課程
Laravel 5.8 從入門到實務

對了 如果你是第一次來到我們頻道的話
哥布林挨踢頻道是專注於電腦科學相關的課程
每週四下午6點都有新的影片上線
如果聽完今天的單元覺得對你有幫助的話
請幫忙給影片按讚訂閱我們的頻道
也別忘了開啟小鈴鐺唷

---
### 前台套版導入

這次實作的前端是使用免費的前端版型Moderna
方便大家可以拿來練習
它的網址會列在下方資訊欄

實際上你可以替換成任何自己喜歡的版型
作法都一樣也不會有任何問題的 請放心
另外這次的實作展示的所有內容
都會放在筆記本當中
所有的程式碼也都可以到筆記本裡頭去複製
筆記本連結請參考底下資訊欄

這一小節 我們來示範前端套版的導入

> 前台套版導入示範影片
　
 
進到Moderna官網
點Free Download來把版型下載到電腦裡頭
我們選擇 Bootstrap v4的版本
下載並解壓縮後會看到一堆的html範例檔以及assets資料夾
請把assets資料夾放進public資料夾
而blog.html以及blog-single.html
就是我們這次要使用的模版

把這兩個檔案複製到resources/view資料夾內
blog.html更名為 blog.blade.php
blog-single.html更名為 post.blade.php

新增一個控制器 名為SiteController
開啟Terminal，輸入以下指令

`php artisan make:controller SiteController`

開啟 SiteController.php
我們將要加入兩個新的方法來呈現部落格頁面
請輸入以下程式碼:

```
//app\Http\Controllers\SiteController.php

public function renderBlogPage(){
    return view('blog');
}

public function renderPostPage(){
    return view('post');
}
```

接著要在路由檔去加入路由來將請求分配給新的控制器方法

為了簡化設定路由時避免每次都要寫控制器的命名空間
需要開啟RouteServiceProvider.php
把$namespace的註解打開來
這樣之後分配控制器就可以省略掉命名空間了

開啟 web.php
請輸入以下程式碼:

```
//routes\web.php

Route::get('/blog','SiteController@renderBlogPage');
Route::get('/blog/{post}','SiteController@renderPostPage');
```

完成之後，開啟瀏覽器輸入專案網址以及blog路徑
看看網頁是否正常出現

到這裡我們已經完成前端框架的導入 是否很簡單呢

---
### 示範 Blade重構

當你確認blog/1路徑時會發現整個佈局都亂掉了
代表樣式檔案的路徑出現了問題

所以這個章節將示範如何解決這個問題同時優化這兩支Blade檔案

> Blade重構示範影片

首先我們解決Post頁面佈局跑掉的問題
請開啟post.blade.php

你會發現目前所有資源路徑都是相對路徑
這將導致如果網址路徑有子目錄的話像是blog/1
就會導致資源路徑錯誤
那修改的方向也很簡單
就是將所有路徑都改為絕對路徑這樣就不會有這問題了
不過如果如果自己打絕對路徑又會有和網址耦合
導致放上正式環境時又會出現問題
因此這裡我們使用Laravel提供的幫助函式asset()
來代替我們生成資源的絕對路徑

改完之後再測看看，果然問題都解決了
不過如果每一頁都這樣改實在太麻煩
而且如果你仔細觀察的話會發現
blog和post這兩個頁面有很多的結構極為類似
應該要簡化才對

> >版型分割說明

我們在views資料夾新增一個layouts子資料夾
並在裡頭新增 site.blade.php
我們將在這檔案裡面移入重複的結構並挖一個名為content的洞
接著刪除原先兩個Blade檔案裡頭重複的內容，繼承site視圖
最後用剩下的內容來填入content這個洞，就完成囉

當兩個檔案都完成之後訪問看看兩個網址是否都能正常顯示
沒有意外的話都正常，也就完成了Blade檔案的重構環節

---
### 示範 如何準備需要的表格

這一小節 我們要示範如何建立分類與文章這兩個表格
透過Laravel的Migration機制來達成

> Laravel的Migration示範

#### 示範腳本

一個簡單的部落格主要是透過分類Cgy以及文章Post來組成
為了簡化示範，我已經把Migration檔案內容準備好了
就像是這個樣子 大家可以直接到筆記本去複製下來改用


```
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCategoriesTable extends Migration
{
    public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->id();

            $table->bigInteger('parent_id')->nullable()->unsigned()->index(); //父分類
            $table->foreign('parent_id')->references('id')->on('categories')->onDelete('cascade');
            $table->string('title',100); //分類名稱
            $table->string('pic',255)->nullable(); //分類圖片
            $table->string('desc',500)->nullable(); //分類描述
            $table->boolean('enabled')->default(true);//是否啟動
            $table->integer('sort'); //排序
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::table('categories', function(Blueprint $table)
        {
            $table->dropForeign(['parent_id']);
        });
        Schema::dropIfExists('categories');
    }
}

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->bigInteger('category_id')->unsigned()->index(); //文章分類
            $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
            $table->string('title', 40); //標題
            $table->string('content_small', 80)->nullable(); //部分內容
            $table->text('content'); //內容
            $table->integer('sort')->default(0); //排序
            $table->string('status', 30)->default('pending'); //狀態
            $table->string('pic', 255); //圖片
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->dropForeign(['category_id']);
        });
        Schema::drop('posts');
    }
}

```

我們就用它來建立Migration檔案
開啟Terminal 輸入以下指令

`php artisan make:migration create_categories_table`
`php artisan make:migration create_posts_table`
`php artisan migrate`

完成後確認一下表格是否正常生成

---
### 假資料建立示範

有了表格接下來就是要填入假資料的環節了
接下來我將要示範的是如何利用Laravel的Seed機制來建立資料

首先開啟Terminal，輸入以下幾個指令

`php artisan make:model Category`

這個指令將會生成categories表格的模型，用來進行表格的互動

`php artisan make:seeder CategorySeeder`

這個指令將會生成CategorySeeder檔案，用來生成假資料

這裡要注意如果安裝Voyager1.4版本
會生成seeds資料夾，導致所有新生成的seeder檔案被放在這個資料夾
請將它們搬回seeders資料夾才會與namespace一致

`php artisan make:factory CategoryFactory`

這個指令將會生成CategoryFactory，用來定義假資料各欄位的內容

開啟 database/seeders/CategorySeeder.php
將以下程式碼貼入

```
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\Category;

class CategorySeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Category::truncate();
        Category::factory(5)->create();
    }
}
```

開啟 database/factories/CategoryFactory.php
將以下程式碼貼入

```
<?php

namespace Database\Factories;

use App\Models\Category;
use Illuminate\Database\Eloquent\Factories\Factory;

class CategoryFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Category::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'title' => $this->faker->realText(10),
            'pic' => 'assets/img/recent-posts-'. rand(1,4) .'.jpg',
            'desc' => $this->faker->realText(200),
            'enabled' => true,
            'sort' => rand(0,10)
        ];
    }
}
```

開啟database/seeders/DatabaseSeeder.php
修改成以下程式碼:

```
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use DB;
use Eloquent;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {   
        Eloquent::unguard();
        DB::statement('SET FOREIGN_KEY_CHECKS=0');
        $this->call([CategorySeeder::class]);
        DB::statement('SET FOREIGN_KEY_CHECKS=1');
        Eloquent::reguard();
    }
}
```
輸入以下指令，來新增假資料

`php artisan db:seed`

開啟資料庫管理工具，看看分類資料是否建立成功了勒
如果你發現假資料是英文和我的不一樣
那是因為我有修改 config/app.php檔案裡頭

`'faker_locale' => 'zh_TW',`
將Faker假資料的語系設定為繁體中文的關係
你修改設定之後再執行一次db:seed
就會是中文的了

接下來要處理posts表格了，一樣會有剛才的三個指令

再次開啟Terminal，輸入以下幾個指令

`php artisan make:model Post`

生成posts表格的模型

`php artisan make:seeder PostSeeder`

生成PostSeeder檔案

一樣把新生成的seeder檔案搬回seeders資料夾

`php artisan make:factory PostFactory`

生成posts的工廠

開啟 database/seeders/PostSeeder.php
將以下程式碼貼入

```
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\Post;

class PostSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Post::truncate();
        Post::factory(100)->create();
    }
}
```
開啟 database/factories/PostFactory.php
將以下程式碼貼入

```
<?php

namespace Database\Factories;

use App\Models\Post;
use Illuminate\Database\Eloquent\Factories\Factory;

class PostFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Post::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'category_id' => rand(1,5),
            'title' => $this->faker->realText(20),
            'content_small' => $this->faker->realText(50),
            'content' => $this->faker->realText(200),
            'sort' => rand(0,10),
            'status' => $this->faker->randomElement(['draft','published']),
            'featured' => $this->faker->boolean,
            'pic' => 'assets/img/blog-post-' .rand(1,4).'.jpg'
        ];
    }
}
```

開啟database/seeders/DatabaseSeeder.php
修改成以下程式碼:

```
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use DB;
use Eloquent;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {   
        Eloquent::unguard();
        DB::statement('SET FOREIGN_KEY_CHECKS=0');
        $this->call([CategorySeeder::class,PostSeeder::class]);
        DB::statement('SET FOREIGN_KEY_CHECKS=1');
        Eloquent::reguard();
    }
}
```

輸入以下指令，來新增文章假資料

`php artisan db:seed`

開啟資料庫管理工具，看看文章資料是否建立成功了勒

最後，我們再來新增一個tags表格及其pivot表格 post_tag
用來儲存文章的標籤以及文章和標籤之間的關係

輸入以下指令來建立標籤的Migration檔案

`php artisan make:migration create_tags_table`

檔案的內容修改如下:

```
    public function up()
    {
        Schema::create('tags', function (Blueprint $table) {
            $table->id();
            $table->string('title',50);
            $table->string('url',255)->nullable();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('tags');
    }
}
```
輸入以下指令來建立標籤的模型

`php artisan make:model Tag`

輸入以下指令來建立pivot表格的Migration檔案

`php artisan make:migration create_post_tag_table`

檔案的內容修改如下:

```
public function up()
{
    Schema::create('post_tag', function (Blueprint $table) {
        $table->id();
        $table->bigInteger('post_id')->unsigned()->index();
        $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
        $table->bigInteger('tag_id')->unsigned()->index();
        $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
        $table->timestamps();
    });
}


public function down()
{
    Schema::table('post_tag', function (Blueprint $table) {
        $table->dropForeign(['post_id']);
        $table->dropForeign(['tag_id']);
    });
    Schema::dropIfExists('post_tag');
}
```
---
### 示範 前台串接

現在有個資料，我們就可以把前台的資料改成由後台提供囉
等會我們將要修改SiteController.php
把資料拋進View視圖內
接著再修改View視圖去取用這些資料
就完成了前台的串接了

> 前台串接示範

#### 示範腳本

##### 處理blog頁面
1.編輯AppServiceProvider.php

```
use View;
...
View::composer(['blog','post'], function ($view) {
    $categories = Category::where('enabled',true)->orderBy('sort','asc')->get();
    $view->with('categories',$categories);
});
```
2.編輯SiteController.php

```
public function renderBlogPage()
{
    $posts = Post::where('status','published')->orderBy('created_at','desc')->get();
    return view('blog',compact('posts'));
}
```
    
3.編輯blog.blade.php

```
//重要程式
$post->created_at->toDateString()
$post->created_at->toFormattedDateString()
```

##### 處理分頁

1.輸入指令 

`php artisan vendor:publish --tag=laravel-pagination`

2.再回去調整AppServiceProvider.php
```
//app\Providers\AppServiceProvider.php

use Illuminate\Pagination\Paginator;=

public function boot(){
    ...
    Paginator::defaultView('pagination::bootstrap-4');
}

```
        
3.修改vendor/pagination/bootstrap-4.blade.php

4.修改SiteController.php

```
//app/Http/Controllers/SiteController.php

public function renderBlogPage()
{
    $posts = Post::where('status','published')->orderBy('created_at','desc')->paginate(5);
    return view('blog',compact('posts'));
}
```
5.修改blog.blade.php

```
//resources/views/blog.blade.php

//重要程式
{{ $posts->links() }}
```

##### 處理分類清單

1.建立資料夾 resources/view/partials
2.建立並編輯視圖 resources/view/partials/categories.blade.php

```
\\resources/view/partials/categories.blade.php

<div class="sidebar-item categories">
    <ul>
        @foreach ($categories as $category)
            <li><a href="#">{{ $category->title }}<span>(25)</span></a></li>
        @endforeach
    </ul>

</div><!-- End sidebar categories-->
```

3.修改blog.blade.php

```
//resources/views/blog.blade.php

//重要程式
@include('partials.categories')
```

##### 加入分類的文章數

1.編輯App\Models\Category.php

```
//app\Models\Category.php

use App\Models\Post;

public function posts(){
    return $this->hasMany(Post::class);
}
```

2.調整AppServiceProvider.php
```
//app\Providers\AppServiceProvider.php

use Illuminate\Database\Eloquent\Builder;

function(){
    View::composer(['blog','post'], function ($view) {
        $categories = Category::where('enabled',true)->orderBy('sort','asc')->withCount(['posts' => function (Builder $query) {
        $query->where('status', 'published');
        }])->get();
        ...
    });
}

```
3.修改視圖 resources/view/partials/categories.blade.php 

```
//resources\view\partials\categories.blade.php 

<span>({{$category->posts_count}})</span>
```

##### 處理post頁面

1.編輯App\Models\Post.php

```
//app\Models\Post.php

use App\Models\Category;

public function category(){
    return $this->belongsTo(Category::class);
}
```

2.編輯post.blade.php


---
### 示範 Voyager 的BREAD

這一小節 我們要示範如何導入Voyager來實作CRUD

現在前端的資料都來自於Blade檔 還沒有與資料庫連結
所以接下來我將要示範如何改由Voyager來管理資料庫的資料

> Voyager的BREAD示範

接著就要開始Voyager的功能設定作業了

在進到BREAD的設定實作之前先簡單的說一下
在Voyager裡頭兩個很重要的表格
分別是 data_types 以及 data_rows
這邊說明一下DataType以及DataRow的關係
每個資料庫表格都會有一個DataType來紀錄該表格的BREAD設定
而每個DataType擁有多個DataRow來說明各欄位的BREAD設定

進到後台開啟 BREAD 功能
這時候 cgies 和 posts 的 BREAD 功能還沒建立
先來建立它們

接著開始設定這兩個表格的BREAD

> BREAD 設定說明

完成設定之後，你就有個CRUD介面可以使用囉
我們就可以管理先前建立的分類和文章資料

> 示範編輯&刪除文章

> >這裏會出現Translate錯誤，需要編輯App/Models/Post.php

```
//app\Models\Post.php

use TCG\Voyager\Traits\Translatable;

class Post extends Model
{
    use Translatable;
    ...
```

完成之後，開啟瀏覽器輸入專案網址以及blog/1路徑
看看文章資訊是否有修改

---



另外BREAD可以說是Voyager的核心
透過剛才的展示沒辦法把所有細節講完
建議大家可以去參考我整理的Voyager中文技術手冊

---
### 示範讓前台的圖片顯示能夠支援Voyager

在剛才我們在編輯文章資料的時候有上傳一張新圖上去
但是圖片並沒有正常顯示在前台
這是為什麼呢?

> 示範讓Voyagr圖片能顯示在前台

#### 示範腳本

因為一開始我們的圖片呈現處是使用從public資料夾來取檔
但是當利用Voyager來管理圖片檔案之後
所有圖片是被存在storage/app/public這裡的資料夾
導致路徑上出現了差異因而無法正常顯示

了解問題原因之後處理起來就很簡單
Voyager有提供一個幫助函式來幫助我們生成圖片絕對路徑
就是Voyager::image()

因此我們只要到圖片呈現的位置改成這樣即可

改完之後再回前台確認看看是否就正常囉
---
---
### 示範 Voyager 的選單管理員

接下來這一小節 我們要示範如何利用Voyager來管理前端的選單

目前前端的選單結構都是寫死在Blade檔裡頭
但其實Voyager就有個選單管理員可以來幫助我們管理選單
接著我來展示該如何使用

> 主選單建立示範

#### 示範腳本

在開始之前我們需要做一點準備
假設我們需要有個選單能夠顯示不同分類的文章
因此我們就需要有個新路由
並且還有個SiteController的新方法來處理請求

因此開啟web.php，加入以下路由規則

```
//routes\web.php

Route::get('/blog/cateogry/{category}','SiteController@renderBlogPageByCategory');
```

開啟SiteController.php，加入以下程式

```
//app\Http\Controllers\SiteController.php

public function renderBlogPageByCategory($category_id)
{
    $category = Category::findOrFail($category_id);
    $posts = $category->posts;
    return view('blog',compact('posts'));
}
```

成為之後就可以到後台的選單管理員來建立選單囉

完成了選單的建立接著就可以回到前台來叫用囉
這裡就可以先將選單的程式碼先註解掉改成以下的程式碼

`{{ menu('frontend')}}`

frontend就是我們剛為選單所取的名字

完成之後，開啟瀏覽器輸入專案網址以及blog路徑
看看網頁上的主選單是否有出現內容

你會發現內容確實有出來但遺憾的是格式卻跑掉了
怎麼辦呢 你不用擔心
Voyager早就為你想到了
因為大部分套版都有自定義樣式類別 
如果沒在標籤中加入這些樣式類別就無法正常出現
因此我們必須要新增一個選單視圖並告知menu()要使用它

請在views資料夾建立一個menu子資料夾
並在裡頭建立primary.blade.php 檔案

裡頭程式碼像這樣

```
//resources/views/menu/primary.blade.php

<nav class="nav-menu float-right d-none d-lg-block">
    <ul>
        @foreach($items as $item)
            @php
                $sub2menu = $item->children;
            @endphp
            @if(isset($sub2menu) && count($sub2menu) > 0)
                <li class="drop-down"><a href="{{$item->link()}}">{{$item->title}} </a>
                <ul>
                    @foreach($sub2menu as $sub2_item)
                        <li><a href="{{$sub2_item->link()}}">{{$sub2_item->title}} </a></li>
                    @endforeach
                </ul>
            @else
                <li><a href="{{$item->link()}}">{{$item->title}} </a>
            @endif
        </li>
        @endforeach
    </ul>
</nav>
```

再回到前台視圖 把menu()加入第二參數
也就是選單視圖改用menu資料夾的primary

`{{ menu('frontend','menu.primary') }}`


完成之後，再開啟瀏覽器輸入專案網址以及blog路徑
看看這次網頁上的選單是否格式就正確了

---


這個技巧除了可以用來製作上方的主選單
實際上還有很多地方都可以利用選單管理員來進行管理唷
想到的夥伴歡迎到底下留言來討論唷

---

### 示範 Voyager 設定管理員

最後這一小節 我們要示範如何利用Voyager來管理前端的參數
比如每一頁要呈現的筆數

> 設定管理員示範

#### 示範腳本

目前每一頁要呈現的筆數是寫死在SiteController內
修改較為不便
我們將透過Voyager的設定管理員來幫我們管理分頁數設定
將分頁顯示文章數設定移到後台去

進到Voyager後台的設定管理員
在admin這個群組加上posts_per_page這組設定

> 在設定管理員加入設定

完成之後預設你會看到旁邊有程式碼提示
告訴你可以怎麼去取得設定
因此你可以把這段複製起來
貼到SiteController.php替換掉原本的內容

當我們把這些內容全都替換完畢後儲存
再開啟瀏覽器輸入專案網址以及blog路徑
看看現在每一頁的文章數目是否發生變化了呢?

---

透過這次的部落格網頁實作
我們展示了Voyager的BREAD
選單管理員以及設定管理員的使用
並簡單示範如何與Laravel結合

如果這個單元的示範 你覺得意猶未盡
不用擔心 我為大家準備好了EzLaravel套件
裡頭的demo/articles頁有今天這個示範的完整程式碼供你參考
關於EzLaravel套件的使用說明
請參考資訊卡或底下資訊欄

更棒的是這個套件不只是作為範例 
你可以用它來快速建置你的網站
裡頭已經為網頁元素以及文章等表格建立了完整的BREAD設定了
連CRUD視圖都客製好 方便你提包入住

之後我仍將利用Voyager來為你示範更多應用
如果有你想知道而我沒展示的 請在底下留言
也許下個單元我就會製作你要的應用囉

如果今天的示範教學你覺得有幫助的話
希望你能夠訂閱我們頻道並開啟小鈴鐺
以免錯過我為你製作的下一支教學影片

我是哥布林工程師，我們下次再見，掰掰

## 影片時間軸

影片開始 00:00
專案準備 01:24　
前台套版導入 08:27
示範視圖優化 12:28
示範資料建立 24:13
示範前台串接 35:41　
示範Voyager的BREAD 01:08:23
動態選單製作　01:19:36 
動態設定製作 01:27:33
課後總結 01:29:29



## 參考網址

[Laravel5.8 從入門到實戰](https://hahow.in/cr/goblinlab-laravel58)
[一頁式網站從零開始](https://youtu.be/wXg0ZdH9Kl0)
[Moderna前台套版](https://bootstrapmade.com/free-bootstrap-template-corporate-moderna/download/)
[課程筆記](https://hackmd.io/@goblinlab/HkfOPdR1d)
[Laravel環境建置](https://hackmd.io/@javck/H1nqUaNh8)
[EzLaravel套件介紹影片](https://youtu.be/J5SjwZ2aY6c)
[Voyager套件簡介影片](https://youtu.be/ZW4RLDDUuFQ)




