+2

Sử dụng Blade trong Laravel 5

Blade rất đơn giản nhưng lại là một templating engine đầy mạnh mẽ. Không giống như những PHP templating engine khác, Blade không giới hạn chúng ta sử dụng code PHP trong views. Tất cả các file blade đều được dịch thành file code PHP và cache cho đến khi file Blade bị thay đổi, điều này có nghĩa Blade tự làm tất cả những điều cần thiết để chạy cho views của bạn. Tất cả các file views dùng blade đều được quy định có đuôi dạng .blade.php và nằm trong thư mục resources/views

Templating Engine (TE)

Để xuất dữ liệu từ PHP ra views chúng ta cần:

<div class="article">
     <h1><?php echo $article->title; ?></h1>
     <p><?php echo $article->content; ?></p>
</div>

Mọi thứ sẽ tốt đẹp nếu chúng ta chỉ dừng lại ở mức độ như trên. Tuy nhiên, trong ứng dụng của chúng ta đổi khi file views không chỉ dừng lại ở đây mà chúng ta cần phải xử lý nhiều hơn với CSS và JS hay HTML. Lúc đó thì code của chúng ta sẽ trở thành như sau:

<div class="article col-lg-3 col-md-4 col-sm-6 col-xm-1">
    <h1 class="article-title hight-light-link"><a href="<?php echo $article->getUrl() ?>"><?php echo $article->title; ?></a></h1>
    <p><?php echo $article->content; ?></p>
</div>

Nhìn ví dụ bên trên chúng ta đã thấy khóc khăn lắm rồi chưa kể đến việc khi chúng ta cần dùng foreach hay là if else. Đó là lý do chúng ta nên dùng và làm việc thường xuyên với TE, TE giúp chúng ta tách biệt hẳn các syntax của PHP ra khỏi HTML, nhằm cho file template trở nên đơn giản, dễ đọc cũng như chỉnh sửa nâng cấp.

Tạo file template đầu tiên

Bây giờ chúng ta tạo file blade đầu tiên. Lưu ý là đuổi file luôn luôn kết thúc bằng .blade.php

<!-- resources/views/index.blade.php -->
<div class="article">
    <h1>Blade Trong Laravel</h1>
    <p><?php echo $name ?></p>
</div>

Khi chạy lần đầu, blade sẽ dịch trang này sang PHP. Hãy tạo 1 routes để chạy file chúng ta vừa tạo ra

Route::get('/index', function ()    {
    return view('index', ['name' => 'CanhNV']);
});

Chúng ta chỉ cần gọi index mà không cần phải gọi rõ ràng là index.blade.php

Hiển thị dữ liệu trong Blade

Để hiện thị dữ liệu trong blade chúng ta dùng cặp dấu {{ và }} bọc quanh biến dữ liệu. Tức là thay vì dùng <?php echo $a ?> thì chúng ta chỉ cần sử dụng {{ $a }}.

<div class="article">
    <h1>Blade Trong Laravel</h1>
    <p>{{ $name }}</p>
</div>

Tiện lợi của dấu {{ }} là bạn không cần strip_tags() hay htmlentities() để lọc text xuất ra bởi vì nó đã thực hiện bao gói dữ liệu xuất ra cho bạn. Tương tự để hiển thị dữ liệu của bảng thì chúng ta cũng chỉ cần gọi:

<p>{{ foo('name') }}</p>
<p>{{ bar['name'] }}</p>
<p>{{ $object->name }}</p>

**Hiển thị dữ liệu thô **

Để có thể hiển thị dữ liệu dạng raw text, nghĩa là có thể xuất HTML, JS… thì phải dùng cặp dấu {!! và !!} . Nhưng cần chú ý sử dụng trong các trường hợp khác nhau. Ví dụ, không nên hiển thị comment từ người duyệt web bằng cặp dấu này, hacker có thể lợi dụng để thực hiện chèn mã độc lên website.

Hello, {!! $name !!}.

**Dùng chung Blade template với các Javascript Framework **

Rất nhiều Js framework cũng sử dụng {{ và }} để hiển thị nội dung lên trình duyệt, do đó khi code có khả năng bị “xung đột” với Blade. Bạn có thể dùng @{{ và }} để báo cho Blade biết đừng đụng vào, vị trí này cho Js, ví dụ:

<h1>Laravel</h1>

Hello, @{{ name }}.

Trong ví dụ này, khi dịch ra PHP, Blade sẽ xóa @ đi, và để nguyên nội dung {{ name }} lại, cho phép bạn xuất nội dung qua Js Framework.

Echo dữ liệu nếu tồn tại

Đôi khi chúng ta cần echo một biến, nhưng lại không chắc chắn biến đó đã được khởi tạo hay gán dữ liệu chưa, chúng ta có thể biểu diễn biểu lệnh xuất dữ liệu trong một dòng PHP như sau:

{{ isset($name) ? $name : 'Default' }}

Tuy nhiên blade cũng cấp cho ta cách ngắn gọn hơn nữa

{{ $name or 'Default' }}

Cấu trúc điều khiển

Cũng giống như việc hiển thị dữ liệu bằng PHP thuần, chúng ta luôn cần dùng các cấu trúc điều khiển để kiểm tra, phù hợp với điều kiện nào thì hiển thị cái nào ra. Blade cung cấp các lối viết tắt ngắn gọn, súc tích mà vẫn giữ được sự quen thuộc với code PHP.

Câu lệnh If

Với câu lệnh if, bạn có thể dùng các chỉ thị trong template như @if , @else , @elseif , @endif . Các từ khóa chỉ thị này có ý nghĩa tương tự với lệnh dùng trong PHP.

@if (count($records) === 1)
    I have a record
@elseif (count($records) > 1)
    I have many record
@else
    I'm empty!
@endif

Vòng lặp

Blade cung cấp các từ khóa chỉ thị tương ứng với các lệnh lặp trong PHP:

@for ($i = 0; $i < 10; $i++)
    Giá trị hiện tại là {{ $i }}
@endfor

@foreach ($users as $user)
    <p>Đây là user có mã {{ $user->id }}</p>
@endforeach

@while (true)
    <p>Tôi đang lặp mãi mãi :(</p>
@endwhile

Nếu bạn có như cầu hiển thị nội dung thay thế cho @foreach , khi duyệt gặp một mảng rỗng, null, Blade hỗ trợ cú pháp ngắn gọn sau:

@forelse ($users as $user)
    <li>{{ $user->name }}</li>
@empty
    <p>Không có user nào!</p>
@endforelse

Trong ví dụ trên, bạn thấy @forelse không có trong PHP, vậy nó là gì? Thực ra nó giống với @foreach . Blade sẽ thay chúng ta kiểm tra biến $users, nếu có dữ liệu sẽ thực hiện xuất qua vòng lặp foreach, nếu không có dữ liệu, sẽ chuyển qua xuất dữ liệu ở giữa @empty@endforelse.

Layout và kế thừa temaplate

Ở trên, chúng ta đã học được cách tạo template và sử dụng chúng để xuất dữ liệu một cách đơn giản và sạch sẽ. Tuy nhiên, với một trang web có rất nhiều màn hình khác nhau, chúng ta không thể liên tục tạo mới file template cho từng trang trong khi chúng chỉ khác về nội dung chứ bố cục tổng thể thì không thay đổi. Chúng ta không nên và cũng không thể copy lặp đi lặp lại cùng một đoạn code (DRY – Don’t Repeat Yourself), việc đó sẽ làm chúng ta rất mất thời gian để tạo ra cũng như bảo trì, nâng cấp các file template. May thay, Laravel 5 cung cấp cho chúng ta giải pháp đơn giản để tổ chức hệ thống file template theo layout gọn gàng, có cấu trúc, giúp giảm thiểu tối đa thời gian triển khai giao diện.

1.png

Định nghĩa một layout

Hai lợi ích chính của việc sử dụng Blade là kế thừa template và chia phần template thành section. Để bắt đầu, hãy xem qua một ví dụ đơn giản. Đầu tiên, chúng ta xem xét trang layout chính. Hầu hết các ứng dụng web đều duy trì layout cơ bản giống nhau trên nhiều trang, điều đó rất tiện cho chúng ta để định nghĩa layout này như một view Blade đã học ở trên:

<!-- Lưu tại resources/views/layouts/master.blade.php -->

<html>
    <head>
        <title>App Name - @yield('title')</title>
    </head>
    <body>
        @section('sidebar')
            <h3>Đây là sidebar chính.</h3>
        @show

        <div class="container">
            @yield('content')
        </div>
    </body>
</html>

Như bạn thấy, file này chứa phần lớn code HTML. Tuy nhiên, chú ý vào hai từ khóa chỉ thị @section@yield . Chỉ thị @section định nghĩa một mảnh/phần/đoạn nội dung, trong khi chỉ thị @yield dùng để hiển thị nội dung của một phần nhất định.

Bây giờ chúng ta đã có một layout được định nghĩa cho ứng dụng của mình. Hãy tiếp tục định nghĩa các trang con kế thừa từ layout chính này.

Sự khác nhau giữa @yield@section

Rõ ràng chúng ta đều thấy child page dùng hai từ khóa này để chỉ thị việc chèn nội dung vào master layout. Vậy chúng khác nhau như thế nào? Khi nào thì dùng cái nào? Theo tôi sự khác nhau nằm ở chính cái tên của chúng, cần hiểu rõ để biết khi nào sử dụng:

@yield: bản thân từ này đồng nghĩa với từ output, do đó dĩ nhiên nhiệm vụ của nó là xuất dữ liệu. Vậy ta chỉ nên dùng cho việc xuất những dữ liệu nhỏ. @section : có nghĩa là phần, đoạn hay mảnh. Rõ ràng từ khóa này nhắm tới việc phân nhỏ layout ra thành từng đoạn nhỏ để các trang con ghi nội dung vào các vị trí đánh dấu này! Về mặt kỹ thuật, thật sự khi sử dụng @section , các trang con sẽ có thể ghi đè, hoặc ghi nối thêm nội dung bằng từ khóa . Khi có từ khóa này, Blade sẽ lấy nội dung trong section của layout “chắp vào” trước nội dung của @section ở trang con. Còn khi sử dụng @yield , nội dung ở trang con sẽ luôn luôn ghi đè vào vị trí đánh dấu ở layout, mà không thể nối thêm dữ liệu ở layout vào như khi dùng @section .

Trên đây là một vài chia sẻ của tôi, Chúc mọi người thành công. ^^


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.