Frontend - 1. Blade Templates
Einführung
Blade ist der einfache, aber leistungsstarke Templating-Motor, der mit Laravel ausgestattet ist. Im Gegensatz zu anderen gängigen PHP-Templating-Engines beschränkt Blade Sie nicht daran, einfachen PHP-Code in Ihren Ansichten zu verwenden. Tatsächlich werden alle Blade-Ansichten in einfachen PHP-Code kompiliert und zwischengespeichert, bis sie geändert werden, was bedeutet, dass Blade Ihrer Anwendung im Wesentlichen keinen Overhead hinzufügt. Blade-Ansichtsdateien verwenden die Dateierweiterung .blade.php und werden normalerweise im Verzeichnis resources/views gespeichert.
more themes about Frontend [TaskID] - Click for open
Template Inheritance
Defining A Layout
Zwei der Hauptvorteile der Verwendung von Blade sind die Vererbung von Vorlagen und Abschnitte. Als Einstieg werfen wir einen Blick auf ein einfaches Beispiel. Zuerst untersuchen wir ein "Master"-Seitenlayout. Da die meisten Webanwendungen das gleiche allgemeine Layout auf verschiedenen Seiten beibehalten, ist es sinnvoll, dieses Layout als eine einzige Blade-Ansicht zu definieren:
<!-- 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>
Wie Sie sehen können, enthält diese Datei den typischen HTML-Markup. Beachten Sie jedoch die Richtlinien @section und @yield. Die @section-Direktive definiert, wie der Name schon sagt, einen Abschnitt des Inhalts, während die @yield-Direktive verwendet wird, um den Inhalt eines bestimmten Abschnitts anzuzeigen.
Nachdem wir nun ein Layout für unsere Anwendung definiert haben, definieren wir eine Unterseite, die das Layout übernimmt.
Extending A Layout
Wenn Sie eine Unteransicht definieren, verwenden Sie die Blade @extends-Direktive, um festzulegen, welches Layout die Unteransicht "erben" soll. Ansichten, die ein Blade-Layout erweitern, können Inhalte in die Abschnitte des Layouts einfügen, indem sie @section-Direktiven verwenden. Denken Sie daran, wie im obigen Beispiel gezeigt, dass der Inhalt dieser Abschnitte im Layout mit @yield angezeigt wird:
<!-- 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
In diesem Beispiel verwendet der Sidebar-Bereich die @parent-Anweisung, um Inhalte an die Sidebar des Layouts anzuhängen (und nicht zu überschreiben). Die @parent Direktive wird beim Rendern der View durch den Inhalt des Layouts ersetzt.
Die @yield-Direktive akzeptiert auch einen Standardwert als zweiten Parameter. Dieser Wert wird angezeigt, wenn der zu liefernde Abschnitt undefiniert ist:
@yield('content', View::make('view.name'))
Blade-Ansichten können über den view helper von Routen zurückgegeben werden:
Route::get('blade', function () {
return view('child');
});
Components & Slots
Komponenten und Slots bieten ähnliche Vorteile wie Sektionen und Layouts; allerdings mögen einige das mentale Modell der Komponenten und Slots leichter verstehen. Stellen wir uns zunächst eine wiederverwendbare "Alarm"-Komponente vor, die wir in unserer gesamten Anwendung wieder verwenden möchten:
<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">
{{ $slot }}
</div>
Die Variable {{ $slot }} enthält den Inhalt, den wir in die Komponente injizieren wollen. Um diese Komponente zu konstruieren, können wir nun die @component Blade Direktive verwenden:
@component('alert')
<strong>Whoops!</strong> Something went wrong!
@endcomponent
Um Laravel anzuweisen, den ersten View zu laden, der aus einem gegebenen Array von möglichen Views für die Komponente existiert, können Sie die Direktive componentFirst verwenden:
@componentFirst(['custom.alert', 'alert'])
<strong>Whoops!</strong> Something went wrong!
@endcomponent
Manchmal ist es hilfreich, mehrere Slots für eine Komponente zu definieren. Lassen Sie uns unsere Alert-Komponente so modifizieren, dass sie die Eingabe eines "Titels" erlaubt. Benannte Slots können angezeigt werden, indem die Variable, die mit ihrem Namen übereinstimmt, "nachgeahmt" wird:
<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">
<div class="alert-title">{{ $title }}</div>
{{ $slot }}
</div>
Jetzt können wir mit der @slot-Direktive Inhalte in den benannten Slot injizieren. Jeglicher Inhalt, der sich nicht innerhalb der @slot-Direktive befindet, wird an die Komponente in der $slot-Variablen übergeben:
@component('alert')
@slot('title')
Forbidden
@endslot
You are not allowed to access this resource!
@endcomponent
Passing Additional Data To Components
Manchmal müssen Sie zusätzliche Daten an eine Komponente übergeben. Aus diesem Grund können Sie ein Array von Daten als zweites Argument an die @component-Anweisung übergeben. Alle Daten werden der Komponentenvorlage als Variablen zur Verfügung gestellt:
@component('alert', ['foo' => 'bar'])
...
@endcomponent
Aliasing Components
Wenn Ihre Blade-Komponenten in einem Unterverzeichnis gespeichert sind, können Sie sie zum leichteren Zugriff mit einem Alias versehen. Stellen Sie sich zum Beispiel eine Blade-Komponente vor, die unter resources/views/components/alert.blade.php gespeichert ist. Sie können die component-Methode verwenden, um die Komponente von components.alert zu alert zu aliasisieren. Typischerweise sollte dies in der boot-Methode Ihres AppServiceProviders geschehen:
use Illuminate\Support\Facades\Blade;
Blade::component('components.alert', 'alert');
Sobald die Komponente aliasisiert wurde, können Sie sie mit einer Direktive rendern:
@alert(['type' => 'danger'])
You are not allowed to access this resource!
@endalert
Sie können die Parameter der Komponente auslassen, wenn sie keine zusätzlichen Slots hat:
@alert
You are not allowed to access this resource!
@endalert
Displaying Data
Sie können die an Ihre Blade-Ansichten übergebenen Daten anzeigen, indem Sie die Variable in geschweifte Klammern setzen. Zum Beispiel, wenn Sie die folgende Route angegeben haben:
Route::get('greeting', function () {
return view('welcome', ['name' => 'Samantha']);
});
Sie können sich den Inhalt der Namensvariablen auf diese Weise anzeigen lassen:
Hello, {{ $name }}.
Sie sind nicht darauf beschränkt, den Inhalt der an den View übergebenen Variablen anzuzeigen. Sie können auch die Ergebnisse jeder beliebigen PHP-Funktion wiedergeben. Tatsächlich können Sie jeden beliebigen PHP-Code in eine Blade-Echo-Anweisung einfügen:
The current UNIX timestamp is {{ time() }}.
Displaying Unescaped Data
Standardmäßig werden Blade {{ }} Anweisungen automatisch durch PHP's htmlspecialchars Funktion gesendet, um XSS Angriffe zu verhindern. Wenn Sie nicht wollen, dass Ihre Daten escaped werden, können Sie die folgende Syntax verwenden:
Hello, {!! $name !!}.
Rendering JSON
Manchmal können Sie ein Array an Ihre Ansicht mit der Absicht übergeben, es als JSON zu rendern, um eine JavaScript-Variable zu initialisieren. Zum Beispiel:
<script>
var app = <?php echo json_encode($array); ?>;
</script>
Anstatt json_encode manuell aufzurufen, können Sie jedoch die @json Blade-Direktive verwenden. Die @json-Direktive akzeptiert die gleichen Argumente wie die PHP-Funktion json_encode:
<script>
var app = @json($array);
var app = @json($array, JSON_PRETTY_PRINT);
</script>
Die @json-Direktive ist auch nützlich für das Seeden von Vue-Komponenten oder data-*-Attributen:
HTML Entity Encoding
Standardmäßig wird Blade (und der Laravel e Helfer) HTML-Elemente doppelt kodieren. Wenn Sie die doppelte Kodierung deaktivieren möchten, rufen Sie die Methode Blade::withoutDoubleEncoding aus der boot-Methode Ihres AppServiceProviders auf:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Blade::withoutDoubleEncoding();
}
}
Blade & JavaScript Frameworks
Da viele JavaScript-Frameworks auch "geschweifte" Klammern verwenden, um anzuzeigen, dass ein bestimmter Ausdruck im Browser angezeigt werden soll, können Sie das @-Symbol verwenden, um der Blade-Rendering-Engine mitzuteilen, dass ein Ausdruck unangetastet bleiben soll. Zum Beispiel:
<h1>Laravel</h1>
Hello, @{{ name }}.
In diesem Beispiel wird das @-Symbol von Blade entfernt; der Ausdruck {{ Name }} bleibt jedoch von der Blade-Engine unangetastet, so dass er stattdessen von Ihrem JavaScript-Framework gerendert werden kann.
The @verbatim Directive
Wenn Sie JavaScript-Variablen in einem großen Teil Ihres Templates anzeigen, können Sie das HTML in der @verbatim-Direktive umbrechen, so dass Sie nicht jeder Blade-Echo-Anweisung ein @-Symbol voranstellen müssen:
@verbatim
<div class="container">
Hello, {{ name }}.
</div>
@endverbatim
Control Structures
Neben der Vererbung von Templates und der Anzeige von Daten bietet Blade auch komfortable Verknüpfungen für gängige PHP-Steuerstrukturen, wie z.B. bedingte Anweisungen und Schleifen. Diese Abkürzungen bieten eine sehr saubere, prägnante Möglichkeit, mit PHP-Kontrollstrukturen zu arbeiten, während sie gleichzeitig mit ihren PHP-Pendants vertraut bleiben.
If Statements
Sie können if-Anweisungen mit den Anweisungen @if, @elseif, @else und @endif erstellen. Diese Direktiven funktionieren identisch zu ihren PHP-Gegenstücken:
@if (count($records) === 1)
I have one record!
@elseif (count($records) > 1)
I have multiple records!
@else
I don't have any records!
@endif
Der Einfachheit halber bietet Blade auch eine @unless-Anweisung:
@unless (Auth::check())
You are not signed in.
@endunless
Zusätzlich zu den bereits besprochenen Bedingungsdirektiven können die @isset- und @empty-Direktiven als bequeme Abkürzungen für ihre jeweiligen PHP-Funktionen verwendet werden:
@isset($records)
// $records is defined and is not null...
@endisset
@empty($records)
// $records is "empty"...
@endempty
Authentication Directives
Die @auth und @guest Direktiven können verwendet werden, um schnell festzustellen, ob der aktuelle Benutzer authentifiziert ist oder ein Gast ist:
@auth
// The user is authenticated...
@endauth
@guest
// The user is not authenticated...
@endguest
Bei Bedarf können Sie den Authentifizierungsschutz angeben, der bei der Verwendung der @auth und @guest Direktiven geprüft werden soll:
@auth('admin')
// The user is authenticated...
@endauth
@guest('admin')
// The user is not authenticated...
@endguest
Section Directives
Sie können mit der @hasSection-Direktive prüfen, ob ein Abschnitt einen Inhalt hat:
@hasSection('navigation')
<div class="pull-right">
@yield('navigation')
</div>
<div class="clearfix"></div>
@endif
Switch Statements
Switch-Anweisungen können mit den Anweisungen @switch, @case, @break, @default und @endswitch erstellt werden:
@switch($i)
@case(1)
First case...
@break
@case(2)
Second case...
@break
@default
Default case...
@endswitch
Loops
Zusätzlich zu den bedingten Anweisungen bietet Blade einfache Direktiven für die Arbeit mit den Schleifenstrukturen von PHP. Auch hier funktioniert jede dieser Direktiven identisch zu ihren PHP-Gegenstücken:
@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
Bei Verwendung von Schleifen können Sie die Schleife auch beenden oder die aktuelle Iteration überspringen:
@foreach ($users as $user)
@if ($user->type == 1)
@continue
@endif
<li>{{ $user->name }}</li>
@if ($user->number == 5)
@break
@endif
@endforeach
Sie können auch die Bedingung mit der Erklärung der Richtlinie in einer Zeile einfügen:
@foreach ($users as $user)
@continue($user->type == 1)
<li>{{ $user->name }}</li>
@break($user->number == 5)
@endforeach
The Loop Variable
Beim Schleifenbetrieb steht eine $loop-Variable innerhalb Ihrer Schleife zur Verfügung. Diese Variable bietet Zugriff auf einige nützliche Informationen, wie z.B. den aktuellen Schleifenindex und ob dies die erste oder letzte Iteration durch die Schleife ist:
@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
Wenn Sie sich in einer geschachtelten Schleife befinden, können Sie auf die $loop-Variable der Elternschleife über die Elterneigenschaft (parent property) zugreifen:
@foreach ($users as $user)
@foreach ($user->posts as $post)
@if ($loop->parent->first)
This is first iteration of the parent loop.
@endif
@endforeach
@endforeach
Die Variable $loop enthält auch eine Vielzahl anderer nützlicher Eigenschaften:
Property | Description |
---|---|
$loop->index | Der Index der aktuellen Schleifeniteration (beginnt bei 0). |
$loop->iteration | Die aktuelle Schleife (beginnt bei 1). |
$loop->remaining | Die in der Schleife verbleibenden Iterationen. |
$loop->count | Die Gesamtzahl der Elemente in dem zu iterierenden Array. |
$loop->first | Ob dies die erste Iteration durch die Schleife ist. |
$loop->last | Ob dies die letzte Iteration durch die Schleife ist. |
$loop->even | Ob dies eine gerade Iteration durch die Schleife ist. |
$loop->odd | Ob dies eine ungerade Iteration durch die Schleife ist. |
$loop->depth | Die Schachtelungsebene der aktuellen Schleife. |
$loop->parent | Wenn in einer geschachtelten Schleife, die Schleifenvariable des Elternteils. |
Comments
Blade erlaubt Ihnen auch, Kommentare in Ihren Ansichten zu definieren. Im Gegensatz zu HTML-Kommentaren sind die Kommentare von Blade jedoch nicht in dem von Ihrer Anwendung zurückgegebenen HTML enthalten:
{{-- This comment will not be present in the rendered HTML --}}
PHP
In einigen Situationen ist es nützlich, PHP-Code in Ihre Ansichten einzubetten. Sie können die Blade @php-Direktive verwenden, um einen Block von einfachem PHP innerhalb Ihres Templates auszuführen:
@php
//
@endphp
Forms
CSRF Field
Jedes Mal, wenn Sie ein HTML-Formular in Ihrer Anwendung definieren, sollten Sie ein verstecktes CSRF-Token-Feld in das Formular einfügen, damit die CSRF-Protection die Anforderung validieren kann. Sie können die @csrf Blade-Direktive verwenden, um das Token-Feld zu generieren:
<form method="POST" action="/profile">
@csrf
...
</form>
Method Field
Da HTML-Formulare keine PUT-, PATCH- oder DELETE-Anforderungen stellen können, müssen Sie ein verstecktes _method-Feld hinzufügen, um diese HTTP-Verben zu verfälschen. Die @method Blade-Direktive kann dieses Feld für Sie erstellen:
<form action="/foo/bar" method="POST">
@method('PUT')
...
</form>
Validation Errors
Die @error-Direktive kann verwendet werden, um schnell zu prüfen, ob für ein gegebenes Attribut Validierungsfehlermeldungen vorliegen. Innerhalb einer @error-Direktive können Sie die Variable $message mit einem Echo versehen, um die Fehlermeldung anzuzeigen:
<!-- /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
Including Sub-Views
Die @include-Anweisung von Blade ermöglicht es Ihnen, eine Blade-Ansicht aus einer anderen Ansicht heraus einzubinden. Alle Variablen, die für die übergeordnete Ansicht verfügbar sind, werden der eingeschlossenen Ansicht zur Verfügung gestellt:
<div>
@include('shared.errors')
<form>
<!-- Form Contents -->
</form>
</div>
Obwohl der eingeschlossene View alle im Parent View verfügbaren Daten erbt, können Sie auch ein Array mit zusätzlichen Daten an den eingeschlossenen View übergeben:
@include('view.name', ['some' => 'data'])
Wenn Sie versuchen, einen View @include einzubinden, der nicht existiert, wird Laravel einen Fehler ausgeben. Wenn Sie einen View einbinden möchten, der vorhanden sein kann oder nicht vorhanden ist, sollten Sie die @includeIf-Direktive verwenden:
@includeWhen($boolean, 'view.name', ['some' => 'data'])
Um den ersten View, der aus einem gegebenen Array von Views existiert, einzubinden, können Sie die includeFirst-Direktive verwenden:
@includeFirst(['custom.admin', 'admin'], ['some' => 'data'])
Aliasing Includes
Wenn Ihre Blade-Includes in einem Unterverzeichnis gespeichert sind, können Sie sie zum leichteren Zugriff mit einem Alias versehen. Stellen Sie sich zum Beispiel ein Blade-Include vor, das unter resources/views/includes/input.blade.php mit folgendem Inhalt gespeichert ist:
<input type="{{ $type ?? 'text' }}">
Sie können die include-Methode verwenden, um das Include von includes.input auf input zu aliasisieren. Typischerweise sollte dies in der boot-Methode Ihres AppServiceProviders geschehen:
use Illuminate\Support\Facades\Blade;
Blade::include('includes.input', 'input');
Sobald der Include aliasiert wurde, können Sie ihn mit dem Alias-Namen als Blade-Direktive rendern:
@input(['type' => 'email'])
Rendering Views For Collections
Sie können Schleifen und Includes mit der @each-Anweisung von Blade in einer Zeile kombinieren:
@each('view.name', $jobs, 'job')
Das erste Argument ist die Ansicht, die für jedes Element im Array oder der Kollektion teilweise gerendert werden soll. Das zweite Argument ist das Array oder die Kollektion, über das/die man iterieren möchte, während das dritte Argument der Variablenname ist, der der aktuellen Iteration innerhalb des Views zugewiesen wird. Wenn Sie also zum Beispiel über ein Array von Jobs iterieren, werden Sie typischerweise auf jeden Job als Job-Variable innerhalb der View partiell zugreifen wollen. Der Schlüssel für die aktuelle Iteration wird als Key-Variable innerhalb des View Parts verfügbar sein.
Sie können auch ein viertes Argument an die @each-Direktive übergeben. Dieses Argument legt den View fest, der gerendert wird, wenn das angegebene Array leer ist.
@each('view.name', $jobs, 'job', 'view.empty')
Stacks
Mit Blade können Sie zu benannten Stacks schieben, die an anderer Stelle in einer anderen Ansicht oder einem anderen Layout gerendert werden können. Dies kann besonders nützlich sein, um alle JavaScript-Bibliotheken anzugeben, die von Ihren untergeordneten Ansichten benötigt werden:
@push('scripts')
<script src="/example.js"></script>
@endpush
Sie können so oft wie nötig auf einen Stapel schieben. Um den kompletten Stack-Inhalt zu rendern, übergeben Sie den Namen des Stacks an die @stack-Direktive:
<head>
<!-- Head Contents -->
@stack('scripts')
</head>
Wenn Sie Inhalte an den Anfang eines Stacks voranstellen möchten, sollten Sie die @prepend-Direktive verwenden:
@push('scripts')
This will be second...
@endpush
// Later...
@prepend('scripts')
This will be first...
@endprepend
Service Injection
Die @inject-Anweisung kann verwendet werden, um einen Dienst aus dem Laravel-Service-Container abzurufen. Das erste Argument, das an @inject übergeben wird, ist der Name der Variable, in die der Dienst platziert wird, während das zweite Argument der Klassen- oder Schnittstellenname des Dienstes ist, den Sie auflösen möchten:
@inject('metrics', 'App\Services\MetricsService')
<div>
Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>
Extending Blade
Blade ermöglicht es Ihnen, Ihre eigenen benutzerdefinierten Anweisungen mit der direktive-Methode zu definieren. Wenn der Blade-Compiler auf die benutzerdefinierte Direktive trifft, ruft er den bereitgestellten Callback mit dem in der Direktive enthaltenen Ausdruck auf.
Das folgende Beispiel erzeugt eine @datetime($var)-Anweisung, die ein gegebenes $var formatiert, das eine Instanz von DateTime sein sollte:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Blade::directive('datetime', function ($expression) {
return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
});
}
}
Wie Sie sehen können, werden wir die format-Methode an jeden Ausdruck verketten, der in der Direktive übergeben wird. In diesem Beispiel wird also das endgültige PHP, das durch diese Direktive generiert wird, sein:
<?php echo ($var)->format('m/d/Y H:i'); ?>
Custom If Statements
Die Programmierung einer benutzerdefinierten Direktive ist manchmal komplexer als notwendig, wenn einfache, benutzerdefinierte bedingte Anweisungen definiert werden. Aus diesem Grund bietet Blade eine Blade::if-Methode, die es Ihnen erlaubt, schnell benutzerdefinierte Bedingungsdirektiven mit Closures zu definieren. Definieren wir zum Beispiel eine benutzerdefinierte Bedingung, die die aktuelle Anwendungsumgebung prüft. Wir können dies in der boot-Methode unseres AppServiceProviders tun:
use Illuminate\Support\Facades\Blade;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Blade::if('env', function ($environment) {
return app()->environment($environment);
});
}
Sobald die benutzerdefinierte Bedingung definiert ist, können wir sie leicht auf unsere Vorlagen anwenden:
@env('local')
// The application is in the local environment...
@elseenv('testing')
// The application is in the testing environment...
@else
// The application is not in the local or testing environment...
@endenv