[Bài đọc] Sử dụng blade template

2. Cơ bản về Laravel Framework

Giới thiệu

Blade rất đơn giản nhưng lại là một templating engine đầy mạnh mẽ của Laravel. Không giống những templating engine của PHP, Blade không giới hạn sử dụng mã PHP thuần trong view. Thực tế, tất cả các Blade view được biên dịch thành mã PHP thuần và lưu lại (giấu kín – cached) cho tới khi bị thay đổi, nghĩa là Blade không làm tăng thêm chi phí cho ứng dụng của bạn. Các file view dùng cho blade có phần tên đuôi là .blade.php và được lưu trong thư mục resources/views

Kế thừa Template 

Tạo một layout

Hai lợi ích chính của việc sử dụng Blade là kế thừa template và sections. Để bắt đầu, hãy cùng xem một ví dụ đơn giản dưới đây. Đầu tiên, chúng ta sẽ cùng xem bố cục trang “master”. Vì hầu hết các ứng dụng web đều có một mẫu bố cục chung giữa các trang với nhau, nên sẽ rất thuận tiện nếu tạo bố cục (layout) này thành một Blade view.

<!-- 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> 

Như bạn thấy, file này chứa các mã HTML. Tuy nhiên, hãy chú ý tới lệnh @section và @yield. Lệnh @section tạo ra một khu vực hiển thị dữ liệu trong ứng dụng, trong khi đó @yield được sử dụng để hiển thị nội dung của dữ liệu đã được đưa ra.

Bây giờ chúng ta đã định nghĩa một layout cho ứng dụng, hãy tạo một trang con kế thừa từ layout vừa tạo.

Sử dụng một layout

Khi tạo một view con, sử dụng @extends để chỉ ra bố cục trang con này sẽ thực hiện kế thừa từ đâu. Các view được kế thừa từ Blade layout có thể đưa nội dung vào trong mục @section. Nhớ rằng, như ở ví dụ trên, nội dung của những section này được hiển thị khi sử dụng @yield: 

<!-- 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

Trong ví dụ này, phần sidebar sử dụng @parent để thêm nội dụng vào trong sidebar (thay vì ghi đè toàn bộ). @parent sẽ được thay thế bởi nội dung của layout khi view được render.

Blade view có thể được trả về từ route bằng cách sử dụng phương thức view như sau:

Route::get('blade', function () {
    return view('child');
});

Components và Slots

Component và slot cung cấp lợi ích tương tự như section và layout; tuy nhiên, cách làm việc của chúng có thể đơn giản hơn. Trước tiên, hãy tưởng tượng một thành phần alert có thể sử dụng lại xuyên suốt ứng dụng như sau:

<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">
    {{ $slot }}
</div> 

Biến {{$slot}} chứa nội dung mà bạn muốn đưa vào trong component. Bây giờ, để xây dựng cấu trúc của component này, chúng ta có thể sử dụng @component directive:

@component('alert')
    <strong>Whoops!</strong> Something went wrong!
@endcomponent

Đôi khi sẽ rất hữu ích khi xác định nhiều slot cho một component. Hãy sửa component alert để cho phép thêm vào một title. Việc đặt tên cho các slot sao cho có ý nghĩa và tên nói lên chức năng của biến đó làm gì.

<!-- /resources/views/alert.blade.php -->

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

    {{ $slot }}
</div>

Bây giờ, chúng ta có thể gán nội dung vào slot bằng cách sử dụng directive @slot. Nội dung không thuộc @slot sẽ được truyền vào component trong biến @slot

@component('alert')
        @slot('title')
            Forbidden
        @endslot
        You are not allowed to access this resource!
@endcomponent

Truyền thêm dữ liệu vào component 

Thỉnh thoảng bạn cần truyền dữ liệu bổ sung vào cho một component. Vì lý do này, bạn có thể truyền một mảng như là tham số thứ hai cho directive @component. Tất cả dữ liệu sẽ được cung cấp cho component template như các biến:

@component('alert', ['foo' => 'bar'])
    ...
@endcomponent

Hiển thị dữ liệu

Bạn có thể hiển thị dữ liệu truyền vào trong Blade view bằng cách đặt biến vào trong cặp ngoặc { }. Ví dụ, với route dưới đây:

Route::get('greeting', function () {
    return view('welcome', ['name' => 'Samantha']);
});

Bạn có thể hiển thị nội dung của biến name như sau:

Hello, {{ $name }}. 
Tất nhiên sẽ không có hạn chế trong việc hiển thị nội dung của biến truyền vào trong view. Bạn cũng có thể hiển thị kết quả trả về của bất cứ hàm PHP nào. Chính xác hơn, bạn có thể đặt bất cứ đoạn mã PHP bạn muốn vào Blade:
The current UNIX timestamp is {{ time() }}.

Lưu ý: Cặp dấu {{ }} của Blade được tự động gửi đến hàm htmlspecialchars của PHP để ngăn chặn các hành vi tấn công XSS.

Hiển thị Unescaped Data

Mặc định, cặp {{}} được tự động gửi qua hàm htmlspecialchars của PHP để ngăn chặn tấn công XSS. Nếu bạn không muốn dữ liệu bị escaped (thất thoát), bạn có thể sử dụng cú pháp:

Hello, {!! $name !!}.

Lưu ý: Phải cẩn thận khi hiển thị nội dung được cung cấp bởi người dùng. Luôn luôn sử dụng cặp ngoặc nhọn {{}} để ngăn chặn tấn công XSS khi hiển thị dữ liệu được đưa bởi người dùng.

Blade và JavaScript Framework

Nhiều framework trong javascript cũng sử dụng cặp dấu ngoặc {} để cho biết một biểu thức cần được hiển thị lên trình duyệt, bạn có thể sử dụng ký hiệu @ để báo cho Bload biết là biểu thức này cần được giữa lại. Ví dụ:

<h1>Laravel</h1>

Hello, @{{ name }}. 

Ở ví dụ này, ký hiệu @ sẽ bị Blade xóa đi, tuy nhiên biểu thức {{name}} sẽ vẫn được giữ lại và cho nó render tiếp với Javascript framework khác.

Directive  @verbatim

Nếu bạn muốn hiển thị biến Javavascript trong phần lớn tamplate của bạn, bạn có thể bọc chúng trong directive @verbatim khi đó bạn sẽ không cần ký tự @ trước câu lệnh hiển thị:

@verbatim
    <div class="container">
        Hello, {{ name }}.
    </div>
@endverbatim

Leave a Reply

Your email address will not be published. Required fields are marked *