Cú pháp template v2
Template v2 là cú pháp template được khuyến nghị của Zittme. Đây là các directive kiểu Blade được bổ sung tính năng riêng của Zittme, và tương thích với cú pháp v1 trong cùng một tệp.
Khai báo phiên bản
- Tệp
.html: ở dòng đầu tiên ghi@version(2)(hoặc<config version="2" />) - Tệp
.blade.php: tự động là v2 (có thể được IDE tô sáng cú pháp)
@version(2)
<div class="my-skin">
<h1>{{ $title }}</h1>
</div>Xuất dữ liệu
| Cú pháp | Ý nghĩa |
|---|---|
{{ $var }} | Xuất sau khi escape HTML (mặc định) |
{!! $var !!} | Xuất nguyên văn, không escape |
{$var} | Xuất tương thích v1 |
Chỉ dùng {!! !!} cho HTML đã được lõi làm sạch, như nội dung của trình soạn thảo. Xuất nguyên dữ liệu người dùng nhập sẽ gây ra XSS. Việc escape được xử lý tự động theo ngữ cảnh (HTML/JS).
Bộ lọc
Bạn có thể nối |filter vào sau phần xuất, và có thể nối nhiều bộ lọc.
{{ $title|upper }}
{{ $timestamp|date:'Y-m-d' }}
{{ $price|number_format }}
{{ $tags|join:', ' }}Các bộ lọc chính: autoescape escape noescape escapejs json strip_tags trim urlencode lower upper nl2br join:separator date:format number_format:decimals number_shorten link
Điều kiện
@if ($is_logged)
...
@elseif ($guest_allowed)
...
@else
...
@endifCũng có các directive điều kiện chuyên dụng.
| Directive | Ý nghĩa |
|---|---|
@isset($var) ~ @endisset | Nếu biến tồn tại |
@empty($var) ~ @endempty | Nếu rỗng |
@admin ~ @endadmin | Nếu là quản trị viên cao nhất |
@auth ~ @endauth | Nếu đã đăng nhập (@auth('manager') là quyền quản lý) |
@guest ~ @endguest | Nếu chưa đăng nhập |
@can('view') ~ @endcan | Nếu có quyền tương ứng (cũng hỗ trợ @cannot, @canany([...])) |
@desktop / @mobile | Phân biệt thiết bị |
Vòng lặp
@foreach ($list as $key => $item)
<li>{{ $item->title }}</li>
@endforeach
@forelse ($list as $item)
<li>{{ $item->title }}</li>
@empty
<li>항목이 없습니다</li>
@endforelseCũng hỗ trợ @for @while @switch/@case/@break/@default @continue.
Bên trong vòng lặp có thể dùng biến $loop: $loop->index (bắt đầu từ 0) $loop->iteration (bắt đầu từ 1) $loop->count $loop->first $loop->last $loop->even $loop->odd $loop->depth $loop->parent
@foreach ($list as $item)
<li class="@if ($loop->first) is-first @endif">{{ $loop->iteration }}. {{ $item->title }}</li>
@endforeachHàm hỗ trợ thuộc tính HTML
<div @class(['base', 'is-on' => $active, 'is-mine' => $item->mine])>...</div>
<div @style(['color: red', 'display: none' => $hidden])>...</div>
<input type="checkbox" @checked($is_checked) />
<option value="1" @selected($val == 1)>하나</option>
<input @disabled($locked) @readonly($readonly) @required($must) />Cách viết checked="checked"|cond="..." của v1 vẫn tiếp tục hoạt động.
Mã PHP
@php
$count = count($list);
$first = $count ? reset($list) : null;
@endphp
{@ $total = $count + 1; }- Biến template mặc định là trạng thái dùng chung tham chiếu tới Context. Thêm dấu gạch chéo ngược như
\$varthì biến trở thành biến cục bộ chỉ của template đó. Tham số của closure và ràng buộc use cũng dùng\$. - Bên trong
{@ ... }cũng có thể mở và đóng khối theo kiểuforeach (...):/endforeach;.
Chú thích
{{-- 템플릿 주석: 출력에서 제거됩니다 --}}
<!--// v1 스타일 주석: 역시 제거됩니다 -->
<!-- 일반 HTML 주석: 출력에 남습니다 -->Lưu ý: chú thích {{-- --}} bắt buộc phải viết trên một dòng. Nếu viết trải trên nhiều dòng, trình phân tích không thể loại bỏ hoàn toàn và có thể gây lỗi máy chủ (500). Đã từng có sự cố thực tế do vấn đề này. Hãy viết giải thích nhiều dòng bằng chú thích HTML (<!-- -->).
Nhúng template khác
@include('_header')
@include('sub/box')
@include('_card', ['title' => $t, 'body' => $b]) {{-- 변수 전달 --}}
<include src="_promo" if="$show_promo" /> {{-- 조건부 포함 --}}
<include src="_banner" unless="$is_admin" />- Khi truyền biến, template được nhúng chỉ dùng các biến được truyền vào thay cho Context (dùng như component).
- Nhúng có điều kiện được thực hiện bằng các thuộc tính
if/when/cond/unlesscủa thẻ<include>. <include target="..." />của v1 cũng hoạt động.
Nạp tài nguyên: @load
@load('css/skin.css')
@load('css/skin.scss', $vars) {{-- SCSS 변수 전달 --}}
@load('js/skin.js')
@load('js/lazy.js', 'body') {{-- body 끝에서 로드 --}}
@load('^/common/js/plugins/URI.js') {{-- ^ 는 사이트 루트 --}}
@load('../lang/') {{-- 언어 파일 디렉터리 --}}
@unload('foo/bar.js') {{-- 로드 취소 --}}Có thể chỉ định thêm tham số: với CSS là media·thứ tự, với JS là head/body·thứ tự.
Tạo URL
<a href="@url('act', 'dispMemberInfo')">내 정보</a>
<a href="{{ getUrl('', 'mid', $mid, 'act', 'dispBoardWrite') }}">글쓰기</a>@url(...) và getUrl(...) làm cùng một việc. Bạn chỉ cần nhớ một quy tắc.
- Liên kết chỉ thay đổi tham số của trang hiện tại (phân trang·sắp xếp): không có tham số đầu tiên,
getUrl('page', $n) - Liên kết đi tới màn hình khác: bắt buộc truyền
''làm tham số đầu tiên để tạo mới từ URL rỗng. Nếu không, toàn bộ tham số của yêu cầu hiện tại sẽ bị kéo theo.
Nếu action có khai báo route thì địa chỉ ngắn sẽ được tạo tự động.
Các directive khác
| Directive | Ý nghĩa |
|---|---|
@csrf | Chèn trường token CSRF vào trong form |
@json($array) | Xuất JSON an toàn cho JS (tự nhận biết ngữ cảnh) |
@lang('key') | Xuất chuỗi ngôn ngữ (@lang('module.key')) |
@use('Namespace\Class', 'Alias') | Khai báo bí danh lớp. Sau đó dùng {{ Alias::method() }} |
@widget('widget-name', $args) | Chèn widget |
@once ~ @endonce | Chỉ chạy một lần kể cả trong vòng lặp |
@verbatim ~ @endverbatim | Không phân tích cú pháp template trong đoạn này |
@dump($var) / @dd($var) | Xuất để gỡ lỗi (dd dừng sau khi xuất) |
@push('name') ~ @endpush / @stack('name') | Gom nội dung rồi xuất tại một chỗ |
@error('validator-id') ~ @enderror | Hiển thị lỗi kiểm tra form |
Những gì v2 không hỗ trợ
- Kế thừa template của Blade (
@extends@yield@section) và slot (@slot@inject) - Thẻ
<block>của v1, thuộc tínhloop/condtrên thẻ bất kỳ (ngoại trừ thuộc tính điều kiện của<include>)
Các tệp cũ cần cú pháp v1 thì cứ để nguyên. Tránh trộn cú pháp của hai thế hệ trong cùng một tệp.
Những cái bẫy thường gặp trong thực tế
Các mục này được rút ra từ các sự cố thực tế.
- Cấm chú thích
{{-- --}}nhiều dòng (xem mục chú thích ở trên). Đây là nguyên nhân quen thuộc của lỗi máy chủ 500. - Khi gọi trực tiếp phương thức tĩnh trong template, hãy khai báo bí danh bằng
@userồi gọi qua bí danh. Nếu gọi trực tiếp bằng đường dẫn namespace đầy đủ bên trong giá trị thuộc tính, quá trình biên dịch có thể sai lệch và tạo ra liên kết hỏng như%7B...%7D. An toàn nhất là truyền giá trị từ controller bằngContext::set(). Context::set()ghi đè biến yêu cầu cùng tên. Khi đọc giá trị form trong action proc, đọc trực tiếp$_POSTsẽ an toàn hơn.- Độ ưu tiên của bộ chọn CSS:
.wrap a { color: inherit }của CSS chung mạnh hơn một.my-linkmới tạo. Nếu màu liên kết không có tác dụng, hãy tăng độ ưu tiên như.wrap a.my-link.