Ray Lee | 李宗叡
Learn or Die
Published in
46 min readDec 20, 2020

--

Photo by Ferenc Almasi on Unsplash

# 前言

我喜歡使用 Laravel 開發的感覺, 除了開發快速, 程式碼簡潔且優雅之外, Laravel 框架本身也是一個很好的學習參照物。 本篇主要將官方文件重點整理成 Q&A 的形式呈現, 原子化的概念, 這方式並不適用於每個人, 但若對你有幫助, 我會很開心。

# 版本

Laravel 8.x

# 目錄

Laravel — 官方文件原子化翻譯 — 目錄

# Template Inheritance

# Defining A Layout

以下的 Laravel example code 的意思是?

  • Example:
<!-- Stored in resources/views/layouts/app.blade.php -->

<html>
<head>
<title>App Name - @yield('title')</title>
</head>
<body>
@section('sidebar')
This is the master sidebar.
@show

<div class="container">
@yield('content')
</div>
</body>
</html>
  • Answer:
<!-- stored in resources/views/layouts/app.blade.php -->

<html>
<head>
<!-- 此 app file 可作為 layout file 讓其他 file extends -->
<!-- 假設, 當 child file extends app file 時, child file -->
<!-- 會有 app.file 上的所有內容, 那如果我想要在 child file 特定的位置加入 -->
<!-- 一些只屬於 child file 的 code, 那便可以使用 @yield 事先在 app file -->
<!-- 如下 example, 當我在 child file 使用 @section('title') -->
<!-- 那我就可以在 @yield 定義的位置, 加入只屬於 child file 的 code -->
<title>app name - @yield('title')</title>
</head>
<body>
@section('sidebar')
this is the master sidebar.
<!-- @show 等於 @endsction 之後, 在 @yield('sidebar') -->
@show

<div class="container">
<!-- 將此位置定義為 'content', 所有 extends app file 的 view -->
<!-- 都可以使用 @section('content') 加入該 view 需要的 code -->
@yield('content')
</div>
</body>
</html>

# Extending A Layout

以下的 Laravel example code 的意思是?

  • Example:
<!-- Stored in resources/views/child.blade.php -->

@extends('layouts.app')

@section('title', 'Page Title')

@section('sidebar')
@parent

<p>This is appended to the master sidebar.</p>
@endsection

@section('content')
<p>This is my body content.</p>
@endsection
  • Answer:
<!-- Stored in resources/views/child.blade.php -->

<!-- extends layouts.app file, 因此會使用 app file 的所有佈局 -->
@extends('layouts.app')

<!-- @yield 會定義在 layout file 的位置, 而 @section -->
<!-- 可以指定要在哪個 yield 的位置插入 code, 這些 code 會被 -->
<!-- render 在 child page, arg2 為縮寫, 直接輸入要插入的 code -->
<!-- 並省略掉 @endsection -->
@section('title', 'Page Title')

<!-- 如果沒有 @parent, 則會 render child page 的 section 內的 code -->
<!-- @parent 可使 layout page section 內的 code 不被覆蓋, 達到 append 的效果 -->
@section('sidebar')
@parent

<p>This is appended to the master sidebar.</p>
@endsection

<!-- 在 layout page @yield('content') 的位置插入以下的 code -->
@section('content')
<p>This is my body content.</p>
@endsection

以下的 Laravel example code 的意思是?

  • Example:
@yield('content', View::make('view.name'))
  • Answer: 定義此位置為 'content', 並定義預設值為 'view.name' page, 所以 extends 此 example 的 child page 都可以使用 @section('content') 在此位置插入 code, 如果 child page 沒有定義 @section('content') 的話, 則使用預設值 'view.name' page

以下的 Laravel example code 的意思是?

  • Example:
<?php
Route::get('blade', function () {
return view('child');
});
  • Answer: 當收到 Request to url ‘blade’, 回傳 ‘child’ view, 可以是一個 blade view

# Displaying Data

以下的 Laravel example code 的意思是?

  • Example:
<?php
Route::get('greeting', function () {
return view('welcome', ['name' => 'Samantha']);
});
  • Answer: 當收到 Request 5o ‘greeting’ uri, 回傳 ‘welcome’ view page, 並帶著 ['name' => 'Samantha'], 並在 view page 可以 display 'name' Hello, {{ $name }}

以下的 Laravel blade example code 的意思是?

  • Example:
The current UNIX timestamp is {{ time() }}.
  • Answer: 使用 blade 語法, 可以在 {{ }} 內執行任何 PHP function

# Displaying Unescaped Data

以下的 Laravel blade example code 的意思是?

  • Example:
Hello, {!! $name !!}.
  • Answer: blade 語法 {{ }} 預設會執行 PHP 的 htmlspecialchars method, 若不希望資料經過 escaped, 可以使用 {!! !!}

# Rendering JSON

以下的 Laravel blade example code 的意思是?

  • Example:
<script>
var app = @json($array);

var app = @json($array, JSON_PRETTY_PRINT);
</script>
  • Answer: blade 語法, @json() 相當於 json_encode(), 預設使用 JSON_HEX_TAG, JSON_HEX_APOS, JSON_HEX_AMP, JSON_HEX_QUOT flags

# HTML Entity Encoding

以下的 Laravel example code 的意思是?

  • Example:
<?php

namespace App\Providers;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Blade::withoutDoubleEncoding();
}
}
  • Answer: Blade 預設會 double encode HTML entities, 若要關閉 double encoding, 可在 AppServiceProvider 的 boot() 中, 使用 Blade 的 withoutDoubleEncoding()

# Blade & JavaScript Frameworks

以下的 Laravel blade example code 的意思是?

  • Example:
<h1>Laravel</h1>

Hello, @{{ name }}.
  • Answer: 許多 JavaScript 框架也會用到 { } 符號來表示某些語法, 可使用 @ 來告訴 Blade 不需對 {{ }} 內的內容做任何動作, 讓他們可以被 JS framework 解析

以下的 Laravel blade example code 的意思是?

  • Example:
{{-- Blade --}}
@@json()

<!-- HTML output -->
@json()
  • Answer: @json() 本是 Blade 的一個 function, 可使用 @ 來 escape Blade 語法, 所以在 HTML 上的輸出會是 @json()

# The @verbatim Directive

以下的 Laravel blade example code 的意思是?

  • Example:
@verbatim
<div class="container">
Hello, {{ name }}.
</div>
@endverbatim
  • Answer: 由於許多 JS Framework 也會使用 {{ }} 來解析變數或一些語法, 如果 Blade page 內有許多的 {{ }} 都是要讓 JS Framework 來解析的話, 可以寫在 @verbatim directive 內

# Control Structures

# If Statements

以下的 Laravel Blade example code 的意思是?

  • Example:
@if (count($records) === 1)
I have one record!
@elseif (count($records) > 1)
I have multiple records!
@else
I don't have any records!
@endif
  • Answer: 使用 Blade 的 if else 語法

以下的 Laravel Blade example code 的意思是?

  • Example:
@unless (Auth::check())
You are not signed in.
@endunless
  • Answer: 使用 Blade 的 unless 語法, 應該是相當語意化了

以下的 Laravel Blade example code 的意思是?

  • Example:
@isset($records)
// $records is defined and is not null...
@endisset

@empty($records)
// $records is "empty"...
@endempty
  • Answer: 同 PHP 的 isset() 以及 empty()

# Authentication Directives

以下的 Laravel Blade example code 的意思是?

  • Example:
@auth
// The user is authenticated...
@endauth

@guest
// The user is not authenticated...
@endguest
  • Answer: 分別定義 authenticated user 以及 unauthenticated user 該做的事

以下的 Laravel Blade example code 的意思是?

  • Example:
@auth('admin')
// The user is authenticated...
@endauth

@guest('admin')
// The user is not authenticated...
@endguest
  • Answer: 分別定義 authenticated user 以及 unauthenticated user 該做的事, 並指定 guard

# Selection Directives

以下的 Laravel Blade example code 的意思是?

  • Example:
@hasSection('navigation')
<div class="pull-right">
@yield('navigation')
</div>

<div class="clearfix"></div>
@endif
  • Answer: 判斷 section 'navigation' 是否有被定義

以下的 Laravel Blade example code 的意思是?

  • Example:
@sectionMissing('navigation')
<div class="pull-right">
@include('default-navigation')
</div>
@endif
  • Answer: 判斷 section 'navigation' 是否沒有被定義

# Environment Directives

以下的 Laravel Blade example code 的意思是?

  • Example:
@production
// Production specific content...
@endproduction
  • Answer: 定義如果 env 為 production 時該做的事

以下的 Laravel Blade example code 的意思是?

  • Example:
@env('staging')
// The application is running in "staging"...
@endenv

@env(['staging', 'production'])
// The application is running in "staging" or "production"...
@endenv
  • Answer: 定義如果 env 為特定的 env 時該做的事

# Switch Statements

以下的 Laravel Blade example code 的意思是?

  • Example:
@switch($i)
@case(1)
First case...
@break

@case(2)
Second case...
@break

@default
Default case...
@endswitch
  • Answer: 同 PHP 的 switch()

# Loops

以下的 Laravel Blade example code 的意思是?

  • Example:
@for ($i = 0; $i < 10; $i++)
The current value is {{ $i }}
@endfor

@foreach ($users as $user)
<p>This is user {{ $user->id }}</p>
@endforeach

@forelse ($users as $user)
<li>{{ $user->name }}</li>
@empty
<p>No users</p>
@endforelse

@while (true)
<p>I'm looping forever.</p>
@endwhile
  • Answer: 同 PHP 的 loop

以下的 Laravel Blade example code 的意思是?

  • Example:
@foreach ($users as $user)
@if ($user->type == 1)
@continue
@endif

<li>{{ $user->name }}</li>

@if ($user->number == 5)
@break
@endif
@endforeach
  • Answer: 同 PHP 的 loop, 也可以 break 中斷 loop

以下的 Laravel Blade example code 的意思是?

  • Example:
@foreach ($users as $user)
@continue($user->type == 1)

<li>{{ $user->name }}</li>

@break($user->number == 5)
@endforeach
  • Answer: 同 PHP 的 loop, 可以將 condition 帶入 continue() 以及 break(), 視條件跳過當次 loop 或中斷整個 loop

# The Loop Variable

以下的 Laravel Blade example code 的意思是?

  • Example:
@foreach ($users as $user)
@if ($loop->first)
This is the first iteration.
@endif

@if ($loop->last)
This is the last iteration.
@endif

<p>This is user {{ $user->id }}</p>
@endforeach
  • Answer: Blade 特有語法, 可在 loop 內使用 $loop variable, 取得關於此 loop 的一些資訊, 如上 example 可判斷該次 loop 是否為第一次獲最後一次

以下的 Laravel Blade example code 的意思是?

  • Example:
@foreach ($users as $user)
@foreach ($user->posts as $post)
@if ($loop->parent->first)
This is first iteration of the parent loop.
@endif
@endforeach
@endforeach
  • Answer: Blade 特有語法, 可在 loop 內使用 $loop variable, 取得關於此 loop 的一些資訊, 如上 example, 可從內圈 loop 中使用 $loop->parent 取得外圈 $loop variable 的資訊

以下的 Laravel Blade example code 的意思是?

  • Example:
@foreach ($users as $user)
$loop->index
$loop->iteration
$loop->remaining
$loop->count
$loop->first
$loop->last
$loop->even
$loop->odd
$loop->depth
$loop->parent
@endforeach
  • Answer:
<!-- Blade 特有語法, 可在 loop 內使用 $loop variable, 取得關於此 loop 的一些資訊, 如上 example, 可從內圈 loop 中使用 $loop->parent 取得外圈 $loop variable 的資訊 -->
@foreach ($users as $user)
<!-- 取得當前 loop index, 從 0 開始 -->
$loop->index
<!-- 取得當前 loop 跑第幾次了, 從 1 開始 -->
$loop->iteration
<!-- 剩餘的 iteration 次數 -->
$loop->remaining
<!-- 總共有幾個 item 要 iterated -->
$loop->count
<!-- 是否為第一個 iteration -->
$loop->first
<!-- 是否為最後一個 iteration -->
$loop->last
<!-- 是否為偶數 iteration -->
$loop->even
<!-- 是否為基數 iteration -->
$loop->odd
<!-- 當前 loop 是位於第幾層 -->
$loop->depth
<!-- 如果位於 nested loop 的話, 取得 parent loop's variable -->
$loop->parent
@endforeach

# Comments

以下的 Laravel Blade example code 的意思是?

  • Example:
{{-- This comment will not be present in the rendered HTML --}}
  • Answer: Blade 特有的 comment 語法, 且並不會顯示在 rendered HTML page

# Including Subviews

以下的 Laravel Blade example code 的意思是?

  • Example:
<div>
@include('shared.errors')

<form>
<!-- Form Contents -->
</form>
</div>
  • Answer: 在當前頁面 include 'shared.errors' page, 所有在 'shared.errors' page 上的 variable 也可被取用

以下的 Laravel Blade example code 的意思是?

  • Example:
@include('view.name', ['status' => 'complete'])
  • Answer: 預設 'view.name' 會使用自己的 variable, 可透過 @include 的 arg2 自定義

以下的 Laravel Blade example code 的意思是?

  • Example:
@includeIf('view.name', ['status' => 'complete'])
  • Answer: 如果 include 一個不存在的 view, Laravel 預設會 throw error, 可加入判斷, 如果存在的話再 include

以下的 Laravel Blade example code 的意思是?

  • Example:
@includeWhen($boolean, 'view.name', ['status' => 'complete'])

@includeUnless($boolean, 'view.name', ['status' => 'complete'])
  • Answer:
<!-- 如果 boolean 為 true, 則 include, 當... 我就執行 include -->
@includeWhen($boolean, 'view.name', ['status' => 'complete'])

<!-- 如果 boolean 為 false, 則 include, 除非... 否則我一律執行 include -->
@includeUnless($boolean, 'view.name', ['status' => 'complete'])

以下的 Laravel Blade example code 的意思是?

  • Example:
@includeFirst(['custom.admin', 'admin'], ['status' => 'complete'])
  • Answer: 將 include array 內存在的第一個 view, 換言之, 若 'custom.admin' 不存在, 則 include 'admin', 並帶入該 view 會使用到的 variable

在 MySQL Blade 中, 需避免使用 DIR, 或 FILE, 為何?

因為會 refer cached, compiled view

# Rendering Views For Collections

以下的 MySQL Blade example code 的意思是?

  • Example:
@each('view.name', $jobs, 'job', 'view.empty')
  • Answer: (1) 'view.name' 表示要 render 的 view (2) $jobs 為一個 array, 將會被 iterated (3) 'job' 表示當次 iteration 的 key/value, 會被 pass 到 'view.name' 中, 可在 'view.name' 中取用 key 以輸出其 value (4) 'view.empty' 表示當 $jobs 是個 empty array 時該 render 的 view

以下的 MySQL Blade example 中, 會繼承 parent 的 variable 嗎?

  • Example:
@each('view.name', $jobs, 'job', 'view.empty')
  • Answer: 不會, 若要使用繼承的 variable, 可使用 @foreach 搭配 @include

# The @once Directive

以下的 Laravel Blade example code 的意思是?

  • Example:
@once
@push('scripts')
<script>
// Your custom JavaScript...
</script>
@endpush
@endonce
  • Answer: Blade 語法, 在 @once 內的語法在當次 render cycle 中只會被讀取一次
  • Answer: Blade 語法, 在 @php directive 內可以直接輸入 PHP code

# Building Layouts

# Layouts Using Components

# Defining The Layout Component

以下的 Laravel Blade example code 的意思是?

  • Example:
<!-- resources/views/components/layout.blade.php -->

<html>
<head>
<title>{{ $title ?? 'Todo Manager' }}
</head>
<body>
<h1>Todos</h1>
<hr/>
{{ $slot }}
</body>
</html>
  • Answer: 定義一個 Blade component 模板, 在其他 page 可以使用 來 render 這個模板定義的元素

# Applying The Layout Component

以下的 Laravel example code 的意思是?

  • Example:
<!-- resources/views/tasks.blade.php -->

<x-layout>
@foreach ($tasks as $task)
{{ $task }}
@endforeach
</x-layout>
  • Answer: 在 task blade page 使用 Layout component, 在 directive 內的 code, 將會被注入到 component 的 $slot variable

# Forms

# CSRF Field

以下的 Laravel Blade example code 的意思是?

  • Example:
<form method="POST" action="/profile">
@csrf

...
</form>
  • Answer: Blade 特有語法, 在該 FORM 中產生 CSRF token field

# Method Field

以下的 Laravel Blade example code 的意思是?

  • Example:
<form action="/foo/bar" method="POST">
@method('PUT')

...
</form>
  • Answer: Blade 特有語法, 因為 HTML Form 並不支援 PUT, PATCH, DELETE, 可使用 @method() 來模擬不支援的 HTTP method

# Validation Errors

以下的 Laravel Blade example code 的意思是?

  • Example:
<!-- /resources/views/post/create.blade.php -->

<label for="title">Post Title</label>

<input id="title" type="text" class="@error('title') is-invalid @enderror">

@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
  • Answer: Blade 特有語法, 如果 error title 存在的話, 則執行 directive 內的動作

以下的 Laravel Blade example code 的意思是?

  • Example:
<!-- /resources/views/auth.blade.php -->

<label for="email">Email address</label>

<input id="email" type="email" class="@error('email', 'login') is-invalid @enderror">

@error('email', 'login')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
  • Answer: Blade 特有語法, @error() 可以指定第二個 args, 為自定義的 message bag name 想像一下如果該 page 有多個 form, 要 submit 到不同的 API, 若有 error 的話肯定會有多個不同的 message bag object, 所以必須給 message bag 自定義 name

# PHP

以下的 Laravel Blade example code 的意思是?

  • Example:
@php
$counter = 1;
@endphp

# Components

以下的 Laravel example command 的意思是?

  • Example:
php artisan make:component Alert
  • Answer: 建立一個 component 名為 Alert

Laravel 中, 當我使用 CLI 建立一個 component, 其 view 及 component 位置為?

view: resources/views/components 資料夾下 component: App\View\Components 資料夾下

以下的 Laravel example command 的意思是?

  • Example:
php artisan make:component Forms/Input
  • Answer: Laravel 預設將 component 置於 resources/views/components 資料夾下, 亦可指定子資料夾, 所以會置於: view: resources/views/components/forms 資料夾下 component: App\View\Components\Forms 資料夾下

# Manually Registering Package Components

以下的 Laravel example code 的意思是?

  • Example:
<?php
use Illuminate\Support\Facades\Blade;

public function boot()
{
Blade::component('package-alert', AlertComponent::class);
}

// 然後在 Blade view page 可以使用
<x-package-alert/>
  • Answer: 如果自己建立一個 package, 並且在裡頭有使用到 Blade components 的話, 需要在 package 的 server provider 的 boot method 當中註冊該 component

以下的 Laravel example code 的意思是?

  • Example:
<?php
use Illuminate\Support\Facades\Blade;

public function boot()
{
Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');
}

// 然後在 Blade page 可以使用
<x-nightshade::calendar />
<x-nightshade::color-picker />
  • Answer: 如果自己建立一個 package, 並且在裡頭有使用到 Blade components 的話, 需要在 package 的 server provider 的 boot method 當中, 註冊 components, 上面的 example 假設在 Nightshade 這個 package 的 Package\Views\Components 位置有 calendar 以及 color-picker components

# Rendering Components

以下的 Laravel Blade example code 的意思是?

  • Example:
<x-alert/>

<x-user-profile/>
  • Answer: 使用 x-alert 以及 x-user-profile components

以下的 Laravel Blade example code 的意思是?

  • Example:
<x-inputs.button/>
  • Answer: 當 component 為 nested, 使用 'dot' 符號 上面 example 使用 App\View\Components\Inputs\Button.php component

# Passing Data To Components

以下的 Laravel Blade example code 的意思是?

  • Example:
<x-alert type="error" :message="$message"/>
  • Answer: 帶入參數到 alert component 當帶入 hard coded string 時, 直接使用 HTML attributes 即可 當帶入 variable, 前線需加上 :

以下的 Laravel example code 的意思是?

  • Example:
<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Alert extends Component
{
public $type;

public $message;

public function __construct($type, $message)
{
$this->type = $type;
$this->message = $message;
}

public function render()
{
return view('components.alert');
}
}

// 在 component view 中
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>

// 在別的 blade 中
<x-alert type="error">
  • Answer: 在 component class 中定義 property, 之後在 component view 中可以使用此 property, 而在引用的 blade 可以 assign 給 type 或 message variable 新的值

# Casting

以下的 Laravel example code 的意思是?

  • Example:
<?php
// 在 component model
public function __construct($alertType)
{
$this->alertType = $alertType;
}

// 在其他 blade page
<x-alert alert-type="danger" />
  • Answer: 在 component model 可定義 property, 需使用 camelCast 而在引用處可帶入該 property, 需使用 kebab-case

# Component Methods

以下的 Laravel example code 的意思是?

  • Example:
<?php
// 在 component model
public function isSelected($option)
{
return $option === $this->selected;
}

// 在 component template
<option {{ $isSelected($value) ? 'selected="selected"' : '' }} value="{{ $value }}">
{{ $label }}
</option>
  • Answer: 可在 component template 使用定義於 component model 的 method

# Accessing Attributes & Slots Within Component Classes

以下的 Laravel Blade component example code 的意思是?

  • Example:
<?php
public function render()
{
return function (array $data) {
// $data['componentName'];
// $data['attributes'];
// $data['slot'];

return '<div>Components content</div>';
};
}
  • Answer: 可以從 render method 中取得 componentName, attributes, slot 的值 return 值為 string, 會覆蓋 component view, 應用待研究

# Additional Dependencies

以下的 Laravel Blade component example code 的意思是?

  • Example:
<?php
use App\Services\AlertCreator

public function __construct(AlertCreator $creator, $type, $message)
{
$this->creator = $creator;
$this->type = $type;
$this->message = $message;
}
  • Answer: 使用 method injection 注入 AlertCreator instance

# Component Attributes

以下的 Laravel example code 的意思是?

  • Example:
// 位於 component layout page
<div {{$attributes}}>
{{$attributes}}
</div>

// 位於其他 view page
@php
$message = 'message';
@endphp

<x-layout type="error" :message="$message" class="mt-4">

</x-layout>
  • Answer: 在 component template page 可以使用 $attributes 實際上 render 該 page 的 attributes, 在 view page 定義的會覆蓋 component view 定義的, 可使用 $attributes->merge() 來使兩者共存

以下的 Laravel example code, 支援嗎?

  • Example:
<x-alert :live="@env('production')"/>
  • Answer: 不支援, component tag 內不支援使用 @ directive

# Default / Merged Attributes

以下的 Laravel Blade example code 的意思是?

  • Example:
// component view page
<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
{{ $message }}
</div>

// 調用 component 的頁面
<x-alert type="error" :message="$message" class="mb-4"/>

// rendered page
<div class="alert alert-error mb-4">
<!-- Contents of the $message variable -->
</div>
  • Answer: 使用 $attribute->merge(), 可以在 component view 定義 default 的 attributes, 並且 render 時又包含引用頁面定義的 attribute, 若不使用 merge(), 引用頁面定義的 attributes 會覆寫 component view 定義的 attributes

以下的 Laravel Blade example code 的意思是?

  • Example:
// component view
<button {{ $attributes->merge(['type' => 'button']) }}>
{{ $slot }}
</button>

// 引用的 page
<x-button type="submit">
Submit
</x-button>

// render 的 page
<button type="submit">
Submit
</button>
  • Answer: 當 $attributes->merge() 的對象不是 class 時, 會被視為 default value, 如果這時在引用的 page 又定義了一次, 那會以引用 page 的為主, 跟 merge class 不同, 兩者並不會共存

以下的 Laravel Blade example code 的意思是?

  • Example:
<div {{ $attributes->merge(['data-controller' => $attributes->prepends('profile-controller')]) }}>
{{ $slot }}
</div>
  • Answer: 當 $attributes->merge() 的對象不是 class 時, 會被視為 default value, 如果這時在引用的 page 又定義了一次, 那會以引用 page 的為主, 跟 merge class 不同, 兩者並不會共存 但可以使用 $attributes->prepends() 使兩者共存, 以上的 example 中, 'data-controller' 的 default value 為 'profile-controller', 然後任何在引用頁面定義的 value 都會被 merge 到此 array 中

# Filtering Attributes

以下的 Laravel Blade example code 的意思是?

  • Example:
{{ $attributes->filter(fn ($value, $key) => $key == 'foo') }}
  • Answer: 在 Blade component view 中使用 $attributes->filter(), 唯有 closure return true 的 attribute 才會被保留

以下的 Laravel Blade example code 的意思是?

  • Example:
{{ $attributes->whereStartsWith('wire:model') }}
  • Answer: 取得 $attributes 中, key 為 'wire:model' 開頭的 attributes

以下的 Laravel Blade example code 的意思是?

  • Example:
{{ $attributes->whereStartsWith('wire:model')->first() }}
  • Answer: 取得 whereStartsWith() 篩選後的第一筆 attribute

# Slots

以下的 Laravel example code 的意思是?

  • Example:
// component view page
<!-- /resources/views/components/alert.blade.php -->

<span class="alert-title">{{ $title }}</span>

<div class="alert alert-danger">
{{ $slot }}
</div>

// 引用頁面
<x-alert>
<x-slot name="title">
Server Error
</x-slot>

<strong>Whoops!</strong> Something went wrong!
</x-alert>
  • Answer: 在 component view page 可定義 $slot 位置, 當引用該 component 時, 在該 component tag 內的內容都會 render 到 component view page 中 $slot 的位置, 如果想要在 component view page 定義多個 $slot 位置的話, 如上 example 可直接定義 variable, 在引用的 page 使用 <x-slot name="yourSlot"

# Scoped Slots

以下的 Laravel Blade example code 的意思是?

  • Example:
<x-alert>
<x-slot name="title">
{{ $component->formatAlert('Server Error') }}
</x-slot>

<strong>Whoops!</strong> Something went wrong!
</x-alert>
  • Answer: 可在 Blade component class 中定義 method, 在 slot 中使用 $component 調用定義好的 method

# Inline Component Views

以下位於 Component class 的 Laravel example code 的意思是?

  • Example:
<?php
public function render()
{
return <<<'blade'
<div class="alert alert-danger">
{{ $slot }}
</div>
blade;
}
  • Answer: 當 component 的範圍比較小, 可能不太需要同時用到 component class 以及 component view page, 這時可以直接在 component class 的 render() return markup

# Generating Inline View Components

以下的 Laravel example command 的意思是?

  • Example:
php artisan make:component Alert --inline
  • Answer: 當 component 的範圍比較小, 可能不太需要同時用到 component class 以及 component view page, 這時可以直接在 component class 的 render() return markup 以上 command 可以直接建立一個 return inline view 的 component

# Anonymous Components

Laravel Blade 中, 何謂 Anonymous Component?

直接在 resources/views/components/ 資料夾底下定義一個 Blade view, 而不需建立 Component class

Laravel Blade 中, component view 可以沒有 component class 而單獨存在嗎?

可以, 又稱為 Anonymous component

# Data Properties / Attributes

以下的 Laravel Blade example code 的意思是?

  • Example:
// 在 component view page
<!-- /resources/views/components/alert.blade.php -->

@props(['type' => 'info', 'message'])

<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
{{ $message }}
</div>

// 在引用 page
<x-alert type="error" :message="$message" class="mb-4"/>
  • Answer: 當使用 Anonymous Component 時, 因為沒有 associated class, 所以使用 @props() 直接在 component view page 定義 property, 效果同定義在 associated class

# Dynamic Components

以下的 Laravel Blade example code 的意思是?

  • Example:
<x-dynamic-component :component="$componentName" class="mt-4" />
  • Answer: 有時你可能需要渲染一個 component, 但只有在 runtime 的時候才知道要渲染哪一個 component, 這時候就可以使用 Dynamic Component 從 :component 帶入指定的 component

# Manually Registering Components

以下的 Laravel Blade example code 的意思是?

  • Example:
<?php
use Illuminate\Support\Facades\Blade;
use VendorPackage\View\Components\AlertComponent;

public function boot()
{
Blade::component('package-alert', AlertComponent::class);
}
  • Answer: Laravel 預設會到 resources/views/components 以及 app\Views\Components 資料夾內尋找並註冊 component, 但如果你在 build 一個 package, 又或者你將 component 放在其他位置的話, 可以在 package service provider 內的 boot() 註冊 components

# Autoloading Package Components

以下的 Laravel Blade example code 的意思是?

  • Example:
<?php
// 在 package service provider 中
public function boot()
{
Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');
}
// 在引用的 page 中
<x-nightshade::calendar />
<x-nightshade::color-picker />
  • Answer: 在 package service provider boot() 中, 註冊一個名為 'nightshade' 的 namespace Laravel 預設會到 resources/views/components 以及 app\Views\Components 資料夾內尋找並註冊 component, 但如果你在 build 一個 package, 又或者你將 component 放在其他位置的話, 可以在 package service provider 內的 boot() 註冊。

# Stacks

以下的 Laravel Blade example code 的意思是?

  • Example:
<?php
@push('scripts')
<script src="/example.js"></script>
@endpush
  • Answer: 將 directive 中的 script push 到名為 scripts 的 stack

以下的 Laravel Blade example code 的意思是?

  • Example:
<?php
<head>
<!-- Head Contents -->

@stack('scripts')
</head>
  • Answer: 將 stack scripts 裡面的內容 pop 出來

以下的 Laravel Blade example code 的意思是?

  • Example:
@push('scripts')
This will be second...
@endpush

// Later...

@prepend('scripts')
This will be first...
@endprepend
  • Answer: 當使用 @push, script 會依照順序執行, 越先 push 的越先執行, 但可以使用 @prepend 改變順序, 越後面 @prepend 的會越先執行

# Service Injection

以下的 Laravel example code 的意思是?

  • Example:
<?php
@inject('metrics', 'App\Services\MetricsService')

<div>
Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>
  • Answer: 從 Laravel service container 取得 service arg1 要將此 service assign to 的 variable, arg 為 Service 的位置

# Extending Blade

以下的 Laravel Blade example code 的意思是?

  • Example:
<?php

namespace App\Providers;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
public function register()
{
//
}

public function boot()
{
Blade::directive('datetime', function ($expression) {
return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
});
}
}
  • Answer: 在 AppServiceProvider 的 boot() 中, 可以使用 Blade 的 directive() 來註冊客製化的 Blade directive 定義一個 Blade directive 名為 datetime, 邏輯定義於 closure 內

Laravel 中, 如果我更新了 Blade view, 需要清除 cache 嗎?

如果有跑 php artisan view:cache 的話, 要執行 php artisan view:clear 清除

# Custom If Statements

以下的 Laravel example code 的意思是?

  • Example:
<?php
// 位於 AppServiceProvider
public function boot()
{
Blade::if('disk', function ($value) {
return config('filesystems.default') === $value;
});
}

// 引用 page
@disk('local')

@elsedisk('s3')

@else

@enddisk

@unlessdisk('local')

@enddisk
  • Answer:
<?php
// 定義一個客製化的 Blade If Statement, 邏輯定義於 closure 內
public function boot()
{
Blade::if('disk', function ($value) {
return config('filesystems.default') === $value;
});
}

// 位於引用 page
@disk('local')
<!-- The application is using the local disk... -->
@elsedisk('s3')
<!-- The application is using the s3 disk... -->
@else
<!-- The application is using some other disk... -->
@enddisk

@unlessdisk('local')
<!-- The application is not using the local disk... -->
@enddisk

--

--

Ray Lee | 李宗叡
Learn or Die

It's Ray. I do both backend and frontend, but more focus on backend. I like coding, and would like to see the whole picture of a product.