<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Laravel Blade &#8211; Larry的午茶時光</title>
	<atom:link href="https://blog.yuyansoftware.com.tw/tag/laravel-blade/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.yuyansoftware.com.tw</link>
	<description></description>
	<lastBuildDate>Sun, 23 Jul 2023 03:08:52 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://blog.yuyansoftware.com.tw/wp-content/uploads/2022/10/favicon-45x45.png</url>
	<title>Laravel Blade &#8211; Larry的午茶時光</title>
	<link>https://blog.yuyansoftware.com.tw</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Laravel Blade Templates：Components, Slots, and Building Layouts</title>
		<link>https://blog.yuyansoftware.com.tw/2021/05/laravel-blade-template-component-slot-layout/</link>
		
		<dc:creator><![CDATA[Larry]]></dc:creator>
		<pubDate>Mon, 17 May 2021 14:15:50 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Laravel Blade]]></category>
		<category><![CDATA[Link7]]></category>
		<guid isPermaLink="false">https://blog.yuyansoftware.com.tw/?p=7775</guid>

					<description><![CDATA[Component &#038; Slot 的概念從 Laravel 5.4 開始就有了，一直演進到目前是 Laravel 8。寫法上觀念上都有很大的改變，也看得出來 Laravel 前端 template 是越來越往 component based 的框架在走。]]></description>
										<content:encoded><![CDATA[
<p><a rel="noreferrer noopener" href="https://laravel.com/docs/8.x/blade" target="_blank">https://laravel.com/docs/8.x/blade</a></p>



<p>******* 以下文章是基於 Laravel 8 *******</p>



<p>Component &amp; Slot 的概念從 Laravel 5.4 開始就有了，一直演進到目前是 Laravel 8。寫法上觀念上都有很大的改變，也看得出來 Laravel 前端 template 是越來越往 component based 的框架在走。前幾年開始到目前 (2021年5月)，似乎 component based 的前端框架還是主流，這點可以再做觀察。</p>



<p>本篇文章主要是講 Laravel 8 的 Component &amp; Slot。如果基礎 Laravel Blade Templates 還不熟的讀者，可以參考我之前的文章：<a rel="noreferrer noopener" href="https://blog.yuyansoftware.com.tw/2016/09/laravel-blade-template-basics/" target="_blank">Laravel Blade Templates：The Basics</a></p>



<p>首先，Component 分為兩種：class based component 和 anonymous component。簡單來說，class based component 是由一支 Class 檔案搭配一支 view template 檔案。而 anonymous component 則是簡單只有一支 view template 檔案。</p>



<h4 class="wp-block-heading">Class based component</h4>



<p>如上方 Laravel 8 官方文件，要建立一個 class based component，可以下這個指令</p>



<pre class="wp-block-code"><code>php artisan make:component Alert</code></pre>



<p>這個指令會在</p>



<ul class="wp-block-list">
<li>App\View\Components 新增一支 Class 檔案。</li>



<li>resources/views/components 新增一支 view template 檔案。</li>
</ul>



<p>建立 class based component 時也可以建立檔案結構 (比較好管理) </p>



<pre class="wp-block-code"><code>php artisan make:component Forms/Input</code></pre>



<p>這個指令會在</p>



<ul class="wp-block-list">
<li>App\View\Components\Forms 新增一支 Class 檔案。</li>



<li>resources/views/components/forms 新增一支 view template 檔案。</li>
</ul>



<p>調用端如何使用？用 x- 開頭接 component class name，以小寫 dash (-) 分隔的方式</p>



<pre class="wp-block-code"><code>&lt;x-alert/&gt;

&lt;x-user-profile/&gt;</code></pre>



<p>如果 component 是有檔案結構，如上例 Forms/Input，除了小寫 dash (-) 分隔的規則，檔案上下層以 dot (.) 分隔</p>



<pre class="wp-block-code"><code>&lt;x-forms.input/&gt;</code></pre>



<div style="height:1px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Component 如何接收調用端的資料</h4>



<p>component class 用 constructor 接收調用端的資料 (下例並非完整，僅用於勾勒出 component 如何接收資料，完整 class 請參考官方文件)</p>



<pre class="wp-block-code"><code>class Alert extends Component
{
    ...

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

    ...
}</code></pre>



<p>這樣調用端就可以將 type, message 傳進 component。<br>注意傳 php 變數的屬性前要加 colon (:)</p>



<pre class="wp-block-code"><code>&lt;x-alert type="error" :message="$message"/&gt;</code></pre>



<p>再看一下上方 class Alert。component class 的 view 可以直接使用 component class 的 public 變數，不用特別傳到 view 裡 (跟一般 Laravel controller 不同)。以上方 class Alert 來說，$type, $message 應該是 public 變數，class Alert 的 view 可以直接使用。</p>



<div style="height:1px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Component Attributes</h4>



<p>所有不在 component constructor 接收的變數，都會自動存到 component 的 &#8220;attribute bag&#8221;，其實就是 component 預設的 $attributes 變數。所以如果沒有特別設定 component constructor，想直接顯示調用端所下的屬性，component view 可以這樣寫</p>



<pre class="wp-block-code"><code>&lt;div {{ $attributes }}&gt;
    &lt;!-- Component content --&gt;
&lt;/div&gt;</code></pre>



<p>很多時候，component view 本身可以設定 css class，同時也開放調用端下 css，可以使用 $attributes-&gt;merge</p>



<pre class="wp-block-code"><code>&lt;div {{ $attributes-&gt;merge(&#91;'class' =&gt; 'alert alert-'.$type]) }}&gt;
    {{ $message }}
&lt;/div&gt;</code></pre>



<p>還記得 class Alert，$type 變數是 constructor 接收。如果調用端這樣寫</p>



<pre class="wp-block-code"><code>&lt;x-alert type="error" :message="$message" class="mb-4"/&gt;</code></pre>



<p>上面 $attributes-&gt;merge 就會把 class=&#8221;alert alert-error&#8221; 跟 &#8220;mb-4&#8221; 合併在一起，最後產出的 html 是</p>



<pre class="wp-block-code"><code>&lt;div class="alert alert-error mb-4"&gt;
    &lt;!-- Contents of the $message variable --&gt;
&lt;/div&gt;</code></pre>



<p>html 屬性不是只有 css class，其他屬性不見得能下多個值。如果 $attributes-&gt;merge 這樣寫</p>



<pre class="wp-block-code"><code>&lt;button {{ $attributes-&gt;merge(&#91;'type' =&gt; 'button']) }}&gt;
    {{ $slot }}
&lt;/button&gt;</code></pre>



<p>當調用端 x-button 沒有指定 type，最後產出的 html button type=&#8221;button&#8221;。<br>當調用端 x-button 有指定 type，最後產出的 html button type=調用端指定的值。<br>所以非 css class 的屬性，$attributes-&gt;merge 的行為是「覆寫」，而非「合併」</p>



<div style="height:1px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Slot</h4>



<p>除了上段討論的 $attributes 變數，component 也預設了 $slot 變數。如果 component view 是</p>



<pre class="wp-block-code"><code>&lt;span class="alert-title"&gt;{{ $title }}&lt;/span&gt;

&lt;div class="alert alert-danger"&gt;
    {{ $slot }}
&lt;/div&gt;</code></pre>



<p>調用端 x-alert 中間夾的內容，會自動填到 $slot 變數中。但 component view 還有一個 $title，此時調用端就要新增一個 &lt;x-slot name=&#8221;title&#8221;&gt;，中間夾的內容會填入 $title (這個地方 title 也是一個 slot)</p>



<pre class="wp-block-code"><code>&lt;x-alert&gt;
    &lt;x-slot name="title"&gt;
        Server Error
    &lt;/x-slot&gt;

    &lt;strong&gt;Whoops!&lt;/strong&gt; Something went wrong!
&lt;/x-alert&gt;</code></pre>



<p>slot 可以看成是一個比較快，不需要 component class，又可以將資料傳到 component 的機制。</p>



<div style="height:1px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Anonymous Component</h4>



<p>anonymous component 不需要 component class，在 resources/views/components 新增一支 view template 檔案，調用端就可使用了 &lt;x-your-component/&gt;</p>



<p>resources/views/components 可以有檔案結構，調用端檔案上下層以 dot (.) 分隔，例如 &lt;x-forms.input/&gt;，這些都跟 class based component 相同。</p>



<p>因為沒有 component class，還是要有一個機制可以傳入指定變數。anonymous component 使用 @props directive，其中並可指定變數的預設值，例如下面 type 的預設值是 &#8220;info&#8221;</p>



<pre class="wp-block-code"><code>@props(&#91;'type' =&gt; 'info', 'message'])

&lt;div {{ $attributes-&gt;merge(&#91;'class' =&gt; 'alert alert-'.$type]) }}&gt;
    {{ $message }}
&lt;/div&gt;</code></pre>



<div style="height:1px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">使用 Component 做版面 layout</h4>



<p>Laravel 演進到現在 (Laravel 8)，其實是鼓勵開發者用 component 做版面 layout，而不是用傳統的 @extends, @yield, @section 等。</p>



<p>用 component 做版面 layout，主要是上面提到的 slot 機制。例如 resources/views/components/layout.blade.php</p>



<pre class="wp-block-code"><code>&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;{{ $title ?? 'Todo Manager' }}&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;h1&gt;Todos&lt;/h1&gt;
        &lt;hr/&gt;
        {{ $slot }}
    &lt;/body&gt;
&lt;/html&gt;</code></pre>



<p>child view：resources/views/tasks.blade.php。其中 &lt;x-layout&gt; 中整段會填到 $slot，也注意到 title slot 的寫法，可以傳入 $title 變數。</p>



<pre class="wp-block-code"><code>&lt;x-layout&gt;
    &lt;x-slot name="title"&gt;
        Custom Title
    &lt;/x-slot&gt;

    @foreach ($tasks as $task)
        {{ $task }}
    @endforeach
&lt;/x-layout&gt;</code></pre>



<p>相較於傳統的 @extends, @yield, @section 佈局方式</p>



<ul class="wp-block-list">
<li>child view 的角色是 component 的調用端</li>



<li>master view 的角色是 component 本身</li>
</ul>



<p>如果對 design pattern 有了解的讀者，傳統的佈局方式跟 component based 的佈局方式，是類似的 design pattern，所以使用上邏輯是很像的。</p>



<p>也可以參考我 <a rel="noreferrer noopener" href="https://blog.yuyansoftware.com.tw/category/software-engineering-philosophy/design-pattern/" target="_blank">Design Pattern 系列的文章</a></p>



<div style="height:1px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">結論</h4>



<p>本文主要是希望能勾勒出 Laravel 8 component 的使用，與使用 component 做版面 layout 的方式。沒有談太多細節、或變化型的使用，很多細節的部分應該是由開發者自行斟酌使用。Laravel 前端目前看起來是往 component based 的方向在走，習慣於 @extends, @yield, @section 佈局方式的開發者，可以考慮使用 component。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Laravel Blade Templates：The Basics</title>
		<link>https://blog.yuyansoftware.com.tw/2016/09/laravel-blade-template-basics/</link>
		
		<dc:creator><![CDATA[Larry]]></dc:creator>
		<pubDate>Fri, 16 Sep 2016 04:38:00 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Laravel Blade]]></category>
		<guid isPermaLink="false">http://test234.yuyansoftware.com.tw/2016/09/16/laravel-5-blade-template-engine/</guid>

					<description><![CDATA[Laravel Blade 是 Laravel 獨家的後端 template 引擎。它是 native php 的包裝，可以幫助開發者做前端檔案的切分管理，並提供簡潔易懂的 template 語法。]]></description>
										<content:encoded><![CDATA[
<p><a rel="noreferrer noopener" aria-label=" (在新分頁中開啟)" href="https://laravel.com/docs/5.3/blade" target="_blank">https://laravel.com/docs/5.3/blade</a></p>



<p>******* 以下文章是基於 Laravel 5.3 *******</p>



<p>Laravel Blade 是 Laravel 獨家的 template 引擎。首先我們要知道兩個名詞：master view 與 child view. 可以把每頁相同的部分，例如 &lt;head&gt; 中的部分，放到 master view. 而把每頁實際內容放到 child view. 所以就一般情況而言，多個 child view 會共用一個 master view.</p>



<p>官方文件提供的 master view 範例</p>



<pre class="wp-block-code"><code>&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;App Name - @yield('title')&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
        @section('sidebar')
            This is the master sidebar.
        @show

        &lt;div class="container"&gt;
            @yield('content')
        &lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Extending A Layout</h4>



<p>對應的 child view 範例</p>



<pre class="wp-block-code"><code>@extends('layouts.app')

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

@section('sidebar')
    @parent

    &lt;p&gt;This is appended to the master sidebar.&lt;/p&gt;
@endsection

@section('content')
    &lt;p&gt;This is my body content.&lt;/p&gt;
@endsection</code></pre>



<p>要使用 master view, child view 的第一行要填入 @extend. 以上面範例來說，master view 是放在 &#8220;resources/views/layouts/app.blade.php&#8221;, 所以 @extend 參數填的是 layouts.app.</p>



<p>第二，master view 的 @yield, child view 用 @section 來接。child view 可以用 @section @endsection 塞一個區塊到 master view，或是 @section 參數直接填字串。child view 也可以不實作 @section，在 master view 裡就是留空。</p>



<p>第三，master view 的 @section @show, child view 用 @section @parent 來接。child view 的 @parent 可以「接著 master view 的內容寫」，而不是整段替換。child view 也可以只用 @section, 不寫 @parent, 這樣就是整段替換，與上面第二點同。child view 也可以不實作 @section，在 master view 裡就是顯示 @section @show 中間的內容。其實大部分使用時機，上面第二點都可以取代這個 @section @show.</p>



<p>要注意，概念上是 master view 管版面架構，child view 管文字、表單內容。child view 的 @section 內容會填回 master view, 而不是在 child view @section 的程式碼位置顯示。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Displaying Data</h4>



<p>Laravel Blade 用兩個大括號來顯示 PHP 變數 {{ $your_variable }}. 而且他會自動通過 PHP htmlentities function, 防止 XSS 攻擊。例如有人留言 &#8220;&lt;script&gt;some malicious code&lt;/script&gt;&#8221;, PHP htmlentities 會把 &lt; &gt; 等符號轉成 html symbol, 呈現給用戶時仍然是 &#8220;&lt;script&gt;some malicious code&lt;/script&gt;&#8221;. 如果沒用 htmlentities 的話，那一段 script 就會跑起來了。</p>



<p>{!! !!} 「不會」通過 PHP htmlentities function. 使用時要特別小心，一般情況「不應該」使用 {!! !!}. 可能極少數情況，想用 Blade template 執行 html code, 例如 &lt;br&gt; 是換行，而 {{  }} 只是把 &#8220;&lt;br&gt;&#8221; 當字串顯示。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Blade &amp; JavaScript Frameworks</h4>



<p>Blade 使用 {{  }} 填入變數，這跟很多 JavaScript Framework 衝到，例如 Angular, Vue. 可以改用 @{{  }}，這樣 {{  }} 就會 serve 到前端，由前端框架來 templating。如果有一大段 @{{  }}，可以使用：</p>



<pre class="wp-block-code"><code>@verbatim
    Hello, {{ name1 }}, {{ name2 }}
    ...
@endverbatim</code></pre>



<p>這樣其中所有 {{  }} 都會交由前端 templating.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Control Structures</h4>



<p>Loop, If 等有 PHP 背景的讀者應該都熟悉，這邊不再贅述。提一下 @php @endphp 可以塞一段 native php 到 blade 檔案。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Including Sub-Views</h4>



<p>master view 可以使用 @include 來把部分 html 切分出去，例如：</p>



<pre class="wp-block-code"><code>@include('view.name', &#91;'some' =&gt; 'data'])</code></pre>



<p>&#8216;view.name&#8217; 是檔案結構路徑，跟 @extends 參數類似，&#39;view.name&#8217; 是指 /resources/views/view/name.blade.php. 也可以傳參數進去 [&#8216;some&#8217; =&gt; &#8216;data&#8217;]</p>



<p>被 include 的檔案 「不需要」extends master view. 如果 master view 有 include 而被 include 的檔案不存在的話，會出現 error. 可以使用 includeIf 如果不確定被 include 的檔案存不存在。</p>



<pre class="wp-block-code"><code>@includeIf('view.name', &#91;'some' =&gt; 'data'])</code></pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Stacks</h4>



<p>@stack and @push. 官方文件說</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>&#8220;This can be particularly useful for specifying any JavaScript libraries required by your child views&#8221;</p></blockquote>



<p>因為 @yield 和 @section 可以完全達成在 child view 中指定該 child view 要用的 JS library，其實不需要 @stack and @push. @stack and @push 唯一獨特的點在於，可以多次 @push, 但就 larry 的經驗來說，使用時機很少。</p>



<p>以上就是 Laravel Blade 主要的架構與語法。其他 Blade 的 service injection, custom directives 等，使用時機很少，讀者可以自行斟酌讀或不讀。</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
