From d8f3f803db2774b56e263530bd4dc4c5db9fe566 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Mon, 2 Sep 2024 01:21:39 +0200 Subject: [PATCH 01/19] new translation wip --- latte/de/filters.texy | 482 ++++++++++++++++++++-------------------- latte/de/tags.texy | 500 +++++++++++++++++++++--------------------- 2 files changed, 491 insertions(+), 491 deletions(-) diff --git a/latte/de/filters.texy b/latte/de/filters.texy index 8e445dd3c3..7db3a09bd2 100644 --- a/latte/de/filters.texy +++ b/latte/de/filters.texy @@ -1,101 +1,101 @@ -Latte Filtern -************* +Latte Filter +************ .[perex] -Filter sind Funktionen, die die Daten in der gewünschten Form verändern oder formatieren. Dies ist eine Zusammenfassung der eingebauten Filter, die verfügbar sind. +In Templates können wir Funktionen verwenden, die bei der Anpassung oder Umformatierung von Daten in die endgültige Form helfen. Wir nennen sie *Filter*. .[table-latte-filters] -|## String / Array Transformation -| `batch` | [Auflistung linearer Daten in einer Tabelle |#batch] -| `breakLines` | [fügt HTML-Zeilenumbrüche vor allen Zeilenumbrüchen ein |#breakLines] -| `bytes` | [formatiert Größe in Bytes |#bytes] -| `clamp` | [klemmt Wert auf den Bereich |#clamp] -| `dataStream` | [Konvertierung des Daten-URI-Protokolls |#datastream] -| `date` | [formatiert das Datum und die Uhrzeit |#date] -| `explode` | [trennt eine Zeichenkette durch das angegebene Trennzeichen auf |#explode] -| `first` | [gibt das erste Element eines Arrays oder ein Zeichen einer Zeichenkette zurück |#first] -| `group` | [gruppiert Daten nach verschiedenen Kriterien |#group] -| `implode` | [fügt ein Array zu einer Zeichenkette zusammen |#implode] -| `indent` | [rückt den Text von links mit einer Anzahl von Tabulatorenein |#indent] -| `join` | [verbindet ein Array mit einer Zeichenkette|#implode] -| `last` | [gibt das letzte Element eines Arrays oder ein Zeichen einer Zeichenkette zurück |#last] -| `length` | [gibt die Länge einer Zeichenkette oder eines Arrays zurück |#length] -| `localDate` | [formatiert das Datum und die Uhrzeit entsprechend dem Gebietsschema |#localDate] -| `number` | [formatiert Zahlen |#number] -| `padLeft` | [vervollständigt die Zeichenkette auf die angegebene Länge von links |#padLeft] -| `padRight` | [vervollständigt die Zeichenkette auf die angegebene Länge von rechts |#padRight] -| `random` | [gibt zufällige Elemente eines Arrays oder Zeichen einer Zeichenkette zurück |#random] -| `repeat` | [Wiederholt die Zeichenkette |#repeat] -| `replace` | [ersetzt alle Vorkommen der gesuchten Zeichenkette durch die Ersetzung |#replace] -| `replaceRE` | [ersetzt alle Vorkommen entsprechend dem regulären Ausdruck |#replaceRE] -| `reverse` | [kehrt eine UTF-8 Zeichenkette oder ein Array um |#reverse] -| `slice` | [extrahiert einen Ausschnitt aus einem Array oder einer Zeichenkette |#slice] -| `sort` | [sortiert ein Array |#sort] -| `spaceless` | [entfernt Leerzeichen |#spaceless], ähnlich dem [spaceless |tags] tag -| `split` | [trennt eine Zeichenkette durch das angegebene Trennzeichen auf |#explode] -| `strip` | [Entfernt Leerzeichen |#spaceless] -| `stripHtml` | [entfernt HTML-Tags und konvertiert HTML-Entities in Text |#stripHtml] -| `substr` | [gibt einen Teil der Zeichenkette zurück |#substr] -| `trim` | [entfernt Leerzeichen aus der Zeichenkette |#trim] -| `translate` | [Übersetzung in andere Sprachen |#translate] -| `truncate` | [verkürzt die Länge unter Beibehaltung ganzer Wörter |#truncate] -| `webalize` | [passt die UTF-8-Zeichenfolge an die in der URL verwendete Forman |#webalize] +|## Transformation +| `batch` | [Auflistung linearer Daten in einer Tabelle |#batch] +| `breakLines` | [Fügt HTML-Zeilenumbrüche am Ende der Zeilen hinzu |#breakLines] +| `bytes` | [formatiert die Größe in Bytes |#bytes] +| `clamp` | [begrenzt einen Wert auf einen bestimmten Bereich |#clamp] +| `dataStream` | [Konvertierung für das Data URI-Protokoll |#datastream] +| `date` | [formatiert Datum und Uhrzeit |#date] +| `explode` | [teilt eine Zeichenkette in ein Array anhand eines Trennzeichens |#explode] +| `first` | [gibt das erste Element eines Arrays oder Zeichen einer Zeichenkette zurück |#first] +| `group` | [gruppiert Daten nach verschiedenen Kriterien |#group] +| `implode` | [verbindet ein Array zu einer Zeichenkette |#implode] +| `indent` | [rückt Text von links um eine bestimmte Anzahl von Tabulatoren ein |#indent] +| `join` | [verbindet ein Array zu einer Zeichenkette |#implode] +| `last` | [gibt das letzte Element eines Arrays oder Zeichen einer Zeichenkette zurück |#last] +| `length` | [gibt die Länge einer Zeichenkette in Zeichen oder eines Arrays zurück |#length] +| `localDate` | [formatiert Datum und Uhrzeit entsprechend den Ländereinstellungen |#localDate] +| `number` | [formatiert eine Zahl |#number] +| `padLeft` | [füllt eine Zeichenkette links auf eine bestimmte Länge auf |#padLeft] +| `padRight` | [füllt eine Zeichenkette rechts auf eine bestimmte Länge auf |#padRight] +| `random` | [gibt ein zufälliges Element eines Arrays oder Zeichen einer Zeichenkette zurück |#random] +| `repeat` | [Wiederholung einer Zeichenkette |#repeat] +| `replace` | [ersetzt Vorkommen einer gesuchten Zeichenkette |#replace] +| `replaceRE` | [ersetzt Vorkommen anhand eines regulären Ausdrucks |#replaceRE] +| `reverse` | [kehrt eine UTF-8 Zeichenkette oder ein Array um |#reverse] +| `slice` | [extrahiert einen Teil eines Arrays oder einer Zeichenkette |#slice] +| `sort` | [sortiert ein Array |#sort] +| `spaceless` | [entfernt Leerzeichen |#spaceless], ähnlich wie das [spaceless |tags] Tag +| `split` | [teilt eine Zeichenkette in ein Array anhand eines Trennzeichens |#explode] +| `strip` | [entfernt Leerzeichen |#spaceless] +| `stripHtml` | [entfernt HTML-Tags und konvertiert HTML-Entities in Zeichen |#stripHtml] +| `substr` | [gibt einen Teil einer Zeichenkette zurück |#substr] +| `trim` | [entfernt führende und abschließende Leerzeichen oder andere Zeichen |#trim] +| `translate` | [Übersetzung in andere Sprachen |#translate] +| `truncate` | [kürzt die Länge unter Beibehaltung von Wörtern |#truncate] +| `webalize` | [passt eine UTF-8 Zeichenkette in eine in URLs verwendete Form an |#webalize] .[table-latte-filters] -|## Buchstabenumbruch -| `capitalize` | [Kleinschreibung, der erste Buchstabe eines jeden Wortes wird großgeschrieben |#capitalize] -| `firstUpper` | [macht den ersten Buchstaben zu einem Großbuchstaben |#firstUpper] -| `lower` | [macht eine Zeichenfolge klein |#lower] -| `upper` | [macht eine Zeichenkette zu einem Großbuchstaben |#upper] +|## Groß-/Kleinschreibung +| `capitalize` | [Kleinbuchstaben, erste Buchstaben der Wörter groß |#capitalize] +| `firstUpper` | [konvertiert den ersten Buchstaben in einen Großbuchstaben |#firstUpper] +| `lower` | [konvertiert in Kleinbuchstaben |#lower] +| `upper` | [konvertiert in Großbuchstaben |#upper] .[table-latte-filters] -|## Rundung von Zahlen -| `ceil` | [rundet eine Zahl auf eine bestimmte Genauigkeit auf|#ceil] -| `floor` | [rundet eine Zahl auf eine bestimmte Genauigkeit ab |#floor] -| `round` | [rundet eine Zahl auf eine bestimmte Genauigkeit|#round] +|## Rundung +| `ceil` | [rundet eine Zahl auf eine bestimmte Genauigkeit auf |#ceil] +| `floor` | [rundet eine Zahl auf eine bestimmte Genauigkeit ab |#floor] +| `round` | [rundet eine Zahl auf eine bestimmte Genauigkeit |#round] .[table-latte-filters] |## Escaping -| `escapeUrl` | [gibt einen Parameter in der URL als Escapezeichen aus|#escapeUrl] -| `noescape` | [druckt eine Variable ohne Escaping |#noescape] -| `query` | [erzeugt eine Abfragezeichenfolge in der URL |#query] +| `escapeUrl` | [escapet einen Parameter in einer URL |#escapeUrl] +| `noescape` | [gibt eine Variable ohne Escaping aus |#noescape] +| `query` | [generiert einen Query-String in einer URL |#query] -Es gibt auch Escape-Filter für HTML (`escapeHtml` und `escapeHtmlComment`), XML (`escapeXml`), JavaScript (`escapeJs`), CSS (`escapeCss`) und iCalendar (`escapeICal`), die Latte dank [kontextsensitivem Escaping |safety-first#Context-aware escaping] selbst verwendet und die Sie nicht schreiben müssen. +Es gibt außerdem Escaping-Filter für HTML (`escapeHtml` und `escapeHtmlComment`), XML (`escapeXml`), JavaScript (`escapeJs`), CSS (`escapeCss`) und iCalendar (`escapeICal`), die Latte selbst dank [kontextsensitivem Escaping |safety-first#Context-aware escaping] verwendet und die Sie nicht explizit schreiben müssen. .[table-latte-filters] |## Sicherheit -| `checkUrl` | [säubert Zeichenketten für die Verwendung im href-Attribut |#checkUrl] -| `nocheck` | [verhindert automatische URL-Sanitisierung |#nocheck] +| `checkUrl` | [behandelt eine URL-Adresse gegen gefährliche Eingaben |#checkUrl] +| `nocheck` | [verhindert die automatische Behandlung einer URL-Adresse |#nocheck] -Latte der `src` und `href` Attribute [prüft automatisch |safety-first#link checking], so dass Sie den `checkUrl` Filter fast nicht verwenden müssen. +Latte [überprüft automatisch |safety-first#link checking] die Attribute `src` und `href`, sodass Sie den `checkUrl`-Filter fast nie verwenden müssen. .[note] -Alle eingebauten Filter arbeiten mit UTF-8 kodierten Zeichenketten. +Alle Standard-Filter sind für Zeichenketten in UTF-8-Kodierung ausgelegt. Verwendung .[#toc-usage] ======================== -Latte erlaubt den Aufruf von Filtern unter Verwendung der Pipe-Schreibweise (vorangestelltes Leerzeichen ist erlaubt): +Filter werden durch einen senkrechten Strich notiert (vor dem ein Leerzeichen stehen kann): ```latte

{$heading|upper}

``` -Filter können verkettet werden, in diesem Fall gelten sie in der Reihenfolge von links nach rechts: +Filter (in älteren Versionen Helper genannt) können verkettet werden und werden dann in der Reihenfolge von links nach rechts angewendet: ```latte

{$heading|lower|capitalize}

``` -Die Parameter werden durch Doppelpunkt oder Komma getrennt hinter den Filternamen gesetzt: +Parameter werden nach dem Filternamen durch Doppelpunkte oder Kommas getrennt angegeben: ```latte

{$heading|truncate:20,''}

``` -Filter können auf Ausdrücke angewendet werden: +Filter können auch auf Ausdrücke angewendet werden: ```latte {var $name = ($title|upper) . ($subtitle|lower)} @@ -108,7 +108,7 @@ $latte = new Latte\Engine; $latte->addFilter('shortify', fn(string $s, int $len = 10) => mb_substr($s, 0, $len)); ``` -Wir verwenden sie in einer Vorlage wie dieser: +Im Template wird es dann so aufgerufen: ```latte

{$text|shortify}

@@ -122,7 +122,7 @@ Filter .[#toc-filters] batch(int length, mixed item): array .[filter] ---------------------------------------------- -Filter, der die Auflistung von linearen Daten in Form einer Tabelle vereinfacht. Er gibt ein Array von Arrays mit der angegebenen Anzahl von Elementen zurück. Wenn Sie einen zweiten Parameter angeben, wird dieser verwendet, um fehlende Elemente in der letzten Zeile aufzufüllen. +Ein Filter, der die Ausgabe linearer Daten in Form einer Tabelle vereinfacht. Er gibt ein Array von Arrays mit der angegebenen Anzahl von Elementen zurück. Wenn Sie einen zweiten Parameter angeben, wird er verwendet, um fehlende Elemente in der letzten Zeile zu ergänzen. ```latte {var $items = ['a', 'b', 'c', 'd', 'e']} @@ -137,7 +137,7 @@ Filter, der die Auflistung von linearen Daten in Form einer Tabelle vereinfacht. ``` -Druckt: +Gibt aus: ```latte @@ -154,22 +154,22 @@ Druckt:
``` -Siehe auch [group |#group] und [iterateWhile-Tag |tags#iterateWhile]. +Siehe auch [#group] und das [iterateWhile |tags#iterateWhile] Tag. breakLines .[filter] -------------------- -Fügt HTML-Zeilenumbrüche vor allen Zeilenumbrüchen ein. +Fügt vor jedem Zeilenumbruchzeichen ein HTML-Tag `
` ein ```latte {var $s = "Text & with \n newline"} -{$s|breakLines} {* gibt "Text & with
\n newline" *} +{$s|breakLines} {* gibt "Text & with
\n newline" aus *} ``` bytes(int precision = 2) .[filter] ---------------------------------- -Formatiert die Größe in Bytes in eine für Menschen lesbare Form. Wenn das [Gebietsschema |develop#locale] festgelegt ist, werden die entsprechenden Dezimal- und Tausendertrennzeichen verwendet. +Formatiert die Größe in Bytes in eine menschenlesbare Form. Wenn [Ländereinstellungen |develop#locale] gesetzt sind, werden die entsprechenden Dezimal- und Tausendertrennzeichen verwendet. ```latte {$size|bytes} 0 B, 1.25 GB, … @@ -179,51 +179,51 @@ Formatiert die Größe in Bytes in eine für Menschen lesbare Form. Wenn das [Ge ceil(int precision = 0) .[filter] --------------------------------- -Rundet eine Zahl bis zu einer bestimmten Genauigkeit. +Rundet eine Zahl auf eine bestimmte Genauigkeit auf. ```latte -{=3.4|ceil} {* gibt 4 *} -{=135.22|ceil:1} {* gibt 135.3 *} -{=135.22|ceil:3} {* gibt 135.22 *} +{=3.4|ceil} {* gibt 4 aus *} +{=135.22|ceil:1} {* gibt 135.3 aus *} +{=135.22|ceil:3} {* gibt 135.22 aus *} ``` -Siehe auch [Stockwerk |#floor], [Runden |#round]. +Siehe auch [#floor], [#round]. capitalize .[filter] -------------------- -Gibt eine Version des Wertes in Großbuchstaben zurück. Die Wörter beginnen mit Großbuchstaben, alle übrigen Zeichen sind Kleinbuchstaben. Erfordert die PHP-Erweiterung `mbstring`. +Wörter beginnen mit Großbuchstaben, alle verbleibenden Zeichen sind klein. Erfordert die PHP-Erweiterung `mbstring`. ```latte -{='i like LATTE'|capitalize} {* gibt 'I Like Latte' *} +{='i like LATTE'|capitalize} {* gibt 'I Like Latte' aus *} ``` -Siehe auch [firstUpper |#firstUpper], [lower |#lower], [upper |#upper]. +Siehe auch [#firstUpper], [#lower], [#upper]. checkUrl .[filter] ------------------ -Erzwingt URL-Sanitization. Sie prüft, ob die Variable eine Web-URL enthält (d. h. HTTP/HTTPS-Protokoll) und verhindert das Schreiben von Links, die ein Sicherheitsrisiko darstellen könnten. +Erzwingt die Behandlung einer URL-Adresse. Überprüft, ob die Variable eine Web-URL enthält (d.h. HTTP/HTTPS-Protokoll) und verhindert die Ausgabe von Links, die ein Sicherheitsrisiko darstellen können. ```latte {var $link = 'javascript:window.close()'} -checked -unchecked +geprüft +ungeprüft ``` -Druckt: +Gibt aus: ```latte -checked -unchecked +geprüft +ungeprüft ``` -Siehe auch [nocheck |#nocheck]. +Siehe auch [#nocheck]. clamp(int|float min, int|float max) .[filter] --------------------------------------------- -Gibt einen Wert zurück, der auf den einschließenden Bereich von min und max geklemmt ist. +Begrenzt einen Wert auf den angegebenen inklusiven Bereich von min und max. ```latte {$level|clamp: 0, 255} @@ -234,15 +234,15 @@ Existiert auch als [Funktion |functions#clamp]. dataStream(string mimetype = detect) .[filter] ---------------------------------------------- -Konvertiert den Inhalt in ein Daten-URI-Schema. Es kann verwendet werden, um Bilder in HTML oder CSS einzufügen, ohne dass externe Dateien verlinkt werden müssen. +Konvertiert den Inhalt in das Data URI-Schema. Damit können Bilder ohne die Notwendigkeit externer Dateien in HTML oder CSS eingebettet werden. -Nehmen wir an, ein Bild befindet sich in einer Variablen `$img = Image::fromFile('obrazek.gif')`, dann +Angenommen, wir haben ein Bild in der Variable `$img = Image::fromFile('bild.gif')`, dann ```latte ``` -Druckt zum Beispiel: +Gibt beispielsweise aus: ```latte {$name} ``` -Siehe auch [Abfrage |#query]. +Siehe auch [#query]. explode(string separator = '') .[filter] ---------------------------------------- -Teilt eine Zeichenkette durch den angegebenen Begrenzer und gibt ein Array von Zeichenketten zurück. Alias für `split`. +Teilt eine Zeichenkette anhand eines Trennzeichens in ein Array. Alias für `split`. ```latte -{='one,two,three'|explode:','} {* liefert ['one', 'two', 'three'] *} +{='one,two,three'|explode:','} {* gibt ['one', 'two', 'three'] zurück *} ``` Wenn das Trennzeichen eine leere Zeichenkette ist (Standardwert), wird die Eingabe in einzelne Zeichen aufgeteilt: ```latte -{='123'|explode} {* liefert ['1', '2', '3'] *} +{='123'|explode} {* gibt ['1', '2', '3'] zurück *} ``` Sie können auch den Alias `split` verwenden: ```latte -{='1,2,3'|split:','} {* liefert ['1', '2', '3'] *} +{='1,2,3'|split:','} {* gibt ['1', '2', '3'] zurück *} ``` -Siehe auch [implode |#implode]. +Siehe auch [#implode]. first .[filter] --------------- -Gibt das erste Element eines Arrays oder ein Zeichen einer Zeichenkette zurück: +Gibt das erste Element eines Arrays oder das erste Zeichen einer Zeichenkette zurück: ```latte -{=[1, 2, 3, 4]|first} {* gibt 1 *} -{='abcd'|first} {* gibt 'a' *} +{=[1, 2, 3, 4]|first} {* gibt 1 aus *} +{='abcd'|first} {* gibt 'a' aus *} ``` -Siehe auch [last |#last], [random |#random]. +Siehe auch [#last], [#random]. floor(int precision = 0) .[filter] @@ -316,30 +316,30 @@ floor(int precision = 0) .[filter] Rundet eine Zahl auf eine bestimmte Genauigkeit ab. ```latte -{=3.5|floor} {* gibt 3 *} -{=135.79|floor:1} {* gibt 135.7 *} -{=135.79|floor:3} {* gibt 135.79 *} +{=3.5|floor} {* gibt 3 aus *} +{=135.79|floor:1} {* gibt 135.7 aus *} +{=135.79|floor:3} {* gibt 135.79 aus *} ``` -Siehe auch [ceil |#ceil], [round |#round]. +Siehe auch [#ceil], [#round]. firstUpper .[filter] -------------------- -Konvertiert den ersten Buchstaben eines Wertes in Großbuchstaben. Erfordert die PHP-Erweiterung `mbstring`. +Konvertiert den ersten Buchstaben in einen Großbuchstaben. Erfordert die PHP-Erweiterung `mbstring`. ```latte -{='the latte'|firstUpper} {* gibt 'The latte' *} +{='the latte'|firstUpper} {* gibt 'The latte' aus *} ``` -Siehe auch [capitalize |#capitalize], [lower |#lower], [upper |#upper]. +Siehe auch [#capitalize], [#lower], [#upper]. group(string|int|\Closure by): array .[filter]{data-version:3.0.16} ------------------------------------------------------------------- -Der Filter gruppiert die Daten nach verschiedenen Kriterien. +Filter, der Daten nach verschiedenen Kriterien gruppiert. -In diesem Beispiel werden die Zeilen in der Tabelle nach der Spalte `categoryId` gruppiert. Die Ausgabe ist ein Array von Arrays, wobei der Schlüssel der Wert in der Spalte `categoryId` ist. Lesen Sie die [ausführliche Anleitung |cookbook/grouping]. +In diesem Beispiel werden die Tabellenzeilen nach der Spalte `categoryId` gruppiert. Die Ausgabe ist ein Array von Arrays, wobei der Schlüssel der Wert in der Spalte `categoryId` ist. [Lesen Sie die detaillierte Anleitung |cookbook/grouping]. ```latte {foreach ($items|group: categoryId) as $categoryId => $categoryItems} @@ -351,28 +351,28 @@ In diesem Beispiel werden die Zeilen in der Tabelle nach der Spalte `categoryId` {/foreach} ``` -Siehe auch [Batch |#batch], die [Gruppenfunktion |functions#group] und das [iterateWhile-Tag |tags#iterateWhile]. +Siehe auch [#batch], die Funktion [group |functions#group] und das Tag [iterateWhile |tags#iterateWhile]. implode(string glue = '') .[filter] ----------------------------------- -Gibt eine Zeichenkette zurück, die die Verkettung der Zeichenketten im Array ist. Alias für `join`. +Gibt eine Zeichenkette zurück, die eine Verkettung der Elemente einer Sequenz ist. Alias für `join`. ```latte -{=[1, 2, 3]|implode} {* gibt '123' *} -{=[1, 2, 3]|implode:'|'} {* gibt '1|2|3' *} +{=[1, 2, 3]|implode} {* gibt '123' aus *} +{=[1, 2, 3]|implode:'|'} {* gibt '1|2|3' aus *} ``` -Sie können auch einen Alias `join` verwenden: +Sie können auch den Alias `join` verwenden: ```latte -{=[1, 2, 3]|join} {* gibt '123' *} +{=[1, 2, 3]|join} {* gibt '123' aus *} ``` indent(int level = 1, string char = "\t") .[filter] --------------------------------------------------- -Rückt einen Text von links um eine bestimmte Anzahl von Tabulatoren oder anderen Zeichen ein, die wir im zweiten optionalen Argument angeben. Leerzeilen werden nicht eingerückt. +Rückt Text von links um eine bestimmte Anzahl von Tabulatoren oder anderen Zeichen ein, die im zweiten Argument angegeben werden können. Leere Zeilen werden nicht eingerückt. ```latte
@@ -382,7 +382,7 @@ Rückt einen Text von links um eine bestimmte Anzahl von Tabulatoren oder andere
``` -Druckt: +Gibt aus: ```latte
@@ -393,24 +393,24 @@ Druckt: last .[filter] -------------- -Gibt das letzte Element eines Arrays oder ein Zeichen einer Zeichenkette zurück: +Gibt das letzte Element eines Arrays oder das letzte Zeichen einer Zeichenkette zurück: ```latte -{=[1, 2, 3, 4]|last} {* gibt 4 *} -{='abcd'|last} {* gibt 'd' *} +{=[1, 2, 3, 4]|last} {* gibt 4 aus *} +{='abcd'|last} {* gibt 'd' aus *} ``` -Siehe auch [first |#first], [random |#random]. +Siehe auch [#first], [#random]. length .[filter] ---------------- Gibt die Länge einer Zeichenkette oder eines Arrays zurück. -- bei Strings wird die Länge in UTF-8 Zeichen zurückgegeben -- für Arrays wird die Anzahl der Elemente zurückgegeben -- bei Objekten, die die Schnittstelle Countable implementieren, wird der Rückgabewert der Funktion count() verwendet -- für Objekte, die die Schnittstelle IteratorAggregate implementieren, wird der Rückgabewert von iterator_count() verwendet. +- für Zeichenketten gibt es die Länge in UTF-8-Zeichen zurück +- für Arrays gibt es die Anzahl der Elemente zurück +- für Objekte, die das Countable-Interface implementieren, verwendet es den Rückgabewert der count()-Methode +- für Objekte, die das IteratorAggregate-Interface implementieren, verwendet es den Rückgabewert der iterator_count()-Funktion ```latte @@ -422,28 +422,28 @@ Gibt die Länge einer Zeichenkette oder eines Arrays zurück. localDate(string format = null, string date = null, string time = null) .[filter] --------------------------------------------------------------------------------- -Formatiert Datum und Uhrzeit entsprechend dem [Gebietsschema |develop#locale], um eine konsistente und lokalisierte Anzeige von Zeitdaten in verschiedenen Sprachen und Regionen zu gewährleisten. Der Filter akzeptiert das Datum als UNIX-Zeitstempel, String oder `DateTimeInterface` Objekt. +Formatiert Datum und Uhrzeit gemäß den [Ländereinstellungen |develop#locale], was eine konsistente und lokalisierte Darstellung von Zeitangaben in verschiedenen Sprachen und Regionen gewährleistet. Der Filter akzeptiert ein Datum als UNIX-Timestamp, Zeichenkette oder Objekt vom Typ `DateTimeInterface`. ```latte -{$date|localDate} {* 15. dubna 2024 *} +{$date|localDate} {* 15. April 2024 *} {$date|format: yM} {* 4/2024 *} {$date|localDate: date: medium} {* 15. 4. 2024 *} ``` -Wenn Sie den Filter ohne Parameter verwenden, gibt er das Datum in der Langformatebene aus, wie weiter unten erläutert. +Wenn Sie den Filter ohne Parameter verwenden, wird das Datum auf der Ebene `long` ausgegeben, siehe unten. **a) Verwendung des Formats** -Der Parameter `format` beschreibt, welche Zeitkomponenten angezeigt werden sollen. Er verwendet Buchstabencodes, wobei die Anzahl der Wiederholungen die Breite der Ausgabe beeinflusst: +Der Parameter `format` beschreibt, welche Zeitkomponenten angezeigt werden sollen. Es verwendet Buchstabencodes dafür, deren Wiederholungsanzahl die Breite der Ausgabe beeinflusst: | Jahr | `y` / `yy` / `yyyy` | `2024` / `24` / `2024` | Monat | `M` / `MM` / `MMM` / `MMMM` | `8` / `08` / `Aug` / `August` -| Tag | `d` / `dd` / `E` / `EEEE` | `1` / `01` / `So` / `Sonntag` -| Stunde | `j` / `H` / `h` | bevorzugt / 24 Stunden / 12 Stunden -| Minute | `m` / `mm` | `5` / `05` (2-stellig, wenn mit Sekunden kombiniert) -| Sekunde | `s` / `ss` | `8` / `08` (2 Ziffern, wenn mit Minuten kombiniert) +| Tag | `d` / `dd` / `E` / `EEEE` | `1` / `01` / `So` / `Sonntag` +| Stunde | `j` / `H` / `h` | bevorzugt / 24-Stunden / 12-Stunden +| Minute | `m` / `mm` | `5` / `05` (2 Ziffern in Kombination mit Sekunden) +| Sekunde | `s` / `ss` | `8` / `08` (2 Ziffern in Kombination mit Minuten) -Die Reihenfolge der Codes im Format spielt keine Rolle, da die Reihenfolge der Komponenten entsprechend den Konventionen des jeweiligen Gebietsschemas angezeigt wird. Daher ist das Format ortsunabhängig. Zum Beispiel gibt das Format `yyyyMMMMd` im Gebietsschema `en_US` `April 15, 2024` aus, während es im Gebietsschema `cs_CZ` `15. dubna 2024` ausgibt: +Die Reihenfolge der Codes im Format spielt keine Rolle, da die Reihenfolge der Komponenten gemäß den Konventionen der Ländereinstellungen ausgegeben wird. Das Format ist also unabhängig davon. Zum Beispiel wird das Format `yyyyMMMMd` in der Umgebung `en_US` als `April 15, 2024` ausgegeben, während es in der Umgebung `de_DE` als `15. April 2024` ausgegeben wird: | locale: | de-DE | en_US |--- @@ -456,9 +456,9 @@ Die Reihenfolge der Codes im Format spielt keine Rolle, da die Reihenfolge der K | `format: 'hm'` | 5:54 PM | 5:54 PM -**b) Verwendung voreingestellter Stile** +**b) Verwendung vordefinierter Stile** -Die Parameter `date` und `time` bestimmen den Detaillierungsgrad der Datums- und Zeitanzeige. Sie können aus mehreren Stufen wählen: `full`, `long`, `medium`, `short`. Sie können nur das Datum, nur die Uhrzeit oder beides anzeigen lassen: +Die Parameter `date` und `time` bestimmen, wie detailliert Datum und Uhrzeit ausgegeben werden sollen. Sie können aus mehreren Ebenen wählen: `full`, `long`, `medium`, `short`. Es ist möglich, nur das Datum, nur die Uhrzeit oder beides ausgeben zu lassen: | locale: | de-DE | en_US |--- @@ -473,52 +473,52 @@ Die Parameter `date` und `time` bestimmen den Detaillierungsgrad der Datums- und | `date: medium, time: short` | 23.01.1978, 08:30 | Jan 23, 1978, 8:30 AM | `date: long, time: short` | 23. Januar 1978 um 08:30 | January 23, 1978 at 8:30 AM -Für das Datum können Sie auch das Präfix `relative-` verwenden (z. B. `relative-short`), das für Daten, die kurz vor der Gegenwart liegen, `yesterday`, `today` oder `tomorrow` anzeigt; andernfalls erfolgt die Anzeige auf die übliche Weise. +Für das Datum können Sie außerdem das Präfix `relative-` verwenden (z.B. `relative-short`), das für Daten nahe der Gegenwart `gestern`, `heute` oder `morgen` anzeigt, andernfalls wird es auf die Standardweise ausgegeben. ```latte -{$date|localDate: date: relative-short} {* yesterday *} +{$date|localDate: date: relative-short} {* gestern *} ``` -Siehe auch [Datum |#date]. +Siehe auch [#date]. lower .[filter] --------------- -Konvertiert einen Wert in Kleinbuchstaben. Erfordert die PHP-Erweiterung `mbstring`. +Konvertiert eine Zeichenkette in Kleinbuchstaben. Erfordert die PHP-Erweiterung `mbstring`. ```latte -{='LATTE'|lower} {* gibt 'latte' *} +{='LATTE'|lower} {* gibt 'latte' aus *} ``` -Siehe auch [capitalize |#capitalize], [firstUpper |#firstUpper], [upper |#upper]. +Siehe auch [#capitalize], [#firstUpper], [#upper]. nocheck .[filter] ----------------- -Verhindert die automatische URL-Sanitization. Latte [prüft automatisch |safety-first#Link checking], ob die Variable eine Web-URL enthält (d.h. HTTP/HTTPS-Protokoll) und verhindert das Schreiben von Links, die ein Sicherheitsrisiko darstellen könnten. +Verhindert die automatische Behandlung einer URL-Adresse. Latte [überprüft automatisch |safety-first#Link checking], ob die Variable eine Web-URL enthält (d.h. HTTP/HTTPS-Protokoll) und verhindert die Ausgabe von Links, die ein Sicherheitsrisiko darstellen können. -Wenn der Link ein anderes Schema verwendet, z. B. `javascript:` oder `data:`, und Sie sich des Inhalts sicher sind, können Sie die Prüfung über `|nocheck` deaktivieren. +Wenn der Link ein anderes Schema verwendet, z.B. `javascript:` oder `data:`, und Sie sich seines Inhalts sicher sind, können Sie die Überprüfung mit `|nocheck` deaktivieren. ```latte {var $link = 'javascript:window.close()'} -checked -unchecked +geprüft +ungeprüft ``` -Drucke: +Gibt aus: ```latte -checked -unchecked +geprüft +ungeprüft ``` -Siehe auch [checkUrl |#checkUrl]. +Siehe auch [#checkUrl]. noescape .[filter] ------------------ -Deaktiviert das automatische Escaping. +Deaktiviert automatisches Escaping. ```latte {var $trustedHtmlString = 'hello'} @@ -526,7 +526,7 @@ Escaped: {$trustedHtmlString} Unescaped: {$trustedHtmlString|noescape} ``` -Druckt: +Gibt aus: ```latte Escaped: <b>hello</b> @@ -534,33 +534,33 @@ Unescaped: hello ``` .[warning] -Die missbräuchliche Verwendung des `noescape` Filters kann zu einer XSS-Schwachstelle führen! Verwenden Sie ihn nur, wenn Sie **absolut sicher** sind, was Sie tun und dass die Zeichenfolge, die Sie drucken, aus einer vertrauenswürdigen Quelle stammt. +Falsche Verwendung des `noescape`-Filters kann zu XSS-Schwachstellen führen! Verwenden Sie ihn niemals, wenn Sie nicht **absolut sicher** sind, was Sie tun, und dass die ausgegebene Zeichenkette aus einer vertrauenswürdigen Quelle stammt. number(int decimals = 0, string decPoint = '.', string thousandsSep = ',') .[filter] ------------------------------------------------------------------------------------ -Formatiert eine Zahl mit einer bestimmten Anzahl von Dezimalstellen. Wenn das [Gebietsschema |develop#locale] festgelegt ist, werden die entsprechenden Dezimal- und Tausendertrennzeichen verwendet. +Formatiert eine Zahl auf eine bestimmte Anzahl von Dezimalstellen. Wenn [Ländereinstellungen |develop#locale] gesetzt sind, werden die entsprechenden Dezimal- und Tausendertrennzeichen verwendet. ```latte -{1234.20 |number} 1,234 -{1234.20 |number:1} 1,234.2 -{1234.20 |number:2} 1,234.20 -{1234.20 |number:2, ',', ' '} 1 234,20 +{1234.20|number} 1,234 +{1234.20|number:1} 1,234.2 +{1234.20|number:2} 1,234.20 +{1234.20|number:2, ',', ' '} 1 234,20 ``` number(string format) .[filter] ------------------------------- -Mit dem Parameter `format` können Sie das Aussehen von Zahlen genau nach Ihren Bedürfnissen festlegen. Er erfordert ein festgelegtes [Gebietsschema |develop#locale]. Das Format besteht aus mehreren Sonderzeichen, deren vollständige Beschreibung in der Dokumentation "DecimalFormat":https://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns zu finden ist: +Der Parameter `format` ermöglicht es Ihnen, das Aussehen von Zahlen genau nach Ihren Bedürfnissen zu definieren. Dafür müssen [Ländereinstellungen |develop#locale] gesetzt sein. Das Format besteht aus mehreren speziellen Zeichen, deren vollständige Beschreibung Sie in der Dokumentation "DecimalFormat":https://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns finden: -- obligatorische Ziffer, wird immer angezeigt, auch wenn sie Null ist -- `#` optionale Ziffer, wird nur angezeigt, wenn die Zahl eine Ziffer an dieser Stelle hat -- `@` signifikante Ziffer, hilft bei der Anzeige der Zahl mit einer bestimmten Anzahl signifikanter Ziffern -- `.` markiert die Stelle, an der das Dezimaltrennzeichen stehen soll (Komma oder Punkt, je nach Gebietsschema) -- `,` wird verwendet, um Gruppen von Ziffern zu trennen, normalerweise Tausender +- `0` obligatorische Ziffer, wird immer angezeigt, auch wenn es eine Null ist +- `#` optionale Ziffer, wird nur angezeigt, wenn an dieser Stelle tatsächlich eine Zahl steht +- `@` signifikante Ziffer, hilft, eine Zahl mit einer bestimmten Anzahl gültiger Ziffern anzuzeigen +- `.` kennzeichnet, wo das Dezimalkomma (oder -punkt, je nach Land) sein soll +- `,` dient zur Trennung von Zifferngruppen, meist Tausender - `%` multipliziert die Zahl mit 100 und fügt das Prozentzeichen hinzu -Schauen wir uns einige Beispiele an. Im ersten Beispiel sind zwei Dezimalstellen obligatorisch, im zweiten sind sie optional. Das dritte Beispiel zeigt Auffüllungen mit Nullen auf beiden Seiten, und das vierte Beispiel zeigt nur die vorhandenen Ziffern an: +Schauen wir uns einige Beispiele an. Im ersten Beispiel sind zwei Dezimalstellen obligatorisch, im zweiten optional. Das dritte Beispiel zeigt das Auffüllen mit Nullen links und rechts, das vierte zeigt nur existierende Ziffern: ```latte {1234.5|number: '#,##0.00'} {* 1,234.50 *} @@ -569,7 +569,7 @@ Schauen wir uns einige Beispiele an. Im ersten Beispiel sind zwei Dezimalstellen {1.2 |number: '##.##'} {* 1.2 *} ``` -Signifikante Ziffern legen fest, wie viele Ziffern, unabhängig vom Dezimalpunkt, angezeigt werden sollen, wobei die Zahl gegebenenfalls gerundet wird: +Signifikante Ziffern bestimmen, wie viele Ziffern unabhängig vom Dezimalpunkt angezeigt werden sollen, wobei gerundet wird: ```latte {1234|number: '@@'} {* 1200 *} @@ -579,13 +579,13 @@ Signifikante Ziffern legen fest, wie viele Ziffern, unabhängig vom Dezimalpunkt {0.00123|number: '@@'} {* 0.0012 *} ``` -Eine einfache Möglichkeit, eine Zahl als Prozentsatz anzuzeigen. Die Zahl wird mit 100 multipliziert und das Zeichen `%` wird hinzugefügt: +Ein einfacher Weg, eine Zahl als Prozentsatz anzuzeigen. Die Zahl wird mit 100 multipliziert und das `%`-Zeichen wird hinzugefügt: ```latte {0.1234|number: '#.##%'} {* 12.34% *} ``` -Wir können ein unterschiedliches Format für positive und negative Zahlen definieren, die durch ein `;` Zeichen getrennt sind. Auf diese Weise können z. B. positive Zahlen mit einem `+` -Zeichen angezeigt werden: +Wir können unterschiedliche Formate für positive und negative Zahlen definieren, getrennt durch ein `;`-Zeichen. Auf diese Weise können wir zum Beispiel festlegen, dass positive Zahlen mit einem `+`-Zeichen angezeigt werden sollen: ```latte {42|number: '#.##;(#.##)'} {* 42 *} @@ -594,140 +594,140 @@ Wir können ein unterschiedliches Format für positive und negative Zahlen defin {-42|number: '+#.##;-#.##'} {* -42 *} ``` -Denken Sie daran, dass das tatsächliche Aussehen von Zahlen je nach den Einstellungen des Gebietsschemas variieren kann. In einigen Ländern wird zum Beispiel ein Komma anstelle eines Punktes als Dezimaltrennzeichen verwendet. Dieser Filter berücksichtigt dies automatisch, so dass Sie sich darüber keine Gedanken machen müssen. +Beachten Sie, dass das tatsächliche Aussehen der Zahlen je nach den Ländereinstellungen variieren kann. In einigen Ländern wird beispielsweise ein Komma statt eines Punkts als Dezimaltrennzeichen verwendet. Dieser Filter berücksichtigt dies automatisch, und Sie müssen sich um nichts kümmern. padLeft(int length, string pad = ' ') .[filter] ----------------------------------------------- -Füllt eine Zeichenkette bis zu einer bestimmten Länge mit einer anderen Zeichenkette von links auf. +Füllt eine Zeichenkette auf eine bestimmte Länge mit einer anderen Zeichenkette von links auf. ```latte -{='hello'|padLeft: 10, '123'} {* gibt '12312hello' *} +{='hello'|padLeft: 10, '123'} {* gibt '12312hello' aus *} ``` padRight(int length, string pad = ' ') .[filter] ------------------------------------------------ -Füllt eine Zeichenfolge auf eine bestimmte Länge mit einer anderen Zeichenfolge von rechts. +Füllt eine Zeichenkette auf eine bestimmte Länge mit einer anderen Zeichenkette von rechts auf. ```latte -{='hello'|padRight: 10, '123'} {* gibt 'hello12312' *} +{='hello'|padRight: 10, '123'} {* gibt 'hello12312' aus *} ``` -query .[filter] ----------------- -Erzeugt dynamisch eine Abfragezeichenfolge in der URL: +query .[filter] +--------------- +Generiert dynamisch einen Query-String in einer URL: ```latte -click -search +klicken +suchen ``` -Druckt: +Gibt aus: ```latte -click -search +klicken +suchen ``` -Tasten mit einem Wert von `null` werden ausgelassen. +Schlüssel mit dem Wert `null` werden weggelassen. -Siehe auch [escapeUrl |#escapeUrl]. +Siehe auch [#escapeUrl]. random .[filter] ---------------- -Gibt ein zufälliges Element eines Arrays oder ein Zeichen einer Zeichenkette zurück: +Gibt ein zufälliges Element eines Arrays oder ein zufälliges Zeichen einer Zeichenkette zurück: ```latte -{=[1, 2, 3, 4]|random} {* example output: 3 *} -{='abcd'|random} {* example output: 'b' *} +{=[1, 2, 3, 4]|random} {* gibt z.B.: 3 aus *} +{='abcd'|random} {* gibt z.B.: 'b' aus *} ``` -Siehe auch [first |#first], [last |#last]. +Siehe auch [#first], [#last]. repeat(int count) .[filter] --------------------------- -Wiederholt die Zeichenkette x-mal. +Wiederholt eine Zeichenkette x-mal. ```latte -{='hello'|repeat: 3} {* gibt 'hellohellohello' *} +{='hello'|repeat: 3} {* gibt 'hellohellohello' aus *} ``` replace(string|array search, string replace = '') .[filter] ----------------------------------------------------------- -Ersetzt alle Vorkommen der Suchzeichenfolge durch die Ersatzzeichenfolge. +Ersetzt alle Vorkommen der Suchzeichenkette durch die Ersatzzeichenkette. ```latte -{='hello world'|replace: 'world', 'friend'} {* gibt 'hello friend' *} +{='hello world'|replace: 'world', 'friend'} {* gibt 'hello friend' aus *} ``` -Es können mehrere Ersetzungen auf einmal vorgenommen werden: +Es können auch mehrere Ersetzungen auf einmal durchgeführt werden: ```latte -{='hello world'|replace: [h => l, l => h]} {* gibt 'lehho worhd' *} +{='hello world'|replace: [h => l, l => h]} {* gibt 'lehho worhd' aus *} ``` replaceRE(string pattern, string replace = '') .[filter] -------------------------------------------------------- -Ersetzt alle Vorkommen entsprechend dem regulären Ausdruck. +Führt eine Suche und Ersetzung mit regulären Ausdrücken durch. ```latte -{='hello world'|replaceRE: '/l.*/', 'l'} {* gibt 'hel' *} +{='hello world'|replaceRE: '/l.*/', 'l'} {* gibt 'hel' aus *} ``` reverse .[filter] ----------------- -Kehrt eine gegebene Zeichenkette oder ein gegebenes Array um. +Kehrt die gegebene Zeichenkette oder das Array um. ```latte {var $s = 'Nette'} -{$s|reverse} {* gibt 'etteN' *} +{$s|reverse} {* gibt 'etteN' aus *} {var $a = ['N', 'e', 't', 't', 'e']} -{$a|reverse} {* liefert ['e', 't', 't', 'e', 'N'] *} +{$a|reverse} {* gibt ['e', 't', 't', 'e', 'N'] zurück *} ``` round(int precision = 0) .[filter] ---------------------------------- -Rundet eine Zahl auf eine bestimmte Genauigkeit. +Rundet eine Zahl auf die angegebene Genauigkeit. ```latte -{=3.4|round} {* gibt 3 *} -{=3.5|round} {* gibt 4 *} -{=135.79|round:1} {* gibt 135.8 *} -{=135.79|round:3} {* gibt 135.79 *} +{=3.4|round} {* gibt 3 aus *} +{=3.5|round} {* gibt 4 aus *} +{=135.79|round:1} {* gibt 135.8 aus *} +{=135.79|round:3} {* gibt 135.79 aus *} ``` -Siehe auch [ceil |#ceil], [floor |#floor]. +Siehe auch [#ceil], [#floor]. slice(int start, int length = null, bool preserveKeys = false) .[filter] ------------------------------------------------------------------------ -Extrahiert einen Ausschnitt aus einem Array oder einer Zeichenkette. +Extrahiert einen Teil eines Arrays oder einer Zeichenkette. ```latte -{='hello'|slice: 1, 2} {* gibt 'el' *} -{=['a', 'b', 'c']|slice: 1, 2} {* gibt ['b', 'c'] *} +{='hello'|slice: 1, 2} {* gibt 'el' aus *} +{=['a', 'b', 'c']|slice: 1, 2} {* gibt ['b', 'c'] aus *} ``` -Der Slice-Filter funktioniert wie die PHP-Funktion `array_slice` für Arrays und `mb_substr` für Strings mit einem Fallback auf `iconv_substr` im UTF-8-Modus. +Der Filter funktioniert wie die PHP-Funktion `array_slice` für Arrays oder `mb_substr` für Zeichenketten mit Fallback auf die Funktion `iconv_substr` im UTF-8-Modus. -Wenn start nicht negativ ist, beginnt die Sequenz an diesem Anfang in der Variablen. Wenn start negativ ist, beginnt die Sequenz so weit vom Ende der Variablen entfernt. +Wenn start positiv ist, beginnt die Sequenz um diese Anzahl vom Anfang des Arrays/der Zeichenkette verschoben. Wenn es negativ ist, beginnt die Sequenz um diese Anzahl vom Ende verschoben. -Wenn length angegeben wird und positiv ist, wird die Sequenz bis zu dieser Anzahl von Elementen enthalten. Wenn die Variable kürzer als die Länge ist, werden nur die verfügbaren Elemente der Variablen angezeigt. Wenn length angegeben wird und negativ ist, endet die Sequenz so viele Elemente vor dem Ende der Variablen. Wird sie weggelassen, enthält die Sequenz alle Elemente vom Offset bis zum Ende der Variablen. +Wenn der Parameter length angegeben und positiv ist, enthält die Sequenz so viele Elemente. Wenn ein negativer length-Parameter an diese Funktion übergeben wird, enthält die Sequenz alle Elemente des ursprünglichen Arrays, beginnend an der Position start und endend an der Position, die um length Elemente vom Ende des Arrays entfernt ist. Wenn Sie diesen Parameter weglassen, enthält die Sequenz alle Elemente des ursprünglichen Arrays, beginnend an der Position start. -Filter ordnet die Schlüssel des Integer-Arrays standardmäßig neu an und setzt sie zurück. Dieses Verhalten kann geändert werden, indem preserveKeys auf true gesetzt wird. String-Schlüssel werden immer beibehalten, unabhängig von diesem Parameter. +Standardmäßig ändert der Filter die Reihenfolge und setzt die ganzzahligen Schlüssel des Arrays zurück. Dieses Verhalten kann geändert werden, indem preserveKeys auf true gesetzt wird. String-Schlüssel werden immer beibehalten, unabhängig von diesem Parameter. sort(?Closure comparison, string|int|\Closure|null by=null, string|int|\Closure|bool byKey=false) .[filter] ----------------------------------------------------------------------------------------------------------- -Der Filter sortiert Elemente eines Arrays oder Iterators unter Beibehaltung ihrer assoziativen Schlüssel. Wenn ein [Gebietsschema |develop#locale] festgelegt ist, folgt die Sortierung dessen Regeln, es sei denn, eine benutzerdefinierte Vergleichsfunktion ist angegeben. +Der Filter sortiert die Elemente eines Arrays oder Iterators und behält ihre assoziativen Schlüssel bei. Bei gesetzten [Ländereinstellungen |develop#locale] folgt die Sortierung deren Regeln, wenn keine eigene Vergleichsfunktion angegeben ist. ```latte {foreach ($names|sort) as $name} @@ -735,7 +735,7 @@ Der Filter sortiert Elemente eines Arrays oder Iterators unter Beibehaltung ihre {/foreach} ``` -Array in umgekehrter Reihenfolge sortiert. +Sortiertes Array in umgekehrter Reihenfolge: ```latte {foreach ($names|sort|reverse) as $name} @@ -743,13 +743,13 @@ Array in umgekehrter Reihenfolge sortiert. {/foreach} ``` -Sie können eine benutzerdefinierte Vergleichsfunktion für die Sortierung angeben (das Beispiel zeigt, wie Sie die Sortierung von der größten zur kleinsten umkehren können): +Sie können eine eigene Vergleichsfunktion für die Sortierung angeben (das Beispiel zeigt, wie die Sortierung von größter zu kleinster umgekehrt wird): ```latte {var $reverted = ($names|sort: fn($a, $b) => $b <=> $a)} ``` -Mit dem Filter `|sort` können Sie auch Elemente nach Schlüssel sortieren: +Der Filter `|sort` ermöglicht auch die Sortierung von Elementen nach Schlüsseln: ```latte {foreach ($names|sort: byKey: true) as $name} @@ -757,7 +757,7 @@ Mit dem Filter `|sort` können Sie auch Elemente nach Schlüssel sortieren: {/foreach} ``` -Wenn Sie eine Tabelle nach einer bestimmten Spalte sortieren müssen, können Sie den Parameter `by` verwenden. Der Wert `'name'` im Beispiel gibt an, dass die Sortierung nach `$row->name` oder `$row['name']`erfolgt, je nachdem, ob `$row` ein Array oder ein Objekt ist: +Wenn Sie eine Tabelle nach einer bestimmten Spalte sortieren müssen, können Sie den Parameter `by` verwenden. Der Wert `'name'` im Beispiel gibt an, dass nach `$item->name` oder `$item['name']` sortiert wird, je nachdem, ob `$item` ein Array oder ein Objekt ist: ```latte {foreach ($items|sort: by: 'name') as $item} @@ -765,7 +765,7 @@ Wenn Sie eine Tabelle nach einer bestimmten Spalte sortieren müssen, können Si {/foreach} ``` -Sie können auch eine Callback-Funktion definieren, die den Wert bestimmt, nach dem sortiert wird: +Sie können auch eine Callback-Funktion definieren, die den Wert bestimmt, nach dem sortiert werden soll: ```latte {foreach ($items|sort: by: fn($items) => $items->category->name) as $item} @@ -773,12 +773,12 @@ Sie können auch eine Callback-Funktion definieren, die den Wert bestimmt, nach {/foreach} ``` -Der Parameter `byKey` kann auf dieselbe Weise verwendet werden. +Der Parameter `byKey` kann auf die gleiche Weise verwendet werden. -spaceless .[filter] --------------------- -Entfernt unnötige Leerzeichen aus der Ausgabe. Sie können auch den Alias `strip` verwenden. +spaceless .[filter] +------------------- +Entfernt überflüssige Leerzeichen aus der Ausgabe. Sie können auch den Alias `strip` verwenden. ```latte {block |spaceless} @@ -788,7 +788,7 @@ Entfernt unnötige Leerzeichen aus der Ausgabe. Sie können auch den Alias `stri {/block} ``` -Druckt: +Gibt aus: ```latte
  • Hello
@@ -797,18 +797,18 @@ Druckt: stripHtml .[filter] ------------------- -Konvertiert HTML in einfachen Text. Das heißt, es werden HTML-Tags entfernt und HTML-Elemente in Text umgewandelt. +Konvertiert HTML in reinen Text. Das heißt, es entfernt HTML-Tags und konvertiert HTML-Entities in Text. ```latte -{='

one < two

'|stripHtml} {* gibt 'one < two' *} +{='

one < two

'|stripHtml} {* gibt 'one < two' aus *} ``` -Der resultierende reine Text kann natürlich Zeichen enthalten, die HTML-Tags darstellen, zum Beispiel wird `'<p>'|stripHtml` in `

`. Geben Sie den resultierenden Text niemals mit `|noescape` aus, da dies zu einer Sicherheitslücke führen kann. +Der resultierende reine Text kann natürlich Zeichen enthalten, die HTML-Tags darstellen, zum Beispiel wird `'<p>'|stripHtml` zu `

` konvertiert. Geben Sie den so erzeugten Text auf keinen Fall mit `|noescape` aus, da dies zu einer Sicherheitslücke führen kann. substr(int offset, int length = null) .[filter] ----------------------------------------------- -Extrahiert einen Ausschnitt aus einer Zeichenkette. Dieser Filter wurde durch einen [Slice-Filter |#slice] ersetzt. +Extrahiert einen Teil einer Zeichenkette. Dieser Filter wurde durch den Filter [#slice] ersetzt. ```latte {$string|substr: 1, 2} @@ -817,57 +817,57 @@ Extrahiert einen Ausschnitt aus einer Zeichenkette. Dieser Filter wurde durch ei translate(string message, ...args) .[filter] -------------------------------------------- -Er übersetzt Ausdrücke in andere Sprachen. Um den Filter verfügbar zu machen, müssen Sie den [Übersetzer ein richten|develop#TranslatorExtension]. Sie können auch die [Tags für die Übersetzung |tags#Translation] verwenden. +Übersetzt Ausdrücke in andere Sprachen. Damit der Filter verfügbar ist, muss ein [Übersetzer eingerichtet |develop#TranslatorExtension] sein. Sie können auch [Tags für Übersetzungen |tags#Translation] verwenden. ```latte -{='Baskter'|translate} +{='Cart'|translate} {$item|translate} ``` trim(string charlist = " \t\n\r\0\x0B\u{A0}") .[filter] ------------------------------------------------------- -Entfernen Sie führende und nachgestellte Zeichen, standardmäßig Leerzeichen. +Entfernt Leerzeichen (oder andere Zeichen) vom Anfang und Ende einer Zeichenkette. ```latte -{=' I like Latte. '|trim} {* gibt 'I like Latte.' *} -{=' I like Latte.'|trim: '.'} {* gibt ' I like Latte' *} +{=' I like Latte. '|trim} {* gibt 'I like Latte.' aus *} +{=' I like Latte.'|trim: '.'} {* gibt ' I like Latte' aus *} ``` truncate(int length, string append = '…') .[filter] --------------------------------------------------- -Kürzt eine Zeichenkette auf die maximal angegebene Länge, versucht aber, ganze Wörter zu erhalten. Wenn die Zeichenkette abgeschnitten ist, wird am Ende ein Auslassungszeichen hinzugefügt (dies kann durch den zweiten Parameter geändert werden). +Kürzt eine Zeichenkette auf die angegebene maximale Länge, wobei versucht wird, ganze Wörter zu erhalten. Wenn die Zeichenkette gekürzt wird, wird am Ende ein Auslassungszeichen hinzugefügt (kann mit dem zweiten Parameter geändert werden). ```latte {var $title = 'Hello, how are you?'} -{$title|truncate:5} {* Hell… *} -{$title|truncate:17} {* Hello, how are… *} -{$title|truncate:30} {* Hello, how are you? *} +{$title|truncate:5} {* Hell… *} +{$title|truncate:17} {* Hello, how are… *} +{$title|truncate:30} {* Hello, how are you? *} ``` upper .[filter] --------------- -Konvertiert einen Wert in Großbuchstaben. Erfordert die PHP-Erweiterung `mbstring`. +Konvertiert eine Zeichenkette in Großbuchstaben. Erfordert die PHP-Erweiterung `mbstring`. ```latte -{='latte'|upper} {* gibt 'LATTE' *} +{='latte'|upper} {* gibt 'LATTE' aus *} ``` -Siehe auch [capitalize |#capitalize], [firstUpper |#firstUpper], [lower |#lower]. +Siehe auch [#capitalize], [#firstUpper], [#lower]. webalize .[filter] ------------------ -Konvertiert nach ASCII. +Konvertiert eine UTF-8-Zeichenkette in die in URLs verwendete Form. -Konvertiert Leerzeichen in Bindestriche. Entfernt Zeichen, die keine alphanumerischen Zeichen, Unterstriche oder Bindestriche sind. Konvertiert in Kleinbuchstaben. Entfernt auch führende und nachfolgende Leerzeichen. +Es wird in ASCII konvertiert. Konvertiert Leerzeichen in Bindestriche. Entfernt Zeichen, die nicht alphanumerisch, Unterstriche oder Bindestriche sind. Konvertiert in Kleinbuchstaben. Entfernt auch führende und abschließende Leerzeichen. ```latte -{var $s = 'Our 10. product'} -{$s|webalize} {* gibt 'our-10-product' *} +{var $s = 'Unser 10. Produkt'} +{$s|webalize} {* gibt 'unser-10-produkt' aus *} ``` .[caution] -Erfordert das Paket [nette/utils |utils:]. +Erfordert die Bibliothek [nette/utils |utils:]. diff --git a/latte/de/tags.texy b/latte/de/tags.texy index a6e13ee626..0fbefed3f3 100644 --- a/latte/de/tags.texy +++ b/latte/de/tags.texy @@ -2,167 +2,167 @@ Latte Tags ********** .[perex] -Zusammenfassung und Beschreibung aller in Latte integrierten Tags. +Eine Übersicht und Beschreibung aller Latte-Template-System-Tags, die standardmäßig zur Verfügung stehen. .[table-latte-tags language-latte] -|## Drucken -| `{$var}`, `{...}` oder `{=...}` | [druckt eine Variable oder einen Ausdruck mit Escapezeichen |#printing] -| `{$var\|filter}` | [druckt mit Filtern |#filters] -| `{l}` oder `{r}` | druckt `{` or `}` Zeichen +|## Ausgabe +| `{$var}`, `{...}` oder `{=...}` | [gibt eine escaped Variable oder einen Ausdruck aus|#Ausgabe] +| `{$var\|filter}` | [gibt mit Verwendung von Filtern aus|#Filter] +| `{l}` oder `{r}` | gibt das Zeichen `{` oder `}` aus .[table-latte-tags language-latte] |## Bedingungen -| `{if}`... `{elseif}`... `{else}`... `{/if}` | [Bedingung if |#if-elseif-else] -| `{ifset}`... `{elseifset}`... `{/ifset}` | [Bedingung ifset |#ifset-elseifset] -| `{ifchanged}`... `{/ifchanged}` | [Test, ob eine Änderung stattgefunden hat |#ifchanged] -| `{switch}` `{case}` `{default}` `{/switch}` | [Bedingung switch |#switch-case-default] -| `n:else` | [alternative Inhalte für Bedingungen |#n:else] +| `{if}` … `{elseif}` … `{else}` … `{/if}` | [if-Bedingung|#if-elseif-else] +| `{ifset}` … `{elseifset}` … `{/ifset}` | [ifset-Bedingung|#ifset-elseifset] +| `{ifchanged}` … `{/ifchanged}` | [Test, ob eine Änderung aufgetreten ist|#ifchanged] +| `{switch}` `{case}` `{default}` `{/switch}` | [switch-Bedingung|#switch-case-default] +| `n:else` | [alternativer Inhalt für Bedingungen|#n:else] .[table-latte-tags language-latte] |## Schleifen -| `{foreach}`... `{/foreach}` | [foreach |#foreach] -| `{for}`... `{/for}` | [for |#for] -| `{while}`... `{/while}` | [while |#while] -| `{continueIf $cond}` | [weiter zur nächsten Iteration |#continueif-skipif-breakif] -| `{skipIf $cond}` | [überspringt die aktuelle Schleifeniteration |#continueif-skipif-breakif] -| `{breakIf $cond}` | [bricht Schleife ab |#continueif-skipif-breakif] -| `{exitIf $cond}` | [vorzeitiges Beenden |#exitif] -| `{first}`... `{/first}` | [ist dies die erste Iteration? |#first-last-sep] -| `{last}`... `{/last}` | [ist es die letzte Iteration? |#first-last-sep] -| `{sep}`... `{/sep}` | [wird die nächste Iteration folgen? |#first-last-sep] -| `{iterateWhile}`... `{/iterateWhile}` | [strukturiert foreach |#iterateWhile] -| `$iterator` | [Spezielle Variable innerhalb der foreach-Schleife |#$iterator] +| `{foreach}` … `{/foreach}` | [#foreach] +| `{for}` … `{/for}` | [#for] +| `{while}` … `{/while}` | [#while] +| `{continueIf $cond}` | [mit der nächsten Iteration fortfahren|#continueif-skipif-breakif] +| `{skipIf $cond}` | [Iteration überspringen|#continueif-skipif-breakif] +| `{breakIf $cond}` | [Schleife abbrechen|#continueif-skipif-breakif] +| `{exitIf $cond}` | [vorzeitige Beendigung|#exitif] +| `{first}` … `{/first}` | [ist es der erste Durchlauf?|#first-last-sep] +| `{last}` … `{/last}` | [ist es der letzte Durchlauf?|#first-last-sep] +| `{sep}` … `{/sep}` | [wird noch ein Durchlauf folgen?|#first-last-sep] +| `{iterateWhile}` … `{/iterateWhile}` | [strukturiertes foreach|#iterateWhile] +| `$iterator` | [spezielle Variable innerhalb von foreach|#$iterator] .[table-latte-tags language-latte] -|## Einbindung anderer Vorlagen -| `{include 'file.latte'}` | [schließt eine Vorlage aus einer anderen Datei ein |#include] -| `{sandbox 'file.latte'}` | [Einfügen einer Vorlage im Sandbox-Modus |#sandbox] +|## Einbindung weiterer Templates +| `{include 'file.latte'}` | [lädt ein Template aus einer anderen Datei|#include] +| `{sandbox 'file.latte'}` | [lädt ein Template im Sandbox-Modus|#sandbox] .[table-latte-tags language-latte] -|## Blöcke, Layouts, Vererbung von Vorlagen -| `{block}` | [anonymer Block |#block] -| `{block blockname}` | [Blockdefinition |template-inheritance#blocks] -| `{define blockname}` | [Blockdefinition für zukünftige Verwendung |template-inheritance#definitions] -| `{include blockname}` | [druckt Block |template-inheritance#printing-blocks] -| `{include blockname from 'file.latte'}` | [druckt einen Block aus einer Datei |template-inheritance#printing-blocks] -| `{import 'file.latte'}` | [lädt Blöcke aus einer anderen Vorlage |template-inheritance#horizontal-reuse] -| `{layout 'file.latte'}` / `{extends}` | [gibt eine Layout-Datei an |template-inheritance#layout-inheritance] -| `{embed}`... `{/embed}` | [lädt die Vorlage oder den Block und ermöglicht das Überschreiben der Blöcke |template-inheritance#unit-inheritance] -| `{ifset blockname}`... `{/ifset}` | [Bedingung, wenn Block definiert ist |template-inheritance#checking-block-existence] +|## Blöcke, Layouts, Template-Vererbung +| `{block}` | [anonymer Block|#block] +| `{block blockname}` | [definiert einen Block|template-inheritance#blocks] +| `{define blockname}` | [definiert einen Block zur späteren Verwendung|template-inheritance#definitions] +| `{include blockname}` | [Darstellung eines Blocks|template-inheritance#printing-blocks] +| `{include blockname from 'file.latte'}` | [stellt einen Block aus einer Datei dar|template-inheritance#printing-blocks] +| `{import 'file.latte'}` | [lädt Blöcke aus einem Template|template-inheritance#horizontal-reuse] +| `{layout 'file.latte'}` / `{extends}` | [bestimmt die Layout-Datei|template-inheritance#layout-inheritance] +| `{embed}` … `{/embed}` | [lädt ein Template oder einen Block und ermöglicht das Überschreiben von Blöcken|template-inheritance#unit-inheritance] +| `{ifset blockname}` … `{/ifset}` | [Bedingung, ob ein Block existiert|template-inheritance#checking-block-existence] .[table-latte-tags language-latte] |## Ausnahmebehandlung -| `{try}`... `{else}`... `{/try}` | [Abfangen von Ausnahmen |#try] -| `{rollback}` | [verwirft try-Block |#rollback] +| `{try}` … `{else}` … `{/try}` | [Abfangen von Ausnahmen|#try] +| `{rollback}` | [Verwerfen eines try-Blocks|#rollback] .[table-latte-tags language-latte] |## Variablen -| `{var $foo = value}` | [Erstellung von Variablen |#var-default] -| `{default $foo = value}` | [Standardwert, wenn Variable nicht deklariert ist |#var-default] -| `{parameters}` | [deklariert Variablen, gibt einen Standardwert ein |#parameters] -| `{capture}`... `{/capture}` | [erfasst einen Abschnitt in einer Variablen |#capture] +| `{var $foo = value}` | [erstellt eine Variable|#var-default] +| `{default $foo = value}` | [erstellt eine Variable, wenn sie nicht existiert|#var-default] +| `{parameters}` | [deklariert Variablen, Typen und Standardwerte|#parameters] +| `{capture}` … `{/capture}` | [erfasst einen Block in eine Variable|#capture] .[table-latte-tags language-latte] |## Typen -| `{varType}` | [deklariert den Typ einer Variablen |type-system#varType] -| `{varPrint}` | [schlägt Variablentypen vor |type-system#varPrint] -| `{templateType}` | [deklariert Variablentypen mittels Klasse |type-system#templateType] -| `{templatePrint}` | [erzeugt Klasse mit Eigenschaften |type-system#templatePrint] +| `{varType}` | [deklariert den Typ einer Variable|type-system#varType] +| `{varPrint}` | [schlägt Typen für Variablen vor|type-system#varPrint] +| `{templateType}` | [deklariert Variablentypen basierend auf einer Klasse|type-system#templateType] +| `{templatePrint}` | [schlägt eine Klasse mit Variablentypen vor|type-system#templatePrint] .[table-latte-tags language-latte] -|## Übersetzung -| `{_string}` | [druckt übersetzt |#Translation] -| `{translate}`... `{/translate}` | [übersetzt den Inhalt |#Translation] +|## Übersetzungen +| `{_...}` | [gibt eine Übersetzung aus|#übersetzungen] +| `{translate}` … `{/translate}` | [übersetzt den Inhalt|#übersetzungen] .[table-latte-tags language-latte] -|## Andere -| `{contentType}` | [schaltet den Escaping-Modus um und sendet HTTP-Header |#contenttype] -| `{debugbreak}` | [setzt einen Haltepunkt im Code |#debugbreak] -| `{do}` | [wertet einen Ausdruck aus, ohne ihn zu drucken |#do] -| `{dump}` | [gibt Variablen in die Tracy Bar aus |#dump] -| `{php}` | [führt beliebigen PHP-Code aus |#php] -| `{spaceless}`... `{/spaceless}` | [entfernt unnötige Leerzeichen |#spaceless] -| `{syntax}` | [schaltet die Syntax während der Laufzeit um |#syntax] -| `{trace}` | [zeigt Stack-Trace |#trace] +|## Sonstiges +| `{contentType}` | [schaltet das Escaping um und sendet einen HTTP-Header|#contenttype] +| `{debugbreak}` | [platziert einen Breakpoint im Code|#debugbreak] +| `{do}` | [führt Code aus, gibt aber nichts aus|#do] +| `{dump}` | [dumpt Variablen in die Tracy Bar|#dump] +| `{php}` | [führt beliebigen PHP-Code aus|#php] +| `{spaceless}` … `{/spaceless}` | [entfernt überflüssige Leerzeichen|#spaceless] +| `{syntax}` | [Änderung der Syntax zur Laufzeit|#syntax] +| `{trace}` | [zeigt den Stack-Trace an|#trace] .[table-latte-tags language-latte] -|## HTML-Tag-Helfer -| `n:class` | [intelligentes Klassenattribut |#n:class] -| `n:attr` | [intelligente HTML-Attribute |#n:attr] -| `n:tag` | [Dynamischer Name des HTML-Elements |#n:tag] -| `n:ifcontent` | [Leeren HTML-Tag auslassen |#n:ifcontent] +|## Helfer für HTML-Codierer +| `n:class` | [dynamische Schreibweise des HTML-Attributs class|#n:class] +| `n:attr` | [dynamische Schreibweise beliebiger HTML-Attribute|#n:attr] +| `n:tag` | [dynamische Schreibweise des HTML-Element-Namens|#n:tag] +| `n:ifcontent` | [lässt einen leeren HTML-Tag aus|#n:ifcontent] .[table-latte-tags language-latte] -|## Nur in Nette Framework verfügbar -| `n:href` | [Link in `` HTML-Elementen |application:creating-links#In the Presenter Template] -| `{link}` | [gibt einen Link aus |application:creating-links#In the Presenter Template] -| `{plink}` | [druckt einen Link zu einem Presenter |application:creating-links#In the Presenter Template] -| `{control}` | [druckt eine Komponente |application:components#Rendering] -| `{snippet}`... `{/snippet}` | [ein Template-Snippet, das per AJAX gesendet werden kann |application:ajax#snippets-in-latte] -| `{snippetArea}` | [Schnipsel Umschlag |application:ajax#snippet-areas] -| `{cache}`... `{/cache}` | [zwischenspeichert einen Vorlagenabschnitt |caching:#caching-in-latte] +|## Nur im Nette Framework verfügbar +| `n:href` | [Link, der in HTML-Elementen `` verwendet wird|application:creating-links#In the Presenter Template] +| `{link}` | [gibt einen Link aus|application:creating-links#In the Presenter Template] +| `{plink}` | [gibt einen Link zu einem Presenter aus|application:creating-links#In the Presenter Template] +| `{control}` | [rendert eine Komponente|application:components#Rendering] +| `{snippet}` … `{/snippet}` | [ein Snippet, das per AJAX gesendet werden kann|application:ajax#snippets-in-latte] +| `{snippetArea}` | [Wrapper für Snippets|application:ajax#snippet-areas] +| `{cache}` … `{/cache}` | [cached einen Teil des Templates|caching:#caching-in-latte] .[table-latte-tags language-latte] |## Nur mit Nette Forms verfügbar -| `{form}`... `{/form}` | [druckt ein Formularelement |forms:rendering#form] -| `{label}`... `{/label}` | [druckt eine Formulareingabebezeichnung |forms:rendering#label-input] -| `{input}` | [druckt ein Formulareingabeelement |forms:rendering#label-input] -| `{inputError}` | [gibt eine Fehlermeldung für ein Formulareingabeelement aus |forms:rendering#inputError] -| `n:name` | [aktiviert ein HTML-Eingabeelement |forms:rendering#n:name] -| `{formContainer}`... `{/formContainer}` | [Darstellung des Formular-Containers |forms:rendering#special-cases] +| `{form}` … `{/form}` | [rendert Formular-Tags|forms:rendering#form] +| `{label}` … `{/label}` | [rendert ein Label für ein Formularelement|forms:rendering#label-input] +| `{input}` | [rendert ein Formularelement|forms:rendering#label-input] +| `{inputError}` | [gibt eine Fehlermeldung für ein Formularelement aus|forms:rendering#inputError] +| `n:name` | [aktiviert ein Formularelement|forms:rendering#n:name] +| `{formContainer}` … `{/formContainer}` | [Zeichnen eines Formular-Containers|forms:rendering#special-cases] -Drucken .[#toc-printing] +Ausgabe .[#toc-printing] ======================== `{$var}` `{...}` `{=...}` ------------------------- -Latte verwendet das Tag `{=...}`, um einen beliebigen Ausdruck in der Ausgabe auszugeben. Wenn der Ausdruck mit einer Variablen oder einem Funktionsaufruf beginnt, ist es nicht nötig, ein Gleichheitszeichen zu schreiben. Das bedeutet in der Praxis, dass es fast nie geschrieben werden muss: +In Latte wird das Tag `{=...}` verwendet, um einen beliebigen Ausdruck auszugeben. Latte legt Wert auf Ihren Komfort, daher ist es nicht nötig, das Gleichheitszeichen zu schreiben, wenn der Ausdruck mit einer Variable oder einem Funktionsaufruf beginnt. Das bedeutet in der Praxis, dass es fast nie notwendig ist, es zu schreiben: ```latte Name: {$name} {$surname}
-Age: {date('Y') - $birth}
+Alter: {date('Y') - $birth}
``` -Sie können alles, was Sie aus PHP kennen, als Ausdruck schreiben. Sie müssen nur keine neue Sprache lernen. Zum Beispiel: +Als Ausdruck können Sie alles schreiben, was Sie aus PHP kennen. Sie müssen einfach keine neue Sprache lernen. Zum Beispiel: ```latte {='0' . ($num ?? $num * 3) . ', ' . PHP_VERSION} ``` -Bitte suchen Sie nicht nach einer Bedeutung in dem vorherigen Beispiel, aber wenn Sie eine finden, schreiben Sie uns :-) +Bitte suchen Sie in dem vorherigen Beispiel keinen Sinn, aber wenn Sie einen finden sollten, schreiben Sie uns :-) -Ausweichende Ausgabe .[#toc-escaping-output] --------------------------------------------- +Ausgabe escapen .[#toc-escaping-output] +--------------------------------------- -Was ist die wichtigste Aufgabe eines Template-Systems? Sicherheitslücken zu vermeiden. Und genau das tut Latte, wenn Sie etwas in die Ausgabe drucken. Es entschlüsselt automatisch alles: +Was ist die wichtigste Aufgabe eines Template-Systems? Sicherheitslücken zu verhindern. Und genau das macht Latte immer, wenn Sie etwas ausgeben. Es escaped es automatisch: ```latte -

{='one < two'}

{* prints: '

one < two

' *} +

{='one < two'}

{* gibt aus: '

one < two

' *} ``` -Um genau zu sein, verwendet Latte kontextabhängiges Escaping, eine so wichtige und einzigartige Funktion dass wir ihr [ein eigenes Kapitel |safety-first#context-aware-escaping] gewidmet haben. +Um genau zu sein, verwendet Latte kontextsensitives Escaping, was so wichtig und einzigartig ist, dass wir ihm [ein eigenes Kapitel|safety-first#context-aware-escaping] gewidmet haben. -Und wenn Sie HTML-codierte Inhalte aus einer vertrauenswürdigen Quelle drucken? Dann können Sie das Escaping einfach abschalten: +Und was ist, wenn Sie HTML-codierten Inhalt aus einer vertrauenswürdigen Quelle ausgeben? Dann kann das Escaping einfach deaktiviert werden: ```latte {$trustedHtmlString|noescape} ``` .[warning] -Der Missbrauch des `noescape`-Filters kann zu einer XSS-Schwachstelle führen! Verwenden Sie ihn nur, wenn Sie **absolut sicher** sind, was Sie tun und dass die Zeichenfolge, die Sie ausgeben, aus einer vertrauenswürdigen Quelle stammt. +Eine falsche Verwendung des `noescape`-Filters kann zu einer XSS-Schwachstelle führen! Verwenden Sie ihn niemals, wenn Sie sich nicht **absolut sicher** sind, was Sie tun, und dass die ausgegebene Zeichenkette aus einer vertrauenswürdigen Quelle stammt. -Drucken in JavaScript .[#toc-printing-in-javascript] +Ausgabe in JavaScript .[#toc-printing-in-javascript] ---------------------------------------------------- -Dank der kontextsensitiven Escape-Funktion ist es wunderbar einfach, Variablen innerhalb von JavaScript zu drucken, und Latte wird sie korrekt escapen. +Dank des kontextsensitiven Escapings ist es wunderbar einfach, Variablen innerhalb von JavaScript auszugeben, und Latte kümmert sich um das korrekte Escaping. -Die Variable muss keine Zeichenkette sein, es wird jeder Datentyp unterstützt, der dann als JSON kodiert wird: +Die Variable muss nicht unbedingt ein String sein, es wird jeder Datentyp unterstützt, der dann als JSON kodiert wird: ```latte {var $foo = ['hello', true, 1]} @@ -179,7 +179,7 @@ Erzeugt: ``` -Dies ist auch der Grund, warum **Variablen nicht in Anführungszeichen** gesetzt werden sollten: Latte fügt sie um Strings herum ein. Und wenn Sie eine String-Variable in einen anderen String einfügen wollen, verketten Sie sie einfach: +Das ist auch der Grund, warum **keine Anführungszeichen** um die Variable geschrieben werden: Latte fügt sie bei Strings selbst hinzu. Und wenn Sie eine String-Variable in einen anderen String einfügen möchten, verbinden Sie sie einfach: ```latte ``` @@ -195,13 +195,13 @@ Dies ist auch der Grund, warum **Variablen nicht in Anführungszeichen** gesetzt Filter .[#toc-filters] ---------------------- -Der gedruckte Ausdruck kann [durch Filter |syntax#filters] verändert werden. In diesem Beispiel wird die Zeichenkette beispielsweise in Großbuchstaben umgewandelt und auf maximal 30 Zeichen gekürzt: +Der ausgegebene Ausdruck kann durch einen [Filter|syntax#filters] modifiziert werden. So können wir zum Beispiel eine Zeichenkette in Großbuchstaben umwandeln und auf maximal 30 Zeichen kürzen: ```latte {$string|upper|truncate:30} ``` -Sie können auch Filter auf Teile eines Ausdrucks anwenden, wie folgt: +Filter können auch auf Teile eines Ausdrucks auf folgende Weise angewendet werden: ```latte {$left . ($middle|upper) . $right} @@ -215,60 +215,60 @@ Bedingungen .[#toc-conditions] `{if}` `{elseif}` `{else}` -------------------------- -Bedingungen verhalten sich genauso wie die entsprechenden PHP-Ausdrücke. Sie können die gleichen Ausdrücke verwenden, die Sie aus PHP kennen, Sie müssen keine neue Sprache lernen. +Bedingungen verhalten sich genauso wie ihre Pendants in PHP. Sie können in ihnen die gleichen Ausdrücke verwenden, die Sie aus PHP kennen, Sie müssen keine neue Sprache lernen. ```latte {if $product->inStock > Stock::Minimum} - In stock + Auf Lager {elseif $product->isOnWay()} - On the way + Unterwegs {else} - Not available + Nicht verfügbar {/if} ``` -Wie jedes Paar-Tag kann ein Paar von `{if} ... {/ if}` zum Beispiel als [n:attribute |syntax#n:attributes] geschrieben werden: +Wie jedes Paar-Tag kann auch das Paar `{if} ... {/if}` in Form eines [n:Attributs|syntax#n:attributes] geschrieben werden, zum Beispiel: ```latte -

In stock {$count} items

+

{$count} Artikel auf Lager

``` -Wussten Sie, dass Sie das Präfix `tag-` zu n:Attributen hinzufügen können? Dann wirkt sich die Bedingung nur auf die HTML-Tags aus und der Inhalt zwischen ihnen wird immer gedruckt: +Wussten Sie, dass Sie n:Attribute mit dem Präfix `tag-` versehen können? Dann bezieht sich die Bedingung nur auf die Ausgabe der HTML-Tags, und der Inhalt dazwischen wird immer ausgegeben: ```latte
Hello -{* prints 'Hello' when $clickable is falsey *} -{* prints 'Hello' when $clickable is truthy *} +{* gibt 'Hello' aus, wenn $clickable falsch ist *} +{* gibt 'Hello' aus, wenn $clickable wahr ist *} ``` -Schön. +Göttlich. `n:else` .{data-version:3.0.11} ------------------------------- -Wenn Sie die Bedingung `{if} ... {/if}` in Form eines [n:-Attributs |syntax#n:attributes] schreiben, haben Sie die Möglichkeit, mit `n:else` eine alternative Verzweigung anzugeben: +Wenn Sie die Bedingung `{if} ... {/if}` in Form eines [n:Attributs|syntax#n:attributes] schreiben, haben Sie die Möglichkeit, eine alternative Verzweigung mit `n:else` anzugeben: ```latte -In stock {$count} items +{$count} Artikel auf Lager -not available +nicht verfügbar ``` -Das Attribut `n:else` kann auch in Verbindung mit [`n:ifset` |#ifset-elseifset], [`n:foreach` |#foreach], [`n:try` |#try], [`n:ifcontent` |#n:ifcontent], und [`n:ifchanged` |#ifchanged]. +Das Attribut `n:else` kann auch in Kombination mit [`n:ifset` |#ifset-elseifset], [`n:foreach` |#foreach], [`n:try` |#try], [`n:ifcontent` |#n:ifcontent] und [`n:ifchanged` |#ifchanged] verwendet werden. `{/if $cond}` ------------- -Sie werden vielleicht überrascht sein, dass der Ausdruck in der Bedingung `{if}` auch im End-Tag angegeben werden kann. Dies ist in Situationen nützlich, in denen wir den Wert der Bedingung noch nicht kennen, wenn das Tag geöffnet wird. Nennen wir es eine aufgeschobene Entscheidung. +Es mag Sie überraschen, dass der Ausdruck in der Bedingung `{if}` auch im schließenden Tag angegeben werden kann. Dies ist nützlich in Situationen, in denen wir beim Öffnen der Bedingung ihren Wert noch nicht kennen. Nennen wir es eine verzögerte Entscheidung. -Wir beginnen z. B. mit der Auflistung einer Tabelle mit Datensätzen aus der Datenbank und stellen erst nach Fertigstellung des Berichts fest, dass kein Datensatz in der Datenbank vorhanden war. Also setzen wir die Bedingung in das End-Tag `{/if}`, und wenn es keinen Datensatz gibt, wird nichts davon gedruckt: +Zum Beispiel beginnen wir mit der Ausgabe einer Tabelle mit Datensätzen aus der Datenbank und erst nach Abschluss der Ausgabe stellen wir fest, dass kein Datensatz in der Datenbank vorhanden war. Also setzen wir eine Bedingung in das schließende `{/if}`-Tag, und wenn kein Datensatz vorhanden ist, wird nichts davon ausgegeben: ```latte {if} -

Printing rows from the database

+

Ausgabe von Zeilen aus der Datenbank

{foreach $resultSet as $row} @@ -278,9 +278,9 @@ Wir beginnen z. B. mit der Auflistung einer Tabelle mit Datensätzen aus der Dat {/if isset($row)} ``` -Praktisch, nicht wahr? +Clever, nicht wahr? -Sie können auch `{else}` in der aufgeschobenen Bedingung verwenden, aber nicht `{elseif}`. +In einer verzögerten Bedingung kann auch `{else}` verwendet werden, aber nicht `{elseif}`. `{ifset}` `{elseifset}` @@ -289,7 +289,7 @@ Sie können auch `{else}` in der aufgeschobenen Bedingung verwenden, aber nicht .[note] Siehe auch [`{ifset block}` |template-inheritance#checking-block-existence] -Verwenden Sie die `{ifset $var}` Bedingung, um festzustellen, ob eine Variable (oder mehrere Variablen) existiert und einen Nicht-Null-Wert hat. Es ist eigentlich das Gleiche wie `if (isset($var))` in PHP. Wie jedes Paar-Tag kann es in der Form von [n:attribute |syntax#n:attributes] geschrieben werden, also zeigen wir es in einem Beispiel: +Mit der Bedingung `{ifset $var}` können wir überprüfen, ob eine Variable (oder mehrere Variablen) existiert und einen nicht-null-Wert hat. Es ist im Grunde dasselbe wie `if (isset($var))` in PHP. Wie jedes Paar-Tag kann es auch in Form eines [n:Attributs|syntax#n:attributes] geschrieben werden, also zeigen wir es als Beispiel: ```latte @@ -299,9 +299,9 @@ Verwenden Sie die `{ifset $var}` Bedingung, um festzustellen, ob eine Variable ( `{ifchanged}` ------------- -`{ifchanged}` prüft, ob sich der Wert einer Variablen seit der letzten Iteration in der Schleife (foreach, for oder while) geändert hat. +`{ifchanged}` überprüft, ob sich der Wert einer Variable seit der letzten Iteration in einer Schleife (foreach, for oder while) geändert hat. -Wenn wir eine oder mehrere Variablen im Tag angeben, wird geprüft, ob sich eine von ihnen geändert hat, und der Inhalt wird entsprechend ausgegeben. Im folgenden Beispiel wird beispielsweise bei der Auflistung von Namen jedes Mal der erste Buchstabe eines Namens als Überschrift ausgegeben, wenn er sich ändert: +Wenn wir eine oder mehrere Variablen im Tag angeben, wird überprüft, ob sich eine von ihnen geändert hat, und dementsprechend wird der Inhalt ausgegeben. Das folgende Beispiel gibt den ersten Buchstaben des Namens als Überschrift aus, jedes Mal wenn er sich bei der Ausgabe der Namen ändert: ```latte {foreach ($names|sort) as $name} @@ -311,7 +311,7 @@ Wenn wir eine oder mehrere Variablen im Tag angeben, wird geprüft, ob sich eine {/foreach} ``` -Wenn jedoch kein Argument angegeben wird, wird der gerenderte Inhalt selbst mit seinem vorherigen Zustand verglichen. Das bedeutet, dass wir im vorherigen Beispiel das Argument im Tag getrost weglassen können. Und natürlich können wir auch [n:attribute |syntax#n:attributes] verwenden: +Wenn wir jedoch kein Argument angeben, wird der gerenderte Inhalt im Vergleich zu seinem vorherigen Zustand überprüft. Das bedeutet, dass wir im vorherigen Beispiel das Argument im Tag weglassen können. Und natürlich können wir auch ein [n:Attribut|syntax#n:attributes] verwenden: ```latte {foreach ($names|sort) as $name} @@ -321,35 +321,35 @@ Wenn jedoch kein Argument angegeben wird, wird der gerenderte Inhalt selbst mit {/foreach} ``` -Sie können auch eine `{else}` Klausel innerhalb der `{ifchanged}` einfügen. +Innerhalb von `{ifchanged}` kann auch eine `{else}`-Klausel verwendet werden. `{switch}` `{case}` `{default}` ------------------------------- -Vergleicht den Wert mit mehreren Optionen. Dies ist ähnlich wie die `switch` Struktur, die Sie aus PHP kennen. Latte verbessert sie jedoch: +Vergleicht einen Wert mit mehreren Möglichkeiten. Es ist ähnlich wie die bedingte Anweisung `switch`, die Sie aus PHP kennen. Latte verbessert sie jedoch: -- verwendet einen strengen Vergleich (`===`) -- braucht kein `break` +- es verwendet einen strikten Vergleich (`===`) +- es benötigt kein `break` -Es ist also das exakte Äquivalent der `match` Struktur, die PHP 8.0 mitbringt. +Es ist also das genaue Äquivalent zur `match`-Struktur, die mit PHP 8.0 eingeführt wurde. ```latte {switch $transport} {case train} - By train + Mit dem Zug {case plane} - By plane + Mit dem Flugzeug {default} - Differently + Anderweitig {/switch} ``` -Die Klausel `{case}` kann mehrere durch Kommas getrennte Werte enthalten: +Die `{case}`-Klausel kann mehrere durch Kommas getrennte Werte enthalten: ```latte {switch $status} -{case $status::New}new item -{case $status::Sold, $status::Unknown}not available +{case $status::New}neuer Artikel +{case $status::Sold, $status::Unknown}nicht verfügbar {/switch} ``` @@ -357,13 +357,13 @@ Die Klausel `{case}` kann mehrere durch Kommas getrennte Werte enthalten: Schleifen .[#toc-loops] ======================= -In Latte stehen Ihnen alle Schleifen, die Sie aus PHP kennen, zur Verfügung: foreach, for und while. +In Latte finden Sie alle Schleifen, die Sie aus PHP kennen: foreach, for und while. `{foreach}` ----------- -Sie schreiben den Zyklus genau so wie in PHP: +Wir schreiben die Schleife genauso wie in PHP: ```latte {foreach $langs as $code => $lang} @@ -371,11 +371,11 @@ Sie schreiben den Zyklus genau so wie in PHP: {/foreach} ``` -Darüber hinaus hat er einige praktische Verbesserungen, über die wir jetzt sprechen werden. +Zusätzlich hat sie einige nützliche Funktionen, über die wir jetzt sprechen werden. -So stellt Latte zum Beispiel sicher, dass erstellte Variablen nicht versehentlich gleichnamige globale Variablen überschreiben. Das hilft Ihnen, wenn Sie davon ausgehen, dass `$lang` die aktuelle Sprache der Seite ist, und Sie nicht merken, dass `foreach $langs as $lang` diese Variable überschrieben hat. +Latte überprüft zum Beispiel, ob erstellte Variablen versehentlich globale Variablen mit demselben Namen überschreiben. Das rettet Situationen, in denen Sie davon ausgehen, dass `$lang` die aktuelle Sprache der Seite ist, und nicht bemerken, dass `foreach $langs as $lang` diese Variable überschrieben hat. -Die foreach-Schleife kann auch sehr elegant und sparsam mit [n:attribute |syntax#n:attributes] geschrieben werden: +Die foreach-Schleife kann auch sehr elegant und kompakt als [n:Attribut|syntax#n:attributes] geschrieben werden: ```latte
    @@ -383,7 +383,7 @@ Die foreach-Schleife kann auch sehr elegant und sparsam mit [n:attribute |syntax
``` -Wussten Sie, dass Sie n:attributes das Präfix `inner-` voranstellen können? Dann wird in der Schleife nur noch der innere Teil des Elements wiederholt: +Wussten Sie, dass Sie n:Attribute mit dem Präfix `inner-` versehen können? Dann wird nur der Inhalt des Elements in der Schleife wiederholt: ```latte
@@ -392,7 +392,7 @@ Wussten Sie, dass Sie n:attributes das Präfix `inner-` voranstellen können? Da
``` -Es wird also etwas gedruckt wie: +Dies wird also etwas wie folgendes ausgeben: ```latte
@@ -407,14 +407,14 @@ Es wird also etwas gedruckt wie: `{else}` .{toc: foreach-else} ----------------------------- -Die Schleife `foreach` kann eine optionale Klausel `{else}` enthalten, deren Text angezeigt wird, wenn das angegebene Feld leer ist: +Innerhalb einer `foreach`-Schleife kann eine `{else}`-Klausel angegeben werden, deren Inhalt angezeigt wird, wenn die Schleife leer ist: ```latte
    {foreach $people as $person}
  • {$person->name}
  • {else} -
  • Sorry, no users in this list
  • +
  • Leider sind in dieser Liste keine Benutzer
  • {/foreach}
``` @@ -423,17 +423,17 @@ Die Schleife `foreach` kann eine optionale Klausel `{else}` enthalten, deren Tex `$iterator` ----------- -Innerhalb der Schleife `foreach` wird die Variable `$iterator` initialisiert. Sie enthält wichtige Informationen über die aktuelle Schleife. +Innerhalb einer `foreach`-Schleife erstellt Latte eine Variable `$iterator`, mit der wir nützliche Informationen über die laufende Schleife abrufen können: -- `$iterator->first` - ist dies die erste Iteration? -- `$iterator->last` - ist dies die letzte Iteration? -- `$iterator->counter` - Iterationszähler, beginnt bei 1 -- `$iterator->counter0` - Iterationszähler, beginnt bei 0 -- `$iterator->odd` - Ist diese Iteration ungerade? -- `$iterator->even` - ist diese Iteration gerade? -- `$iterator->parent` - der Iterator, der den aktuellen Iterator umgibt -- `$iterator->nextValue` - das nächste Element in der Schleife -- `$iterator->nextKey` - der Schlüssel des nächsten Elements in der Schleife +- `$iterator->first` - ist dies der erste Durchlauf? +- `$iterator->last` - ist dies der letzte Durchlauf? +- `$iterator->counter` - der wievielte Durchlauf ist es, gezählt ab eins? +- `$iterator->counter0` - der wievielte Durchlauf ist es, gezählt ab null? +- `$iterator->odd` - ist dies ein ungerader Durchlauf? +- `$iterator->even` - ist dies ein gerader Durchlauf? +- `$iterator->parent` - der Iterator, der den aktuellen umgibt +- `$iterator->nextValue` - der nächste Eintrag in der Schleife +- `$iterator->nextKey` - der Schlüssel des nächsten Eintrags in der Schleife ```latte @@ -449,20 +449,20 @@ Innerhalb der Schleife `foreach` wird die Variable `$iterator` initialisiert. Si {/foreach} ``` -Die Latte ist schlau und `$iterator->last` funktioniert nicht nur für Arrays, sondern auch, wenn die Schleife über einen allgemeinen Iterator läuft, bei dem die Anzahl der Elemente nicht im Voraus bekannt ist. +Latte ist schlau und `$iterator->last` funktioniert nicht nur bei Arrays, sondern auch wenn die Schleife über einen allgemeinen Iterator läuft, bei dem die Anzahl der Elemente nicht im Voraus bekannt ist. `{first}` `{last}` `{sep}` -------------------------- -Diese Tags können innerhalb der Schleife `{foreach}` verwendet werden. Der Inhalt von `{first}` wird beim ersten Durchlauf gerendert. -Der Inhalt von `{last}` wird gerendert ... können Sie es erraten? Ja, für den letzten Durchlauf. Dies sind eigentlich Abkürzungen für `{if $iterator->first}` und `{if $iterator->last}`. +Diese Tags können innerhalb einer `{foreach}`-Schleife verwendet werden. Der Inhalt von `{first}` wird gerendert, wenn es sich um den ersten Durchlauf handelt. +Der Inhalt von `{last}` wird gerendert ... können Sie es erraten? Ja, wenn es sich um den letzten Durchlauf handelt. Es handelt sich eigentlich um Abkürzungen für `{if $iterator->first}` und `{if $iterator->last}`. -Die Tags können auch als [n:attributes |syntax#n:attributes] geschrieben werden: +Die Tags können auch elegant als [n:Attribute|syntax#n:attributes] verwendet werden: ```latte {foreach $rows as $row} - {first}

List of names

{/first} + {first}

Liste der Namen

{/first}

{$row->name}

@@ -470,21 +470,21 @@ Die Tags können auch als [n:attributes |syntax#n:attributes] geschrieben werden {/foreach} ``` -Der Inhalt von `{sep}` wird wiedergegeben, wenn es sich nicht um die letzte Iteration handelt, und eignet sich daher für die Ausgabe von Begrenzungszeichen, wie z. B. Kommas zwischen aufgelisteten Elementen: +Der Inhalt des `{sep}`-Tags wird gerendert, wenn der Durchlauf nicht der letzte ist. Es eignet sich also zum Rendern von Trennzeichen, zum Beispiel Kommas zwischen ausgegebenen Elementen: ```latte {foreach $items as $item} {$item} {sep}, {/sep} {/foreach} ``` -Das ist doch ziemlich praktisch, oder? +Das ist ziemlich praktisch, nicht wahr? `{iterateWhile}` ---------------- -Vereinfacht die Gruppierung von linearen Daten während der Iteration in einer foreach-Schleife durch Iteration in einer verschachtelten Schleife, bis eine Bedingung erfüllt ist. [Lesen Sie die ausführliche Anleitung |cookbook/grouping]. +Vereinfacht die Gruppierung linearer Daten während der Iteration in einer foreach-Schleife, indem die Iteration in einer verschachtelten Schleife durchgeführt wird, solange eine Bedingung erfüllt ist. [Lesen Sie die detaillierte Anleitung|cookbook/grouping]. -Sie kann auch `{first}` und `{last}` im obigen Beispiel elegant ersetzen: +Es kann auch elegant `{first}` und `{last}` im obigen Beispiel ersetzen: ```latte {foreach $rows as $row} @@ -501,21 +501,21 @@ Sie kann auch `{first}` und `{last}` im obigen Beispiel elegant ersetzen: {/foreach} ``` -Siehe auch [Batch- |filters#batch] und [Gruppenfilter |filters#group]. +Siehe auch die Filter [batch|filters#batch] und [group|filters#group]. `{for}` ------- -Wir schreiben den Zyklus genau so wie in PHP: +Wir schreiben die Schleife genauso wie in PHP: ```latte {for $i = 0; $i < 10; $i++} - Item #{$i} + Element {$i} {/for} ``` -Das Tag kann auch als [n:attribute |syntax#n:attributes] geschrieben werden: +Das Tag kann auch als [n:Attribut|syntax#n:attributes] verwendet werden: ```latte

{$i}

@@ -525,7 +525,7 @@ Das Tag kann auch als [n:attribute |syntax#n:attributes] geschrieben werden: `{while}` --------- -Auch hier schreiben wir den Zyklus genau so, wie in PHP: +Wir schreiben die Schleife wieder genauso wie in PHP: ```latte {while $row = $result->fetch()} @@ -533,7 +533,7 @@ Auch hier schreiben wir den Zyklus genau so, wie in PHP: {/while} ``` -Oder als [n:Attribut |syntax#n:attributes]: +Oder als [n:Attribut|syntax#n:attributes]: ```latte @@ -541,7 +541,7 @@ Oder als [n:Attribut |syntax#n:attributes]: ``` -Eine Variante mit einer Bedingung im End-Tag entspricht der do-while-Schleife in PHP: +Eine Variante mit der Bedingung im schließenden Tag ist ebenfalls möglich, die der do-while-Schleife in PHP entspricht: ```latte {while} @@ -553,7 +553,7 @@ Eine Variante mit einer Bedingung im End-Tag entspricht der do-while-Schleife in `{continueIf}` `{skipIf}` `{breakIf}` ------------------------------------- -Es gibt spezielle Tags, die Sie zur Steuerung jeder Schleife verwenden können - `{continueIf ?}` und `{breakIf ?}`, die zur nächsten Iteration springen bzw. die Schleife beenden, wenn die Bedingungen erfüllt sind: +Zur Steuerung jeder Schleife können die Tags `{continueIf ?}` und `{breakIf ?}` verwendet werden, die zum nächsten Element übergehen bzw. die Schleife beenden, wenn eine Bedingung erfüllt ist: ```latte {foreach $rows as $row} @@ -564,7 +564,7 @@ Es gibt spezielle Tags, die Sie zur Steuerung jeder Schleife verwenden können - ``` -Das Tag `{skipIf}` ist dem Tag `{continueIf}` sehr ähnlich, erhöht aber den Zähler nicht. So gibt es keine Löcher in der Nummerierung, wenn Sie `$iterator->counter` ausdrucken und einige Elemente überspringen. Auch die {else}-Klausel wird wiedergegeben, wenn Sie alle Elemente überspringen. +Das `{skipIf}`-Tag ist sehr ähnlich wie `{continueIf}`, erhöht aber nicht den Zähler `$iterator->counter`, so dass, wenn wir ihn ausgeben und gleichzeitig einige Elemente überspringen, keine Lücken in der Nummerierung entstehen. Außerdem wird die `{else}`-Klausel gerendert, wenn wir alle Elemente überspringen. ```latte
    @@ -572,7 +572,7 @@ Das Tag `{skipIf}` ist dem Tag `{continueIf}` sehr ähnlich, erhöht aber den Z {skipIf $person->age < 18}
  • {$iterator->counter}. {$person->name}
  • {else} -
  • Sorry, no adult users in this list
  • +
  • Leider gibt es keine Erwachsenen in dieser Liste
  • {/foreach}
``` @@ -581,20 +581,20 @@ Das Tag `{skipIf}` ist dem Tag `{continueIf}` sehr ähnlich, erhöht aber den Z `{exitIf}` .{data-version:3.0.5} -------------------------------- -Beendet das Rendering einer Vorlage oder eines Blocks, wenn eine Bedingung erfüllt ist (d. h. "early exit"). +Beendet das Rendern des Templates oder Blocks, wenn eine Bedingung erfüllt ist (sogenannter "early exit"). ```latte {exitIf !$messages} -

Messages

+

Nachrichten

{$message}
``` -Schablonen einbeziehen .[#toc-including-templates] -================================================== +Einbindung von Templates .[#toc-including-templates] +==================================================== `{include 'file.latte'}` .{toc: include} @@ -603,46 +603,46 @@ Schablonen einbeziehen .[#toc-including-templates] .[note] Siehe auch [`{include block}` |template-inheritance#printing-blocks] -Der `{include}` Tag lädt und rendert die angegebene Vorlage. In unserer Lieblingssprache PHP sieht das so aus: +Das `{include}`-Tag lädt und rendert das angegebene Template. Wenn wir in der Sprache unserer Lieblingssprache PHP sprechen würden, wäre es so etwas wie: ```php ``` -Eingebundene Templates haben keinen Zugriff auf die Variablen des aktiven Kontexts, aber sie haben Zugriff auf die globalen Variablen. +Eingebundene Templates haben keinen Zugriff auf die Variablen des aktiven Kontexts, sie haben nur Zugriff auf globale Variablen. -Sie können der eingefügten Vorlage auf folgende Weise Variablen übergeben: +Variablen können auf diese Weise an das eingebundene Template übergeben werden: ```latte {include 'template.latte', foo: 'bar', id: 123} ``` -Der Name der Vorlage kann ein beliebiger PHP-Ausdruck sein: +Der Name des Templates kann ein beliebiger PHP-Ausdruck sein: ```latte {include $someVar} {include $ajax ? 'ajax.latte' : 'not-ajax.latte'} ``` -Der eingefügte Inhalt kann durch [Filter |syntax#filters] verändert werden. Im folgenden Beispiel werden alle HTML-Elemente entfernt und die Groß- und Kleinschreibung angepasst: +Der eingebundene Inhalt kann mit [Filtern|syntax#Filters] modifiziert werden. Das folgende Beispiel entfernt das gesamte HTML und passt die Groß-/Kleinschreibung an: ```latte {include 'heading.latte' |stripHtml|capitalize} ``` -Die [Vorlagenvererbung |template inheritance] ist standardmäßig **nicht** daran beteiligt. Sie können zwar Block-Tags zu eingebundenen Vorlagen hinzufügen, diese ersetzen jedoch nicht die passenden Blöcke in der Vorlage, in die sie eingebunden sind. Betrachten Sie Includes als unabhängige und abgeschirmte Teile von Seiten oder Modulen. Dieses Verhalten kann mit dem Modifikator `with blocks` geändert werden: +Standardmäßig spielt die [Template-Vererbung|template-inheritance] in diesem Fall keine Rolle. Auch wenn wir in dem eingebundenen Template Blöcke verwenden können, werden die entsprechenden Blöcke in dem Template, in das eingebunden wird, nicht ersetzt. Denken Sie an eingebundene Templates als separate, abgeschirmte Teile von Seiten oder Modulen. Dieses Verhalten kann mit dem Modifikator `with blocks` geändert werden: ```latte {include 'template.latte' with blocks} ``` -Die Beziehung zwischen dem im Tag angegebenen Dateinamen und der Datei auf der Festplatte ist eine Sache des [Loaders |extending-latte#Loaders]. +Die Beziehung zwischen dem im Tag angegebenen Dateinamen und der Datei auf der Festplatte ist eine Angelegenheit des [Loaders|extending-latte#Loaders]. `{sandbox}` ----------- -Wenn Sie eine von einem Endbenutzer erstellte Vorlage einbinden, sollten Sie eine Sandbox verwenden (weitere Informationen finden Sie in der [Sandbox-Dokumentation |sandbox]): +Bei der Einbindung eines vom Endbenutzer erstellten Templates sollten Sie den Sandbox-Modus in Betracht ziehen (weitere Informationen finden Sie in der [Sandbox-Dokumentation |sandbox]): ```latte {sandbox 'untrusted.latte', level: 3, data: $menu} @@ -655,7 +655,7 @@ Wenn Sie eine von einem Endbenutzer erstellte Vorlage einbinden, sollten Sie ein .[note] Siehe auch [`{block name}` |template-inheritance#blocks] -Blöcke ohne Namen dienen dazu, [Filter |syntax#filters] auf einen Teil der Vorlage anzuwenden. Sie können zum Beispiel einen [Streifenfilter |filters#strip] anwenden, um überflüssige Leerzeichen zu entfernen: +Namenlose Blöcke dienen als Möglichkeit, [Filter|syntax#Filters] auf einen Teil des Templates anzuwenden. Zum Beispiel kann auf diese Weise der [strip|filters#strip]-Filter angewendet werden, der überflüssige Leerzeichen entfernt: ```latte {block|strip} @@ -666,16 +666,16 @@ Blöcke ohne Namen dienen dazu, [Filter |syntax#filters] auf einen Teil der Vorl ``` -Behandlung von Ausnahmen .[#toc-exception-handling] -=================================================== +Ausnahmebehandlung .[#toc-exception-handling] +============================================= `{try}` ------- -Diese Tags machen es extrem einfach, robuste Vorlagen zu erstellen. +Dank dieses Tags ist es extrem einfach, robuste Templates zu erstellen. -Wenn beim Rendern des `{try}` -Blocks eine Ausnahme auftritt, wird der gesamte Block verworfen und das Rendern danach fortgesetzt: +Wenn während des Renderns eines `{try}`-Blocks eine Ausnahme auftritt, wird der gesamte Block verworfen und das Rendering wird danach fortgesetzt: ```latte {try} @@ -687,7 +687,7 @@ Wenn beim Rendern des `{try}` -Blocks eine Ausnahme auftritt, wird der gesamte B {/try} ``` -Der Inhalt der optionalen Klausel `{else}` wird nur gerendert, wenn eine Ausnahme auftritt: +Der Inhalt in der optionalen `{else}`-Klausel wird nur gerendert, wenn eine Ausnahme auftritt: ```latte {try} @@ -697,11 +697,11 @@ Der Inhalt der optionalen Klausel `{else}` wird nur gerendert, wenn eine Ausnahm {/foreach} {else} -

Sorry, the tweets could not be loaded.

+

Es tut uns leid, die Tweets konnten nicht geladen werden.

{/try} ``` -Der Tag kann auch als [n:attribute |syntax#n:attributes] geschrieben werden: +Das Tag kann auch als [n:Attribut|syntax#n:attributes] verwendet werden: ```latte
    @@ -709,13 +709,13 @@ Der Tag kann auch als [n:attribute |syntax#n:attributes] geschrieben werden:
``` -Es ist auch möglich, [einen eigenen Exception-Handler |develop#exception handler] für z.B. die Protokollierung zu definieren: +Es ist auch möglich, einen eigenen [Handler für Ausnahmen|develop#exception handler] zu definieren, zum Beispiel für Logging-Zwecke. `{rollback}` ------------ -Der Block `{try}` kann auch manuell mit `{rollback}` angehalten und übersprungen werden. So müssen Sie nicht alle Eingabedaten im Voraus prüfen und können erst während des Renderings entscheiden, ob es sinnvoll ist, das Objekt zu rendern. +Ein `{try}`-Block kann auch manuell mit `{rollback}` gestoppt und übersprungen werden. Dadurch müssen Sie nicht alle Eingabedaten im Voraus überprüfen und können während des Renderings entscheiden, dass Sie das Objekt überhaupt nicht rendern möchten: ```latte {try} @@ -738,23 +738,23 @@ Variablen .[#toc-variables] `{var}` `{default}` ------------------- -Wir werden neue Variablen in der Vorlage mit dem Tag `{var}` erstellen: +Neue Variablen werden im Template mit dem Tag `{var}` erstellt: ```latte {var $name = 'John Smith'} {var $age = 27} -{* Mehrfache Deklaration *} +{* Mehrfachdeklaration *} {var $name = 'John Smith', $age = 27} ``` -Das Tag `{default}` funktioniert ähnlich, mit dem Unterschied, dass es Variablen nur dann anlegt, wenn sie nicht existieren: +Das Tag `{default}` funktioniert ähnlich, mit dem Unterschied, dass es Variablen nur dann erstellt, wenn sie nicht existieren: ```latte {default $lang = 'cs'} ``` -Sie können auch [Typen von Variablen |type-system] angeben. Im Moment sind sie informativ und Latte prüft sie nicht. +Sie können auch [Variablentypen|type-system] angeben. Diese sind derzeit informativ und werden von Latte nicht überprüft. ```latte {var string $name = $article->getTitle()} @@ -765,7 +765,7 @@ Sie können auch [Typen von Variablen |type-system] angeben. Im Moment sind sie `{parameters}` -------------- -So wie eine Funktion ihre Parameter deklariert, kann eine Vorlage ihre Variablen am Anfang deklarieren: +So wie eine Funktion ihre Parameter deklariert, kann auch ein Template am Anfang seine Variablen deklarieren: ```latte {parameters @@ -775,15 +775,15 @@ So wie eine Funktion ihre Parameter deklariert, kann eine Vorlage ihre Variablen } ``` -Die Variablen `$a` und `$b` ohne Standardwert haben automatisch den Standardwert `null`. Die deklarierten Typen sind immer noch informativ, und Latte überprüft sie nicht. +Variablen `$a` und `$b` ohne angegebenen Standardwert haben automatisch den Standardwert `null`. Die deklarierten Typen sind derzeit informativ und werden von Latte nicht überprüft. -Andere als die deklarierten Variablen werden nicht an die Vorlage übergeben. Dies ist ein Unterschied zum Tag `{default}`. +Andere als die deklarierten Variablen werden nicht in das Template übertragen. Dies unterscheidet es vom Tag `{default}`. `{capture}` ----------- -Mit dem Tag `{capture}` können Sie die Ausgabe in einer Variablen erfassen: +Erfasst die Ausgabe in eine Variable: ```latte {capture $var} @@ -792,10 +792,10 @@ Mit dem Tag `{capture}` können Sie die Ausgabe in einer Variablen erfassen: {/capture} -

Captured: {$var}

+

Erfasst: {$var}

``` -Der Tag kann auch als [n:attribute |syntax#n:attributes] geschrieben werden, wie jeder paarweise Tag: +Das Tag kann, wie jedes Paar-Tag, auch als [n:Attribut|syntax#n:Attribute] geschrieben werden: ```latte
    @@ -803,17 +803,17 @@ Der Tag kann auch als [n:attribute |syntax#n:attributes] geschrieben werden, wie
``` -Die HTML-Ausgabe wird in der Variablen `$var` als `Latte\Runtime\Html` -Objekt gespeichert, um [unerwünschtes Escaping |develop#disabling-auto-escaping-of-variable] beim Drucken [zu vermeiden |develop#disabling-auto-escaping-of-variable]. +Die HTML-Ausgabe wird in der Variable `$var` als `Latte\Runtime\Html`-Objekt gespeichert, um [unerwünschtes Escaping |develop#disabling-auto-escaping-of-variable] beim Ausgeben zu verhindern. -Andere .[#toc-others] -===================== +Sonstiges .[#toc-others] +======================== `{contentType}` --------------- -Verwenden Sie das Tag, um anzugeben, welche Art von Inhalt die Vorlage darstellt. Die Optionen sind: +Mit diesem Tag geben Sie an, welchen Inhaltstyp das Template darstellt. Die Optionen sind: - `html` (Standardtyp) - `xml` @@ -822,16 +822,16 @@ Verwenden Sie das Tag, um anzugeben, welche Art von Inhalt die Vorlage darstellt - `calendar` (iCal) - `text` -Die Verwendung dieses Befehls ist wichtig, weil er die [kontextabhängige Escape-Funktion |safety-first#context-aware-escaping] einstellt und nur dann kann Latte korrekt escapen. Zum Beispiel schaltet `{contentType xml}` in den XML-Modus, `{contentType text}` schaltet das Escapen komplett ab. +Seine Verwendung ist wichtig, da es das [kontextsensitive Escaping |safety-first#context-aware-escaping] festlegt und nur so richtig escapen kann. Zum Beispiel schaltet `{contentType xml}` in den XML-Modus um, `{contentType text}` schaltet das Escaping komplett aus. -Handelt es sich bei dem Parameter um einen MIME-Typ mit vollem Funktionsumfang, wie z. B. `application/xml`, so wird auch ein HTTP-Header `Content-Type` an den Browser gesendet: +Wenn der Parameter ein vollständiger MIME-Typ ist, wie zum Beispiel `application/xml`, wird zusätzlich der HTTP-Header `Content-Type` an den Browser gesendet: ```latte {contentType application/xml} - RSS feed + RSS-Feed ... @@ -843,19 +843,19 @@ Handelt es sich bei dem Parameter um einen MIME-Typ mit vollem Funktionsumfang, `{debugbreak}` -------------- -Gibt die Stelle an, an der die Codeausführung unterbrochen wird. Sie wird zu Debugging-Zwecken verwendet, damit der Programmierer die Laufzeitumgebung überprüfen und sicherstellen kann, dass der Code wie erwartet ausgeführt wird. Er unterstützt [Xdebug |https://xdebug.org]. Zusätzlich können Sie eine Bedingung angeben, unter der der Code unterbrochen werden soll. +Markiert eine Stelle, an der die Programmausführung angehalten und der Debugger gestartet wird, damit der Programmierer die Laufzeitumgebung inspizieren und überprüfen kann, ob das Programm wie erwartet funktioniert. Es unterstützt [Xdebug |https://xdebug.org/]. Eine Bedingung kann hinzugefügt werden, die bestimmt, wann das Programm angehalten werden soll. ```latte -{debugbreak} {* bricht das Programm *} +{debugbreak} {* hält das Programm an *} -{debugbreak $counter == 1} {* bricht das Programm ab, wenn die Bedingung erfüllt ist *} +{debugbreak $counter == 1} {* hält das Programm an, wenn die Bedingung erfüllt ist *} ``` `{do}` ------ -Führt den PHP-Code aus und gibt nichts aus. Wie bei allen anderen Tags ist der PHP-Code ein einzelner Ausdruck, siehe [PHP-Einschränkungen |syntax#PHP Limitations in Latte]. +Führt PHP-Code aus und gibt nichts aus. Wie bei allen anderen Tags mit PHP-Code handelt es sich um einen einzelnen Ausdruck, siehe [PHP-Einschränkungen |syntax#PHP Limitations in Latte]. ```latte {do $num++} @@ -868,80 +868,80 @@ Führt den PHP-Code aus und gibt nichts aus. Wie bei allen anderen Tags ist der Gibt eine Variable oder den aktuellen Kontext aus. ```latte -{dump $name} {* gibt die Variable $name aus *} +{dump $name} {* Gibt die Variable $name aus *} -{dump} {* gibt alle definierten Variablen aus *} +{dump} {* Gibt alle aktuell definierten Variablen aus *} ``` .[caution] -Erfordert das Paket [Tracy |tracy:]. +Erfordert die [Tracy|tracy:]-Bibliothek. `{php}` ------- -Ermöglicht die Ausführung von beliebigem PHP-Code. Das Tag muss mit der Erweiterung [RawPhpExtension |develop#RawPhpExtension] aktiviert werden. +Ermöglicht die Ausführung beliebigen PHP-Codes. Das Tag muss durch die [RawPhpExtension |develop#RawPhpExtension] aktiviert werden. `{spaceless}` ------------- -Entfernt unnötige Leerzeichen. Ähnlich wie der [raumlose |filters#spaceless] Filter. +Entfernt überflüssige Leerzeichen aus der Ausgabe. Funktioniert ähnlich wie der Filter [spaceless|filters#spaceless]. ```latte {spaceless}
    -
  • Hello
  • +
  • Hallo
{/spaceless} ``` -Ausgaben: +Erzeugt ```latte -
  • Hello
+
  • Hallo
``` -Der Tag kann auch als [n:attribute |syntax#n:attributes] geschrieben werden: +Das Tag kann auch als [n:Attribut|syntax#n:attributes] geschrieben werden. `{syntax}` ---------- -Latten-Tags müssen nicht nur in geschweifte Klammern eingeschlossen werden. Sie können ein anderes Trennzeichen wählen, auch zur Laufzeit. Dies geschieht durch `{syntax…}`, wobei der Parameter sein kann: +Latte-Tags müssen nicht nur durch einfache geschweifte Klammern begrenzt sein. Wir können auch einen anderen Begrenzer wählen, sogar zur Laufzeit. Dafür wird `{syntax …}` verwendet, wobei als Parameter angegeben werden kann: - double: `{{...}}` -- off: deaktiviert die Latte-Tags vollständig +- off: schaltet die Verarbeitung von Latte-Tags komplett aus -Mit der Notation n:attribute können wir Latte nur für einen JavaScript-Block deaktivieren: +Mit Hilfe von n:Attributen kann Latte zum Beispiel nur für einen JavaScript-Block ausgeschaltet werden: ```latte ``` -Latte kann sehr bequem innerhalb von JavaScript verwendet werden, man sollte nur Konstrukte wie in diesem Beispiel vermeiden, bei denen der Buchstabe unmittelbar auf `{` folgt, siehe [Latte innerhalb von JavaScript oder CSS |recipes#Latte inside JavaScript or CSS]. +Latte kann sehr bequem auch innerhalb von JavaScript verwendet werden, man muss nur Konstruktionen wie in diesem Beispiel vermeiden, bei denen direkt nach `{` ein Buchstabe folgt, siehe [Latte innerhalb von JavaScript oder CSS|recipes#Latte inside JavaScript or CSS]. -Wenn Sie Latte mit dem `{syntax off}` (d.h. Tag, nicht das n:-Attribut) ausschalten, werden alle Tags bis zu `{/syntax}` strikt ignoriert. +Wenn Sie Latte mit `{syntax off}` ausschalten (d.h. mit einem Tag, nicht mit einem n:Attribut), wird es konsequent alle Tags bis `{/syntax}` ignorieren. {trace} ------- -Wirft eine `Latte\RuntimeException` Exception, deren Stack-Trace im Sinne der Templates ist. Anstatt Funktionen und Methoden aufzurufen, werden also Blöcke aufgerufen und Vorlagen eingefügt. Wenn Sie ein Tool zur übersichtlichen Darstellung von geworfenen Ausnahmen wie [Tracy |tracy:] verwenden, sehen Sie deutlich den Aufrufstapel, einschließlich aller übergebenen Argumente. +Wirft eine `Latte\RuntimeException`, deren Stack-Trace im Geiste der Templates ist. Anstelle von Funktions- und Methodenaufrufen enthält er also Blockaufrufe und Template-Einbindungen. Wenn Sie ein Tool zur übersichtlichen Anzeige von geworfenen Ausnahmen verwenden, wie zum Beispiel [Tracy|tracy:], wird Ihnen der Call Stack einschließlich aller übergebenen Argumente übersichtlich angezeigt. -HTML-Tag-Hilfsmittel .[#toc-html-tag-helpers] -============================================= +Helfer für HTML-Codierer .[#toc-html-tag-helpers] +================================================= n:class ------- -Dank `n:class` ist es sehr einfach, das HTML-Attribut `class` genau so zu generieren, wie Sie es brauchen. +Dank `n:class` können Sie sehr einfach das HTML-Attribut `class` genau nach Ihren Vorstellungen generieren. -Beispiel: Ich möchte, dass das aktive Element die Klasse `active` hat: +Beispiel: Ich brauche, dass das aktive Element die Klasse `active` hat: ```latte {foreach $items as $item} @@ -949,7 +949,7 @@ Beispiel: Ich möchte, dass das aktive Element die Klasse `active` hat: {/foreach} ``` -Außerdem muss das erste Element die Klassen `first` und `main` haben: +Und weiter, dass das erste Element die Klassen `first` und `main` hat: ```latte {foreach $items as $item} @@ -957,7 +957,7 @@ Außerdem muss das erste Element die Klassen `first` und `main` haben: {/foreach} ``` -Und alle Elemente sollten die Klasse `list-item` haben: +Und alle Elemente sollen die Klasse `list-item` haben: ```latte {foreach $items as $item} @@ -965,13 +965,13 @@ Und alle Elemente sollten die Klasse `list-item` haben: {/foreach} ``` -Verblüffend einfach, nicht wahr? +Unglaublich einfach, nicht wahr? n:attr ------ -Das Attribut `n:attr` kann beliebige HTML-Attribute mit der gleichen Eleganz wie [n:class |#n:class] erzeugen. +Das Attribut `n:attr` kann mit der gleichen Eleganz wie [n:class|#n:class] beliebige HTML-Attribute generieren. ```latte {foreach $data as $item} @@ -979,7 +979,7 @@ Das Attribut `n:attr` kann beliebige HTML-Attribute mit der gleichen Eleganz wie {/foreach} ``` -Abhängig von den zurückgegebenen Werten zeigt es z. B: +Abhängig von den zurückgegebenen Werten wird zum Beispiel Folgendes ausgegeben: ```latte @@ -993,25 +993,25 @@ Abhängig von den zurückgegebenen Werten zeigt es z. B: n:tag ----- -Das Attribut `n:tag` kann den Namen eines HTML-Elements dynamisch ändern. +Das Attribut `n:tag` kann den Namen des HTML-Elements dynamisch ändern. ```latte

{$title}

``` -Wenn `$heading === null`, wird das `

` Tag ohne Änderung gedruckt. Andernfalls wird der Elementname in den Wert der Variablen geändert, so dass für `$heading === 'h3'` geschrieben wird: +Wenn `$heading === null` ist, wird der Tag `

` unverändert ausgegeben. Andernfalls wird der Name des Elements auf den Wert der Variable geändert, so dass für `$heading === 'h3'` Folgendes ausgegeben wird: ```latte

...

``` -Da es sich bei Latte um ein sicheres Templating-System handelt, wird überprüft, ob der neue Tag-Name gültig ist und keine unerwünschten oder bösartigen Werte enthält. +Da Latte ein sicheres Template-System ist, überprüft es, ob der neue Tag-Name gültig ist und keine unerwünschten oder schädlichen Werte enthält. n:ifcontent ----------- -Verhindert, dass ein leeres HTML-Element gedruckt wird, d.h. ein Element, das nichts als Leerraum enthält. +Verhindert, dass ein leeres HTML-Element ausgegeben wird, d.h. ein Element, das nichts außer Leerzeichen enthält. ```latte
@@ -1019,7 +1019,7 @@ Verhindert, dass ein leeres HTML-Element gedruckt wird, d.h. ein Element, das ni
``` -Abhängig von den Werten der Variablen `$error` wird dies gedruckt: +Gibt abhängig vom Wert der Variable `$error` aus: ```latte {* $error = '' *} @@ -1033,10 +1033,10 @@ Abhängig von den Werten der Variablen `$error` wird dies gedruckt: ``` -Übersetzung .[#toc-translation] -=============================== +Übersetzungen .[#toc-translation] +================================= -Damit die Übersetzungs-Tags funktionieren, müssen Sie den [Übersetzer ein richten|develop#TranslatorExtension]. Sie können auch den [`translate` |filters#translate] Filter für die Übersetzung verwenden. +Damit die Übersetzungs-Tags funktionieren, muss der [Übersetzer aktiviert werden|develop#TranslatorExtension]. Für Übersetzungen können Sie auch den Filter [`translate`|filters#translate] verwenden. `{_...}` @@ -1045,30 +1045,30 @@ Damit die Übersetzungs-Tags funktionieren, müssen Sie den [Übersetzer ein ric Übersetzt Werte in andere Sprachen. ```latte -{_'Basket'} +{_'Warenkorb'} {_$item} ``` -Es können auch andere Parameter an den Übersetzer übergeben werden: +Dem Übersetzer können auch weitere Parameter übergeben werden: ```latte -{_'Basket', domain: order} +{_'Warenkorb', domain: order} ``` `{translate}` ------------- -Překládá části šablony: +Übersetzt Teile des Templates: ```latte -

{translate}Order{/translate}

+

{translate}Bestellung{/translate}

{translate domain: order}Lorem ipsum ...{/translate} ``` -Der Tag kann auch als [n:attribute |syntax#n:attributes] geschrieben werden, um das Innere des Elements zu übersetzen: +Das Tag kann auch als [n:Attribut|syntax#n:attributes] geschrieben werden, um den Inhalt des Elements zu übersetzen: ```latte -

Order

+

Bestellung

``` From b0de7ecef7a47b14222f0dfd594c4adff514788f Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 4 Sep 2024 21:36:48 +0200 Subject: [PATCH 02/19] latte improved --- .../cs/lets-create-contact-form.texy | 2 +- .../how-to-write-sql-queries-in-latte.texy | 32 ++- latte/cs/cookbook/migration-from-php.texy | 28 +- latte/cs/cookbook/migration-from-twig.texy | 40 ++- latte/cs/cookbook/passing-variables.texy | 28 +- latte/cs/creating-extension.texy | 78 +++--- latte/cs/develop.texy | 71 +++-- latte/cs/extending-latte.texy | 96 ++++--- latte/cs/filters.texy | 261 +++++++++--------- latte/cs/functions.texy | 52 ++-- latte/cs/recipes.texy | 69 +++-- latte/cs/safety-first.texy | 178 ++++++------ latte/cs/sandbox.texy | 67 ++++- latte/cs/syntax.texy | 106 +++---- latte/cs/tags.texy | 159 ++++++----- latte/cs/template-inheritance.texy | 220 ++++++++------- latte/cs/type-system.texy | 35 ++- 17 files changed, 827 insertions(+), 695 deletions(-) diff --git a/best-practices/cs/lets-create-contact-form.texy b/best-practices/cs/lets-create-contact-form.texy index 80503acf55..aa24fb819f 100644 --- a/best-practices/cs/lets-create-contact-form.texy +++ b/best-practices/cs/lets-create-contact-form.texy @@ -131,7 +131,7 @@ Zatím se odesílá prostý textový email obsahující pouze zprávu odeslanou ``` -Zbývá upravit `ContactFacade`, aby tuto šablonu používal. V konstruktoru si vyžádáme třídu `LatteFactory`, která umí vyrobit objekt `Latte\Engine`, tedy [vykreslovač Latte šablon |latte:develop#jak-vykreslit-sablonu]. Pomocí metody `renderToString()` šablonu vykreslíme do souboru, prvním parametrem je cesta k šabloně a druhým jsou proměnné. +Zbývá upravit `ContactFacade`, aby tuto šablonu používal. V konstruktoru si vyžádáme třídu `LatteFactory`, která umí vyrobit objekt `Latte\Engine`, tedy [vykreslovač Latte šablon |latte:develop#vykresleni-sablony]. Pomocí metody `renderToString()` šablonu vykreslíme do souboru, prvním parametrem je cesta k šabloně a druhým jsou proměnné. ```php namespace App\Model; diff --git a/latte/cs/cookbook/how-to-write-sql-queries-in-latte.texy b/latte/cs/cookbook/how-to-write-sql-queries-in-latte.texy index bdfc0feedc..07fb5dec84 100644 --- a/latte/cs/cookbook/how-to-write-sql-queries-in-latte.texy +++ b/latte/cs/cookbook/how-to-write-sql-queries-in-latte.texy @@ -2,9 +2,9 @@ Jak psát SQL queries v Latte? ***************************** .[perex] -Latte se může hodit i pro generování opravdu složitých SQL dotazů. +Latte může být užitečným nástrojem i pro generování komplexních SQL dotazů, což zvyšuje jejich čitelnost a udržovatelnost. -Pokud vytvoření SQL dotazu obsahuje řadu podmínek a proměnných, může být opravdu přehlednější ho napsat v Latte. Velmi jednoduchý příklad: +Když SQL dotaz obsahuje mnoho podmínek a proměnných, může být jeho zápis v Latte přehlednější a flexibilnější. Zde je jednoduchý příklad demonstrující tuto výhodu: ```latte SELECT users.* FROM users @@ -14,8 +14,13 @@ SELECT users.* FROM users WHERE groups.name = 'Admins' {ifset $country} AND country.name = {$country} {/ifset} ``` -Pomocí `$latte->setContentType()` řekneme Latte, aby k obsahu přistupovalo jako k prostému textu (nikoliv jako k HTML) a dále -připravíme escapovací funkci, která bude řetězce escapovat přímo databázovým driverem: +Pro správné fungování je třeba provést několik kroků: + +1. Nastavení typu obsahu: pomocí `$latte->setContentType()` informujeme Latte, že obsah má být zpracován jako prostý text, nikoliv jako HTML. + +2. Definice escapovací funkce: vytvoříme vlastní escapovací funkci, která bude řetězce escapovat přímo pomocí databázového driveru. Tím zajistíme bezpečnost proti SQL injection. + +Zde je ukázka implementace těchto kroků: ```php $db = new PDO(/* ... */); @@ -31,13 +36,28 @@ $latte->addFilter('escape', fn($val) => match (true) { }); ``` -Použití by vypadalo takto: +Tato escapovací funkce zajišťuje správné ošetření různých datových typů: +- Řetězce jsou escapovány pomocí metody `quote()` databázového driveru. +- Čísla (celá i s plovoucí desetinnou čárkou) jsou převedena na řetězce. +- Booleovské hodnoty jsou převedeny na '1' nebo '0'. +- Null hodnoty jsou převedeny na 'NULL'. +- Pro nepodporované typy je vyhozena výjimka. + +Použití v praxi by pak vypadalo takto: ```php $sql = $latte->renderToString('query.sql.latte', ['country' => $country]); $result = $db->query($sql); ``` -*Uvedený příklad vyžaduje Latte v3.0.5 nebo vyšší.* +Tento přístup umožňuje: +1. Dynamické sestavování SQL dotazů s využitím logiky Latte. +2. Bezpečné vkládání proměnných do dotazu díky vlastní escapovací funkci. +3. Lepší čitelnost a udržovatelnost komplexních SQL dotazů. + +.[note] +Tento příklad vyžaduje Latte ve verzi 3.0.5 nebo novější. + +Využití Latte pro generování SQL dotazů může výrazně zjednodušit práci s komplexními dotazy, zejména v situacích, kdy se dotaz dynamicky mění na základě různých podmínek. Zároveň tento přístup pomáhá udržet kód čistý a snadno upravitelný. {{leftbar: /@left-menu}} diff --git a/latte/cs/cookbook/migration-from-php.texy b/latte/cs/cookbook/migration-from-php.texy index f17181af91..2bec5df959 100644 --- a/latte/cs/cookbook/migration-from-php.texy +++ b/latte/cs/cookbook/migration-from-php.texy @@ -2,27 +2,30 @@ Migrace z PHP do Latte ********************** .[perex] -Převádíte starý projekt napsaný v čistém PHP do Latte? Máme pro vás nástroj, které vám migraci usnadní. [Vyzkoušejte jej online |https://php2latte.nette.org]. +Převádíte starší projekt napsaný v čistém PHP na Latte? Máme pro vás nástroj, který tento proces výrazně zjednoduší. [Vyzkoušejte jej online |https://php2latte.nette.org]. -Nástroj si můžete stáhnout z [GitHubu|https://github.com/nette/latte-tools] nebo nainstalovat pomocí Composeru: +Tento užitečný nástroj můžete získat dvěma způsoby: + +1. Stáhnout z [GitHubu|https://github.com/nette/latte-tools] +2. Nainstalovat pomocí Composeru: ```shell composer create-project latte/tools ``` -Převodník nepoužívá jednoduché záměny pomocí regulárních výrazů, naopak využívá přímo PHP parser, takže si poradí s jakkoliv složitou syntaxí. +Na rozdíl od jednoduchých nástrojů využívajících regulární výrazy, tento převodník používá sofistikovaný PHP parser. Díky tomu si poradí i s komplexní PHP syntaxí. -K převodu z PHP do Latte slouží skript `php-to-latte.php`: +Pro převod z PHP do Latte použijte skript `php-to-latte.php`: ```shell php-to-latte.php input.php [output.latte] ``` -Příklad -------- +Příklad použití +--------------- -Vstupní soubor může vypadat třeba takto (jde o část kódu fóra PunBB): +Podívejme se na konkrétní příklad. Níže je ukázka vstupního PHP souboru (část kódu fóra PunBB): ```php

@@ -48,7 +51,7 @@ foreach ($result as $cur_group) {
``` -Vygeneruje tuto šablonu: +Po zpracování nástrojem získáme následující Latte šablonu: ```latte

{$lang_common['User list']}

@@ -69,4 +72,13 @@ Vygeneruje tuto šablonu: ``` +Hlavní výhody tohoto převodu: + +1. **Čistší syntaxe**: Latte šablona je čitelnější a snáze udržovatelná. +2. **Automatické escapování**: Latte automaticky escapuje výstup, čímž zvyšuje bezpečnost (např. `htmlspecialchars()` již není potřeba). +3. **Lepší struktura**: Latte tagy (`{foreach}`, `{if}`) jasně oddělují logiku od prezentace. +4. **Zjednodušení**: Odstraňuje nutnost explicitního výpisu pomocí `echo`. + +Tento nástroj významně urychluje a zjednodušuje proces migrace z PHP na Latte, což vám umožní rychleji modernizovat vaše projekty a využít všech výhod, které Latte nabízí. + {{leftbar: /@left-menu}} diff --git a/latte/cs/cookbook/migration-from-twig.texy b/latte/cs/cookbook/migration-from-twig.texy index 4ded46f341..8a7fb5bd9c 100644 --- a/latte/cs/cookbook/migration-from-twig.texy +++ b/latte/cs/cookbook/migration-from-twig.texy @@ -2,37 +2,40 @@ Migrace z Twigu do Latte ************************ .[perex] -Převádíte projekt napsaný v Twigu do modernějšího Latte? Máme pro vás nástroj, které vám migraci usnadní. [Vyzkoušejte jej online |https://twig2latte.nette.org]. +Převádíte projekt z Twigu na modernější a mnohem bezpečnější Latte? Máme pro vás nástroj, který tento proces výrazně zjednoduší. [Vyzkoušejte jej online |https://twig2latte.nette.org]. -Nástroj si můžete stáhnout z [GitHubu|https://github.com/nette/latte-tools] nebo nainstalovat pomocí Composeru: +Tento užitečný nástroj je dostupný dvěma způsoby: + +1. Stažením z [GitHubu|https://github.com/nette/latte-tools] +2. Instalací pomocí Composeru: ```shell composer create-project latte/tools ``` -Převodník nepoužívá jednoduché záměny pomocí regulárních výrazů, naopak využívá přímo Twig parser, takže si poradí s jakkoliv složitou syntaxí. +Na rozdíl od jednoduchých nástrojů využívajících regulární výrazy, tento převodník používá sofistikovaný Twig parser. Díky tomu si poradí i s komplexní Twig syntaxí. -K převodu z Twigu do Latte slouží skript `twig-to-latte.php`: +Pro převod z Twigu do Latte použijte skript `twig-to-latte.php`: ```shell twig-to-latte.php input.twig.html [output.latte] ``` -Konverze --------- +Konverze a její specifika +------------------------- -Převod předpokládá ruční úpravu výsledku, protože konverzi nelze provést jednoznačně. Twig používá tečkovou syntax, kde `{{ a.b }}` může znamenat `$a->b`, `$a['b']` nebo `$a->getB()`, což nelze rozlišit při kompilaci. Převaděč proto vše převádí na `$a->b`. +Je důležité poznamenat, že převod může vyžadovat ruční úpravy výsledku. Důvodem je, že některé konstrukce v Twigu nelze jednoznačně převést do Latte. Například, Twig používá tečkovou syntax, kde `{{ a.b }}` může znamenat `$a->b`, `$a['b']` nebo `$a->getB()`. Tento rozdíl nelze rozlišit při kompilaci, proto převaděč vše převádí na `$a->b`. -Některé funkce, filtry nebo tagy nemají obdobu v Latte, nebo se mohou chovat mírně jinak. +Některé funkce, filtry nebo tagy v Twigu nemají přímou obdobu v Latte, nebo se mohou chovat mírně odlišně. To je další důvod, proč může být potřeba ruční úprava po automatickém převodu. -Příklad -------- +Příklad použití +--------------- -Vstupní soubor může vypadat třeba takto: +Podívejme se na konkrétní příklad. Níže je ukázka vstupního Twig souboru: -```latte +```twig {% use "blocks.twig" %} @@ -54,7 +57,7 @@ Vstupní soubor může vypadat třeba takto: ``` -Po konverzi do Latte získáme tuto šablonu: +Po konverzi do Latte získáme následující šablonu: ```latte {import 'blocks.latte'} @@ -78,4 +81,15 @@ Po konverzi do Latte získáme tuto šablonu: ``` +Hlavní rozdíly a výhody po převodu: + +1. **Změna syntaxe**: Twig používá `{% ... %}` pro logiku a `{{ ... }}` pro výpis, zatímco Latte používá jednotnou `{ ... }` syntaxi +2. **Bloky**: `{% block ... %}` se mění na `{block ...}` +3. **Cykly**: `{% for ... %}` se převádí na `{foreach ...}` +4. **Podmínky**: `{% if ... %}` zůstává podobné, ale používá se `{if ...}`. +5. **Přístup k proměnným**: Tečková notace `item.caption` se mění na objektovou notaci `$item->caption` +6. **Import**: `{% use ... %}` se mění na `{import ...}` + +Tento nástroj významně urychluje a zjednodušuje proces migrace z Twigu na Latte. Umožňuje vám rychle modernizovat vaše projekty a využít všech výhod, které Latte nabízí, včetně jeho výkonu a flexibilnity. Nezapomeňte však po automatickém převodu zkontrolovat a případně upravit výsledný kód, aby plně odpovídal vašim potřebám a specifikům vašeho projektu. + {{leftbar: /@left-menu}} diff --git a/latte/cs/cookbook/passing-variables.texy b/latte/cs/cookbook/passing-variables.texy index b4840427c2..7bb477af7a 100644 --- a/latte/cs/cookbook/passing-variables.texy +++ b/latte/cs/cookbook/passing-variables.texy @@ -1,14 +1,14 @@ Předávání proměnných napříč šablonami ************************************* -Tento průvodce vám vysvětlí, jak se proměnné předávají mezi šablonami v Latte pomocí různých tagů jako `{include}`, `{import}`, `{embed}`, `{layout}`, `{sandbox}` a dalších. Dozvíte se také, jak pracovat s proměnnými v tagu `{block}` a `{define}`, a k čemu slouží značka `{parameters}`. +Tento průvodce objasňuje, jak se v Latte předávají proměnné mezi šablonami pomocí různých tagů jako `{include}`, `{import}`, `{embed}`, `{layout}`, `{sandbox}` a dalších. Dozvíte se také, jak pracovat s proměnnými v tagu `{block}` a `{define}`, a k čemu slouží značka `{parameters}`. Typy proměnných --------------- -Proměnné v Latte můžeme rozdělit do tří kategorií podle toho, jak a kde jsou definovány: +V Latte rozlišujeme tři kategorie proměnných podle jejich definice a dostupnosti: -**Vstupní proměnné** jsou ty, které jsou do šablony předávány zvenčí, například z PHP skriptu nebo pomocí tagu jako `{include}`. +**Vstupní proměnné** jsou předávány do šablony zvenčí, typicky z PHP skriptu nebo pomocí tagů jako `{include}`. ```php $latte->render('template.latte', ['userName' => 'Jan', 'userAge' => 30]); @@ -45,7 +45,7 @@ Tag `{block}` se používá k definování opakovaně použitelných bloků kód `{define}` ---------- -Tag `{define}` slouží k vytváření bloků, které se renderují až po jejich zavolání pomocí `{include}`. Proměnné dostupné uvnitř těchto bloků závisí na tom, zda jsou v definici uvedeny parametry. Pokud ano, přístup mají jen k těmto parametrům. Pokud ne, přístup mají ke všem vstupním proměnným šablony, ve které jsou bloky definovány. +Tag `{define}` vytváří bloky, které se renderují až po jejich explicitním zavolání pomocí `{include}`. Dostupnost proměnných uvnitř těchto bloků závisí na přítomnosti parametrů v definici. S parametry mají bloky přístup pouze k těmto parametrům. Bez parametrů mají přístup ke všem vstupním proměnným šablony, ve které jsou definovány. ```latte {define hello} @@ -60,7 +60,7 @@ Tag `{define}` slouží k vytváření bloků, které se renderují až po jejic `{parameters}` -------------- -Tag `{parameters}` slouží k explicitní deklaraci očekávaných vstupních proměnných na začátku šablony. Tímto způsobem lze snadno dokumentovat očekávané proměnné a jejich datové typy. Také je možné definovat výchozí hodnoty. +Tag `{parameters}` slouží k explicitní deklaraci očekávaných vstupních proměnných na začátku šablony. Tímto způsobem lze efektivně dokumentovat očekávané proměnné a jejich datové typy. Umožňuje také definovat výchozí hodnoty. ```latte {parameters int $age, string $name = 'neznámé'} @@ -70,7 +70,7 @@ Tag `{parameters}` slouží k explicitní deklaraci očekávaných vstupních pr `{include file}` ---------------- -Tag `{include file}` slouží k vložení celé šablony. Této šabloně se předávají jak vstupní proměnné šablony, ve které je značka použita, tak proměnné v ní explicitně definované. Cílová šablona ale může rozsah omezit pomocí `{parameters}`. +Tag `{include file}` vkládá celou šablonu. Do vkládané šablony se předávají vstupní proměnné šablony, ve které je značka použita, spolu s explicitně definovanými proměnnými. Cílová šablona může omezit rozsah přijímaných proměnných pomocí `{parameters}`. ```latte {include 'profile.latte', userId: $user->id} @@ -79,7 +79,7 @@ Tag `{include file}` slouží k vložení celé šablony. Této šabloně se př `{include block}` ----------------- -Když vkládáte blok definovaný ve stejné šabloně, předávají se do něj všechny okolní a explicitně definované proměnné: +Při vkládání bloku definovaného ve stejné šabloně se do něj předávají všechny okolní a explicitně definované proměnné: ```latte {define blockName} @@ -90,9 +90,9 @@ Když vkládáte blok definovaný ve stejné šabloně, předávají se do něj {include blockName} ``` -V tomto příkladu se proměnné `$name` a `$age` předají do bloku `blockName`. Stejným způsobem se chová i `{include parent}`. +V tomto příkladu jsou proměnné `$name` a `$age` předány do bloku `blockName`. Stejně se chová i `{include parent}`. -Při vkládání bloku z jiné šablony jsou předávány pouze vstupní proměnné a explicitně definované. Okolní proměnné nejsou automaticky dostupné. +Při vkládání bloku z jiné šablony se předávají pouze vstupní proměnné a explicitně definované proměnné. Okolní proměnné nejsou automaticky dostupné. ```latte {include blockInOtherTemplate, name: $name, age: $age} @@ -101,7 +101,7 @@ Při vkládání bloku z jiné šablony jsou předávány pouze vstupní proměn `{layout}` nebo `{extends}` --------------------------- -Tyto tagy definují layout, do kterého se předávají vstupní proměnné podřízené šablony a dále proměnné vytvořené v kódu před bloky: +Tyto tagy definují layout, do kterého se předávají vstupní proměnné podřízené šablony a proměnné vytvořené v kódu před bloky: ```latte {layout 'layout.latte'} @@ -134,7 +134,7 @@ Naopak v blocích uvnitř `{embed}` je přístup ke všem okolním proměnným: {var $name = 'Jan'} {embed 'menu.latte', items: $menuItems} {block foo} - {$nam} + {$name} {/block} {/embed} ``` @@ -142,7 +142,7 @@ Naopak v blocích uvnitř `{embed}` je přístup ke všem okolním proměnným: `{import}` ---------- -Tag `{import}` se využívá pro načítání bloků z jiných šablon. Přenáší se jak vstupní, tak explicitně deklarované proměnné do importovaných bloků. +Tag `{import}` se používá pro načítání bloků z jiných šablon. Do importovaných bloků se předávají jak vstupní, tak explicitně deklarované proměnné. ```latte {import 'buttons.latte'} @@ -151,11 +151,13 @@ Tag `{import}` se využívá pro načítání bloků z jiných šablon. Přená `{sandbox}` ----------- -Tag `{sandbox}` izoluje šablonu pro bezpečné zpracování. Proměnné jsou předávány výhradně explicitně. +Tag `{sandbox}` izoluje šablonu pro bezpečné zpracování. Proměnné jsou předávány výhradně explicitně, což zvyšuje kontrolu nad daty vstupujícími do izolovaného prostředí. ```latte {sandbox 'secure.latte', data: $secureData} ``` +Tento mechanismus umožňuje přesnou kontrolu nad tím, jaká data jsou dostupná v izolované šabloně, což je užitečné pro zpracování potenciálně nebezpečného obsahu. + {{leftbar: /@left-menu}} diff --git a/latte/cs/creating-extension.texy b/latte/cs/creating-extension.texy index 24ff44bc2a..7608d85ebc 100644 --- a/latte/cs/creating-extension.texy +++ b/latte/cs/creating-extension.texy @@ -2,25 +2,24 @@ Vytváříme Extension ******************* .[perex] -Tzv. rozšíření je opakovatelně použitelná třída, která může definovat vlastní značky, filtry, funkce, providery, atd. +Rozšíření (extension) je znovupoužitelná třída, která může definovat vlastní značky, filtry, funkce, providery a další prvky pro Latte. Vytváříme je, když chceme své úpravy Latte použít v různých projektech nebo je sdílet s komunitou. -Rozšíření vytváříme tehdy, pokud chceme své úpravy Latte znovu použít v různých projektech nebo je sdílet s ostatními. -Je užitečné vytvářet rozšíření i pro každý webový projekt, které bude obsahovat všechny specifické značky a filtry, které chcete v šablonách projektu využívat. +Rozšíření je užitečné vytvořit i pro každý webový projekt. Může obsahovat všechny specifické značky a filtry, které chcete v šablonách projektu využívat. Třída rozšíření =============== -Rozšíření je třída dědící od [api:Latte\Extension]. Do Latte se registruje pomocí `addExtension()` (případně [konfiguračním souborem |application:configuration#Šablony Latte]): +Rozšíření je třída dědící od [api:Latte\Extension]. Do Latte se registruje pomocí `addExtension()` nebo [konfiguračním souborem |application:configuration#Šablony Latte]: ```php $latte = new Latte\Engine; $latte->addExtension(new MyLatteExtension); ``` -Pokud zaregistrujete vícero rozšíření a ty definují stejně pojmenované tagy, filtry nebo funkce, vyhrává poslední přidané rozšíření. Z toho také plyne, že vaše rozšíření mohou přepisovat nativní značky/filtry/funkce. +Pokud zaregistrujete více rozšíření definujících stejně pojmenované tagy, filtry nebo funkce, platí poslední přidané. To znamená, že vaše rozšíření může přepisovat nativní značky/filtry/funkce. -Kdykoliv v třídě provedete změnu a není vypnutý auto-refresh, Latte automaticky překompiluje vaše šablony. +Kdykoliv provedete změnu ve třídě rozšíření a není vypnutý auto-refresh, Latte automaticky překompiluje vaše šablony. Třída může implementovat kteroukoliv z následujících metod: @@ -76,11 +75,13 @@ abstract class Extension Pro představu, jak rozšíření vypadá, se podívejte na vestavěné "CoreExtension":https://github.com/nette/latte/blob/master/src/Latte/Essential/CoreExtension.php. +Nyní si podrobněji rozebereme jednotlivé metody: + beforeCompile(Latte\Engine $engine): void .[method] --------------------------------------------------- -Volá se před kompilací šablony. Metodu lze využít např. pro inicializace související s kompilací. +Tato metoda se volá před kompilací šablony. Můžete ji využít například pro inicializace související s kompilací. getTags(): array .[method] @@ -102,18 +103,18 @@ public function getTags(): array Značka `n:baz` představuje ryzí n:atribut, tj. jde o značku, kterou lze zapisovat pouze jako atribut. -V případě značek `foo` a `bar` Latte samo rozezná, zda jsou párové, a pokud ano, bude je možné automaticky zapisovat i pomocí n:atributů, včetně variant s prefixy `n:inner-foo` a `n:tag-foo`. +Latte automaticky rozpozná, zda jsou značky `foo` a `bar` párové. Pokud ano, bude je možné zapisovat i pomocí n:atributů, včetně variant s prefixy `n:inner-foo` a `n:tag-foo`. -Pořadí provádění takovýchto n:atributů je dáno jejich pořadím v poli vráceném `getTags()`. Tedy `n:foo` se provede vždy před `n:bar`, i kdyby byly atributy v HTML značce uvedeny v opačném pořadí jako `
`. +Pořadí provádění n:atributů je dáno jejich pořadím v poli vráceném `getTags()`. Tedy `n:foo` se provede vždy před `n:bar`, i kdyby byly atributy v HTML značce uvedeny v opačném pořadí. -Pokud potřebujete stanovit pořadí n:atributů napříč více rozšířeními, použijte pomocnou metodu `order()`, kde parametr `before` a nebo `after` určuje, před nebo za kterými značkami se daná značka zařadí. +Pro stanovení pořadí n:atributů napříč více rozšířeními použijte pomocnou metodu `order()`. Parametry `before` a `after` určují, před nebo za kterými značkami se daná značka zařadí: ```php public function getTags(): array { return [ - 'foo' => self::order([FooNode::class, 'create'], before: 'bar')] - 'bar' => self::order([BarNode::class, 'create'], after: ['block', 'snippet'])] + 'foo' => self::order([FooNode::class, 'create'], before: 'bar'), + 'bar' => self::order([BarNode::class, 'create'], after: ['block', 'snippet']), ]; } ``` @@ -122,7 +123,7 @@ public function getTags(): array getPasses(): array .[method] ---------------------------- -Volá se při kompilaci šablony. Vrací asociativní pole *název pass => callable*, což jsou funkce představující tzv. [#průchody kompilátoru], které procházejí a modifikujou AST. +Volá se při kompilaci šablony. Vrací asociativní pole *název pass => callable*, což jsou funkce představující tzv. [#průchody kompilátoru], které procházejí a modifikují AST. Opět je možné využít pomocnou metodu `order()`. Hodnotou parametrů `before` nebo `after` může být `'*'` s významem před/za všemi. @@ -141,7 +142,7 @@ public function getPasses(): array beforeRender(Latte\Engine $engine): void .[method] -------------------------------------------------- -Volá se před každým vykreslením šablony. Metodu lze využít např. pro inicializaci proměnných používaných při vykreslování. +Volá se před každým vykreslením šablony. Metodu lze využít například pro inicializaci proměnných používaných při vykreslování. getFilters(): array .[method] @@ -181,7 +182,7 @@ public function getFunctions(): array getProviders(): array .[method] ------------------------------- -Volá se před vykreslením šablony. Vrací pole tzv. providers, což jsou zpravidla objekty, které za běhu využívají tagy. Přistupují k nim přes `$this->global->...`. +Volá se před vykreslením šablony. Vrací pole tzv. providerů, což jsou zpravidla objekty, které za běhu využívají tagy. Přistupují k nim přes `$this->global->...`. ```php public function getProviders(): array @@ -198,7 +199,7 @@ public function getProviders(): array getCacheKey(Latte\Engine $engine): mixed .[method] -------------------------------------------------- -Volá se před vykreslením šablony. Vrácená hodnota se stane součástí klíče, jehož hash je obsažen v názvu souboru se zkompilovanou šablonou. Tedy pro různé vrácené hodnoty Latte vygeneruje různé soubory v cache. +Volá se před vykreslením šablony. Vrácená hodnota se stane součástí klíče, jehož hash je obsažen v názvu souboru se zkompilovanou šablonou. Pro různé vrácené hodnoty tedy Latte vygeneruje různé soubory v cache. Jak Latte funguje? @@ -208,20 +209,19 @@ Pro pochopení toho, jak definovat vlastní tagy nebo compiler passes, je nezbyt Kompilace šablon v Latte probíhá zjednodušeně takto: -- Nejprve **lexer** tokenizuje zdrojový kód šablony na malé části (tokeny) pro snadnější zpracování. -- Poté **parser** převede proud tokenů na smysluplný strom uzlů (abstraktní syntaktický strom, AST). -- Nakonec překladač **vygeneruje** z AST třídu PHP, která vykresluje šablonu, a uloží ji do cache. +1. **Lexer** tokenizuje zdrojový kód šablony na menší části (tokeny) pro snadnější zpracování. +2. **Parser** převede proud tokenů na smysluplný strom uzlů (abstraktní syntaktický strom, AST). +3. **Překladač** vygeneruje z AST třídu PHP, která vykresluje šablonu, a uloží ji do cache. Ve skutečnosti je kompilace o něco složitější. Latte **má dva** lexery a parsery: jeden pro HTML šablonu a druhý pro PHP-like kód uvnitř tagů. A také parsování neprobíhá až po tokenizaci, ale lexer i parser běží paralelně ve dvou "vláknech" a koordinují se. Je to raketová věda :-) -Dále své parsovací rutiny mají i všechny tagy. Když parser narazí na tag, zavolá jeho parsovací funkci (vrací je [Extension::getTags()|#getTags]). -Jejich úkolem je naparsovat argumenty značky a v případě párových značek i vnitřní obsah. Vrací *uzel*, který se stane součástí AST. Podrobně v části [#Parsovací funkce tagu]. +Každý tag má svou parsovací rutinu. Když parser narazí na tag, zavolá jeho parsovací funkci (vrací je [Extension::getTags()|#getTags]). Jejich úkolem je naparsovat argumenty značky a v případě párových značek i vnitřní obsah. Vrací *uzel*, který se stane součástí AST. Podrobně v části [#Parsovací funkce tagu]. -Když parser dokončí práci, máme kompletní AST reprezentující šablonu. Kořenovým uzlem je `Latte\Compiler\Nodes\TemplateNode`. Jednotlivé uzly uvnitř stromu pak reprezentují nejen tagy, ale i HTML elementy, jejich atributy, všechny výrazy použité uvnitř značek atd. +Po dokončení parsování máme kompletní AST reprezentující šablonu. Kořenovým uzlem je `Latte\Compiler\Nodes\TemplateNode`. Jednotlivé uzly uvnitř stromu reprezentují nejen tagy, ale i HTML elementy, jejich atributy, všechny výrazy použité uvnitř značek atd. Poté přicházejí na řadu tzv. [#Průchody kompilátoru], což jsou funkce (vrací je [Extension::getPasses()|#getPasses]), které modifikují AST. -Celý proces od načtení obsahu šablony přes parsování až po vygenerování výsledného souboru se dá sekvenčně vykonat tímto kódem, se kterým můžete experimentovat a dumpovat si jednotlivé mezikroky: +Celý proces od načtení obsahu šablony přes parsování až po vygenerování výsledného souboru můžete sekvenčně vykonat tímto kódem: ```php $latte = new Latte\Engine; @@ -285,19 +285,21 @@ Vlastní tagy K definování nové značky jsou zapotřebí tři kroky: -- definování [#parsovací funkce tagu] (zodpovědná za parsování tagu do uzlu) -- vytvoření třídy uzlu (zodpovědné za [#generování PHP kódu] a [#procházení AST]) -- registrace tagu pomocí [Extension::getTags()|#getTags] +1. Definování [#parsovací funkce tagu] (zodpovědná za parsování tagu do uzlu) +2. Vytvoření třídy uzlu (zodpovědné za [#generování PHP kódu] a [#procházení AST]) +3. Registrace tagu pomocí [Extension::getTags()|#getTags] Parsovací funkce tagu --------------------- -Parsování tagů ma na starosti jeho parsovací funkce (ta, kterou vrací [Extension::getTags()|#getTags]). Jejím úkolem je naparsovat a zkontrolovat případné argumenty uvnitř značky (k tomu využívá TagParser). -A dále, pokud je značka párová, požádá TemplateParser o naparsování a vrácení vnitřního obsahu. -Funkce vytvoří a vrátí uzel, který je zpravidla potomkem `Latte\Compiler\Nodes\StatementNode`, a ten se stane součástí AST. +Parsování tagů má na starosti jeho parsovací funkce (ta, kterou vrací [Extension::getTags()|#getTags]). Jejím úkolem je: + +1. Naparsovat a zkontrolovat případné argumenty uvnitř značky (k tomu využívá TagParser). +2. Pokud je značka párová, požádat TemplateParser o naparsování a vrácení vnitřního obsahu. +3. Vytvořit a vrátit uzel, který je zpravidla potomkem `Latte\Compiler\Nodes\StatementNode`, a který se stane součástí AST. -Pro každý uzel si vytváříme třídu, což uděláme teď hned a parsovací funkci do ní elegantně umístíme jako statickou továrnu. Jako příklad si zkusíme vytvořit známý tag `{foreach}`: +Pro každý uzel vytváříme třídu a parsovací funkci do ní umístíme jako statickou továrnu. Jako příklad si vytvoříme známý tag `{foreach}`: ```php use Latte\Compiler\Nodes\StatementNode; @@ -338,7 +340,7 @@ a dále nízkoúrovňový [api:Latte\Compiler\TokenStream] operující přímo s - `$tag->parser->stream->consume(...): Token` - `$tag->parser->stream->tryConsume(...): ?Token` -Latte drobnými způsoby rozšiřuje syntaxi PHP, například o modifikátory, zkrácené ternání operátory, nebo umožňuje jednoduché alfanumerické řetězce psát bez uvozovek. Proto používáme termím *PHP-like* místo PHP. Tudíž metoda `parseExpression()` naparsuje např. `foo` jako `'foo'`. +Latte mírně rozšiřuje syntaxi PHP, například o modifikátory, zkrácené ternání operátory, nebo umožňuje jednoduché alfanumerické řetězce psát bez uvozovek. Proto používáme termín *PHP-like* místo PHP. Metoda `parseExpression()` tedy naparsuje např. `foo` jako `'foo'`. Vedle toho *unquoted-řetězec* je speciálním případem řetězce, který také nemusí být v uvozovkách, ale zároveň nemusí být ani alfanumerický. Jde třeba o cestu k souboru ve značce `{include ../file.latte}`. K jeho naparsování slouží metoda `parseUnquotedStringOrExpression()`. .[note] @@ -416,7 +418,7 @@ Každý uzel musí implementovat metodu `print()`. Vrací PHP kód vykreslujíc Metoda `format(string $mask, ...$args)` akceptuje v masce tyto placeholdery: - `%node` vypisuje Node -- `%dump` vyexporuje hodnotu do PHP +- `%dump` vyexportuje hodnotu do PHP - `%raw` vloží přímo text bez jakékoliv transformace - `%args` vypíše ArrayNode jako argumenty volání funkce - `%line` vypíše komentář s číslem řádku @@ -474,7 +476,7 @@ Všimněte si, že `getIterator()` vrací reference. Právě díky tomu mohou *n .[warning] Pokud má uzel poduzly, je nezbytné tuto metodu implementovat a všechny poduzly zpřístupnit. Jinak by mohla vzniknout bezpečnostní díra. Například režim sandboxu by nebyl schopen kontrolovat poduzly a zajistit, aby v nich nebyly volány nepovolené konstrukce. -Protože klíčové slovo `yield` musí být přítomno v těle metody i pokud nemá žádné podřízené uzly, zapište ji takto: +Pokud uzel nemá žádné poduzly, implementujte metodu takto: ```php public function &getIterator(): \Generator @@ -498,7 +500,7 @@ Pokud vytváříte nový tag pro Latte, je žádoucí, abyste pro něj vytvořil $node = new AuxiliaryNode( // tělo metody print(): fn(PrintContext $context, $argNode) => $context->format('myFunc(%node)', $argNode), - // uzly zpřístupnění přes getIterator() a také předané do metody print(): + // uzly zpřístupněné přes getIterator() a také předané do metody print(): [$argNode], ); ``` @@ -544,9 +546,9 @@ $ast = (new NodeTraverser)->traverse( ); ``` -Modul AST může snadno obsahovat tisíce uzlů a procházení všech uzlů může být pomalé. V některých případech je možné se úplnému procházení vyhnout. +AST může snadno obsahovat tisíce uzlů a procházení všech uzlů může být časově náročné. V některých případech je možné se úplnému procházení vyhnout. -Pokud ve stromu hledáte všechny uzly `Html\ElementNode`, pak víte, že jakmile jednou uvidíte uzel `Php\ExpressionNode`, nemá smysl kontrolovat také všechny jeho podřízené uzly, protože HTML nemůže být uvnitř ve výrazech. V takovém případě můžete traverseru přikázat, aby do uzlu třídy neprováděl rekurzi: +Pokud ve stromu hledáte všechny uzly `Html\ElementNode`, pak víte, že jakmile jednou uvidíte uzel `Php\ExpressionNode`, nemá smysl kontrolovat také všechny jeho podřízené uzly, protože HTML nemůže být uvnitř výrazů. V takovém případě můžete traverseru přikázat, aby do uzlu třídy neprováděl rekurzi: ```php $ast = (new NodeTraverser)->traverse( @@ -578,7 +580,7 @@ $ast = (new NodeTraverser)->traverse( Pomocníci pro uzly ------------------ -Třída [api:Latte\Compiler\NodeHelpers] poskytuje některé metody, které mohou najít uzly AST, které buď splňují určitou podmínku atd. Několik příkladů: +Třída [api:Latte\Compiler\NodeHelpers] poskytuje některé metody, které mohou najít uzly AST, které splňují určitou podmínku atd. Několik příkladů: ```php use Latte\Compiler\NodeHelpers; @@ -595,3 +597,5 @@ $value = NodeHelpers::toValue($node); // převede statický textový uzel na řetězec $text = NodeHelpers::toText($node); ``` + +Tímto způsobem můžete efektivně procházet a manipulovat s AST stromem ve vašich rozšířeních pro Latte. diff --git a/latte/cs/develop.texy b/latte/cs/develop.texy index 19e8f2d33a..db494d990c 100644 --- a/latte/cs/develop.texy +++ b/latte/cs/develop.texy @@ -5,7 +5,7 @@ Vývojářské postupy Instalace ========= -Nejlepší způsob, jak nainstalovat Latte, je pomocí Composeru: +Nejlepší způsob instalace Latte je pomocí Composeru: ```shell composer require latte/latte @@ -18,22 +18,22 @@ Podporované verze PHP (platí pro poslední setinkové verze Latte): | Latte 3.0 | PHP 8.0 – 8.2 -Jak vykreslit šablonu -===================== +Vykreslení šablony +================== Jak vykreslit šablonu? Stačí k tomu tento jednoduchý kód: ```php $latte = new Latte\Engine; -// adresář pro cache +// nastavení adresáře pro cache $latte->setTempDirectory('/path/to/tempdir'); $params = [ /* proměnné šablony */ ]; -// or $params = new TemplateParameters(/* ... */); +// nebo $params = new TemplateParameters(/* ... */); -// kresli na výstup +// vykreslení na výstup $latte->render('template.latte', $params); -// kresli do proměnné +// vykreslení do proměnné $output = $latte->renderToString('template.latte', $params); ``` @@ -46,23 +46,21 @@ Ukázky použití najdete také v repozitáři [Latte examples |https://github.c Výkon a cache ============= -Šablony v Latte jsou nesmírně rychlé, Latte je totiž kompiluje přímo do PHP kódu a ukládá do cache na disk. Nemají tedy žádnou režii navíc oproti šablonám psaným v čistém PHP. +Šablony v Latte jsou extrémně rychlé, protože se kompilují přímo do PHP kódu a ukládají do cache na disk. Nemají tedy žádnou režii navíc oproti šablonám psaným v čistém PHP. -Cache se automaticky regeneruje pokaždé, když změníte zdrojový soubor. Během vývoje si tedy pohodlně editujete šablony v Latte a změny okamžitě vidíte v prohlížeči. Tuto funkci můžete v produkčním prostředí vypnout a ušetřit tím malinko výkonu: +Cache se automaticky regeneruje při změně zdrojového souboru. Během vývoje tedy pohodlně editujete šablony v Latte a změny okamžitě vidíte v prohlížeči. Pro mírné zvýšení výkonu v produkčním prostředí můžete automatickou regeneraci vypnout: ```php $latte->setAutoRefresh(false); ``` -Při nasazení na produkčním serveru může prvotní vygenerování cache, zejména u rozsáhlejších aplikací, pochopitelně chviličku trvat. Latte má vestavěnou prevenci před "cache stampede":https://en.wikipedia.org/wiki/Cache_stampede. -Jde o situaci, kdy se sejde větší počet souběžných požadavků, které spustí Latte, a protože cache ještě neexistuje, začaly by ji všechny generovat současně. Což by neúměrně zatížilo server. -Latte je chytré a při více souběžných požadavcích generuje cache pouze první vlákno, ostatní čekají a následně ji využíjí. +Při nasazení na produkční server může prvotní vygenerování cache, zejména u rozsáhlých aplikací, chvíli trvat. Latte má vestavěnou prevenci proti "cache stampede":https://en.wikipedia.org/wiki/Cache_stampede, což je situace, kdy velký počet souběžných požadavků spustí generování cache současně, což by mohlo přetížit server. Latte tento problém řeší chytře - při více souběžných požadavcích generuje cache pouze první vlákno, zatímco ostatní čekají a následně využijí vytvořenou cache. Parametry jako třída ==================== -Lepší než předávat proměnné do šablony jako pole je vytvořit si třídu. Získáte tak [typově bezpečný zápis|type-system], [příjemné napovídání v IDE|recipes#Editory a IDE] a cestu pro [registraci filtrů|extending-latte#Filtry pomocí třídy] a [funkcí|extending-latte#Funkce pomocí třídy]. +Místo předávání proměnných do šablony jako pole je lepší vytvořit si třídu. Získáte tak [typově bezpečný zápis|type-system], [příjemné napovídání v IDE|recipes#Editory a IDE] a možnost [registrace filtrů|extending-latte#Filtry pomocí třídy] a [funkcí|extending-latte#Funkce pomocí třídy]. ```php class MailTemplateParameters @@ -89,9 +87,9 @@ $latte->render('mail.latte', new MailTemplateParameters( Vypnutí auto-escapování proměnné ================================ -Pokud proměnná obsahuje řetězec v HTML, můžete ji označit tak, aby ji Latte automaticky (a tedy dvojitě) neescapovalo. Vyhnete se tak potřebě uvádět v šabloně `|noescape`. +Pokud proměnná obsahuje HTML řetězec, můžete ji označit tak, aby ji Latte automaticky (a tedy dvojitě) neescapovalo. Tím se vyhnete potřebě uvádět v šabloně `|noescape`. -Nejjednodušší cestou je řetězec zabalit do objektu `Latte\Runtime\Html`: +Nejjednodušší způsob je zabalit řetězec do objektu `Latte\Runtime\Html`: ```php $params = [ @@ -99,10 +97,10 @@ $params = [ ]; ``` -Latte dále neescapuje všechny objekty, které implementují rozhraní `Latte\HtmlStringable`. Můžete si tak vytvořit vlastní třídu, jejíž metoda `__toString()` bude vracet HTML kód, který se nebude automaticky escapovat: +Latte také neescapuje objekty implementující rozhraní `Latte\HtmlStringable`. Můžete si vytvořit vlastní třídu, jejíž metoda `__toString()` bude vracet HTML kód, který se nebude automaticky escapovat: ```php -class Emphasis extends Latte\HtmlStringable +class Emphasis implements Latte\HtmlStringable { public function __construct( private string $str, @@ -127,16 +125,14 @@ Metoda `__toString` musí vracet korektní HTML a zajistit escapování parametr Jak rozšířit Latte o filtry, značky atd. ======================================== -Jak do Latte přidat vlastní filtr, funkci, značku atd? O tom pojednává kapitola [rozšiřujeme Latte |extending-latte]. +Informace o přidávání vlastních filtrů, funkcí, značek atd. najdete v kapitole [rozšiřujeme Latte |extending-latte]. Pokud chcete své úpravy znovu použít v různých projektech nebo je sdílet s ostatními, měli byste [vytvořit rozšíření |creating-extension]. -Libovolný kód v šabloně `{php ...}` .{toc: RawPhpExtension} -=========================================================== +Libovolný PHP kód v šabloně `{php ...}` .{toc: RawPhpExtension} +=============================================================== -Uvnitř značky [`{do}`|tags#do] lze zapisovat pouze PHP výrazy, nemůžete tak třeba vložit konstrukce jako `if ... else` nebo statementy ukončené středníkem. - -Můžete si však zaregistrovat rozšíření `RawPhpExtension`, které přidává značku `{php ...}`. Pomocí té lze vkládat jakýkoliv PHP kód. Nevztahují se na něj žádná pravidla sandbox režimu, použití je tedy na zodpovědnost autora šablony. +Zatímco uvnitř značky [`{do}`|tags#do] lze zapisovat pouze PHP výrazy, rozšíření `RawPhpExtension` přidává značku `{php ...}`, která umožňuje vkládat jakýkoliv PHP kód. Použití je na zodpovědnost autora šablony, protože se na ni nevztahují pravidla sandbox režimu. ```php $latte->addExtension(new Latte\Essential\RawPhpExtension); @@ -146,12 +142,10 @@ $latte->addExtension(new Latte\Essential\RawPhpExtension); Kontrola vygenerovaného kódu .{data-version:3.0.7} ================================================== -Latte kompiluje šablony do PHP kódu. Samozřejmě dbá na to, aby vygenerovaný kód byl syntakticky validní. Nicméně při použítí rozšíření třetích stran nebo `RawPhpExtension` nemůže Latte zaručit správnost vygenerovaného souboru. -Také lze v PHP zapsat kód, který je sice syntakticky správný, ale je zakázaný (například přiřazení hodnoty do proměnné `$this`) a způsobí PHP Compile Error. +Latte kompiluje šablony do PHP kódu a dbá na jeho syntaktickou správnost. Nicméně při použití rozšíření třetích stran nebo `RawPhpExtension` nemůže Latte zaručit korektnost vygenerovaného souboru. V PHP lze také zapsat kód, který je syntakticky správný, ale zakázaný (například přiřazení hodnoty do `$this`) a způsobí PHP Compile Error. Pokud takovou operaci zapíšete v šabloně, dostane se i do vygenerovaného PHP kódu. Jelikož v PHP existují na dvě stovky různých zakázaných operací, nemá Latte ambici je odhalovat. Upozorní na ně až samotné PHP při vykreslení, což obvykle ničemu nevadí. -Jsou ale situace, kdy chcete vědět už v době kompilace šablony, že žádný PHP Compile Error neobsahuje. Zejména tehdy, pokud šablony mohou editovat uživatelé, nebo používáte [Sandbox]. V takovém případě si nechte šablony kontrolovat už v době kompilace. -Tuto funkčnost zapnete metodou `Engine::enablePhpLint()`. Jelikož ke kontrole potřebuje volat binárku PHP, cestu k ní předejte jako parametr: +Pokud chcete odhalit tyto problémy už v době kompilace šablony, zejména pokud šablony mohou editovat uživatelé nebo používáte [Sandbox], můžete zapnout kontrolu pomocí `Engine::enablePhpLint()`. Ke kontrole je potřeba volat binárku PHP, jejíž cestu předáte jako parametr: ```php $latte = new Latte\Engine; @@ -185,7 +179,7 @@ Vyžaduje PHP rozšíření `intl`. Nastavení v Latte neovlivňuje globální n Striktní režim .{data-version:3.0.8} ==================================== -Ve striktním režimu parsování Latte kontroluje, zda nechybí uzavírací HTML značky a také zakazuje používání proměnné `$this`. Zapnete jej takto: +Ve striktním režimu parsování Latte kontroluje, zda nechybí uzavírací HTML značky a zakazuje používání proměnné `$this`. Zapnete jej takto: ```php $latte = new Latte\Engine; @@ -203,7 +197,7 @@ $latte->setStrictTypes(); Překládání v šablonách .{toc: TranslatorExtension} ================================================== -Pomocí rozšíření `TranslatorExtension` přidáte do šablony značky [`{_...}`|tags#_], [`{translate}`|tags#translate] a filtr [`translate`|filters#translate]. Slouží k překládání hodnot nebo částí šablony do jiných jazyků. Jako parametr uvedeme metodu (PHP callable) provádějící překlad: +Rozšíření `TranslatorExtension` přidává do šablony značky [`{_...}`|tags#_], [`{translate}`|tags#translate] a filtr [`translate`|filters#translate] pro překládání hodnot nebo částí šablony do jiných jazyků. Jako parametr uvedeme metodu provádějící překlad: ```php class MyTranslator @@ -249,7 +243,7 @@ public function translate(string $original, ...$params): string Debuggování a Tracy =================== -Latte se vám snaží vývoj co nejvíce zpříjemnit. Přímo pro účely debugování existuje trojice značek [`{dump}`|tags#dump], [`{debugbreak}`|tags#debugbreak] a [`{trace}`|tags#trace]. +Latte se vám snaží vývoj co nejvíce zpříjemnit. Nabízí několik nástrojů pro debugování, včetně značek [`{dump}`|tags#dump], [`{debugbreak}`|tags#debugbreak] a [`{trace}`|tags#trace]. Největší komfort získáte, když ještě si nainstalujete skvělý [ladicí nástroj Tracy|tracy:] a aktivujete doplněk pro Latte: @@ -267,13 +261,13 @@ Zároveň v pravém dolním rohu v tzv. Tracy Baru se objeví záložka pro Latt [* latte-debugging.webp *] -Jelikož Latte kompiluje šablony do přehledného PHP kódu, můžete je pohodlně ve svém IDE krokovat. +Jelikož Latte kompiluje šablony do přehledného PHP kódu, můžete je pohodlně krokovat ve svém IDE. Linter: validace syntaxe šablon .{toc: Linter} ============================================== -Projít všechny šablony a zkontrolovat, zda neobsahují syntaktické chyby, vám pomůže nástroj Linter. Spouští se z konzole: +Pro kontrolu syntaxe všech šablon můžete použít nástroj Linter, který se spouští z konzole: ```shell vendor/bin/latte-lint @@ -281,31 +275,30 @@ vendor/bin/latte-lint Parametrem `--strict` aktivujete [striktní režim|#striktní režim]. -Pokud používáte vlastní značky, vytvořte si také vlastní verzi Linteru, např. `custom-latte-lint`: +Pokud používáte vlastní značky, vytvořte si vlastní verzi Linteru, např. `custom-latte-lint`: ```php #!/usr/bin/env php getEngine(); -// tady přidejte jednotlivá svá rozšíření +// zde přidejte svá rozšíření $latte->addExtension(/* ... */); $ok = $linter->scanDirectory($path); exit($ok ? 0 : 1); ``` -Alternativně můžete vlastní objekt `Latte\Engine` předat do Linteru: +Alternativně můžete předat vlastní objekt `Latte\Engine` do Linteru: ```php $latte = new Latte\Engine; -// tady nakonfigurujeme objekt $latte +// zde nakonfigurujeme objekt $latte $linter = new Latte\Tools\Linter(engine: $latte); ``` @@ -313,7 +306,7 @@ $linter = new Latte\Tools\Linter(engine: $latte); Načítání šablon z řetězce ========================= -Potřebujete načítat šablony z řetězců místo souborů, třeba pro účely testování? Pomůže vám [StringLoader|extending-latte#stringloader]: +Pro načítání šablon z řetězců, například pro účely testování, můžete použít [StringLoader|extending-latte#stringloader]: ```php $latte->setLoader(new Latte\Loaders\StringLoader([ @@ -359,4 +352,4 @@ $latte = new Latte\Engine; $latte->addProvider('coreParentFinder', $finder); ``` -Pokud šablona nemá mít layout, oznámí to značkou `{layout none}`. +Pokud šablona nemá mít layout, použije se značka `{layout none}`. diff --git a/latte/cs/extending-latte.texy b/latte/cs/extending-latte.texy index 15442df8e8..3a4089c0aa 100644 --- a/latte/cs/extending-latte.texy +++ b/latte/cs/extending-latte.texy @@ -2,74 +2,76 @@ Rozšiřujeme Latte ***************** .[perex] -Latte je velmi flexibilní a lze jej rozšířit mnoha způsoby: můžete přidat vlastní filtry, funkce, značky, loadery atd. Ukážeme si jak na to. +Latte je mimořádně flexibilní šablonovací systém, který můžete přizpůsobit svým potřebám mnoha způsoby. Ať už potřebujete přidat vlastní filtry, funkce, značky nebo změnit způsob načítání šablon, Latte vám to umožní. Pojďme se podívat, jak na to. -Tato kapitola popisuje jednotlivé cesty rozšiřování Latte. Pokud chcete své úpravy znovu použít v různých projektech nebo je sdílet s ostatními, měli byste [vytvořit tzv. rozšíření |creating-extension]. +Tato kapitola vás provede různými metodami rozšíření Latte. Pokud plánujete své rozšíření použít ve více projektech nebo ho sdílet s komunitou, doporučujeme vytvořit [samostatné rozšíření |creating-extension]. Kolik cest vede do Říma? ======================== -Protože některé způsoby rozšíření Latte mohou splývat, zkusíme si nejprve vysvětlit rozdíly mezi nimi. Jako příklad se pokusíme implementovat generátor *Lorem ipsum*, kterému předáme počet slov, jenž má vygenerovat. +Jelikož některé způsoby rozšíření Latte mohou být podobné, pojďme si nejprve objasnit rozdíly mezi nimi. Jako příklad implementujeme generátor textu *Lorem ipsum*, kterému předáme požadovaný počet slov. -Hlavní konstrukcí jazyka Latte je značka (tag). Generátor můžeme implementovat rozšířením jazyka Latte o nový tag: +Základním stavebním kamenem jazyka Latte je značka (tag). Generátor bychom mohli implementovat jako novou značku: ```latte {lipsum 40} ``` +Tato značka by fungovala dobře, ale nemusí být dostatečně flexibilní, protože ji nelze použít ve výrazech. Mimochodem, v praxi je potřeba vytvářet nové značky jen zřídka, což je dobrá zpráva, protože jde o složitější způsob rozšíření. -Tag bude skvěle fungovat. Nicméně generátor v podobě tagu nemusí být dostatečně flexibilní, protože jej nelze použít ve výrazu. Mimochodem v praxi potřebujete tagy vytvářet jen zřídka; a to je dobrá zpráva, protože tagy jsou složitějším způsobem rozšíření. - -Dobrá, zkusme místo tagu vytvořit filtr: +Zkusme místo značky vytvořit filtr: ```latte {=40|lipsum} ``` -Opět validní možnost. Ale filtr by měl předanou hodnotu transformovat na něco jiného. Zde hodnotu `40`, která udává počet vygenerovaných slov, používáme jako argument filtru, nikoli jako hodnotu, kterou chceme transformovat. +To je také platná možnost. Avšak filtr by měl typicky transformovat předanou hodnotu. V tomto případě hodnotu `40`, která určuje počet generovaných slov, používáme jako argument filtru, nikoli jako hodnotu k transformaci. -Tak zkusíme použít funkci: +Pojďme tedy zkusit funkci: ```latte {lipsum(40)} ``` -To je ono! Pro tento konkrétní příklad je vytvoření funkce ideálním způsobem rozšíření. Můžete ji volat kdekoli, kde je akceptován výraz, například: +To je ono! Pro tento konkrétní případ je vytvoření funkce ideálním způsobem rozšíření. Můžete ji volat kdekoli, kde je povolen výraz, například: ```latte {var $text = lipsum(40)} ``` +Tento příklad ukazuje, že výběr správného způsobu rozšíření závisí na konkrétním použití. Nyní se pojďme podívat na jednotlivé metody podrobněji. + Filtry ====== -Filtr vytvoříme zaregistrováním jeho názvu a libovolného PHP callable, třeba funkce: +Filtry jsou mocné nástroje pro transformaci dat přímo v šabloně. Vytvořit vlastní filtr je jednoduché: ```php $latte = new Latte\Engine; -$latte->addFilter('shortify', fn(string $s) => mb_substr($s, 0, 10)); // zkrátí text na 10 písmen +$latte->addFilter('shortify', fn(string $s) => mb_substr($s, 0, 10)); // zkrátí text na 10 znaků ``` -V tomto případě by bylo šikovnější, kdyby filtr přijímal další parametr: +V tomto případě by bylo užitečné, kdyby filtr přijímal další parametr: ```php $latte->addFilter('shortify', fn(string $s, int $len = 10) => mb_substr($s, 0, $len)); ``` -V šabloně se potom volá takto: +V šabloně se pak volá takto: ```latte

{$text|shortify}

{$text|shortify:100}

``` -Jak vidíte, funkce obdrží levou stranu filtru před pipe `|` jako první argument a argumenty předané filtru za `:` jako další argumenty. +Všimněte si, že: +- První argument filtru je vždy hodnota nalevo od `|` +- Další argumenty se předávají za dvojtečkou +- Filtry mohou mít libovolný počet argumentů, včetně volitelných -Funkce představující filtr může samozřejmě přijímat libovolný počet parametrů, podporovány jsou i variadic parametry. - -Pokud filtr vrací řetězec v HTML, můžete jej označit tak, aby jej Latte automaticky (a tedy dvojitě) neescapovalo. Vyhnete se tak potřebě uvádět v šabloně `|noescape`. -Nejjednodušší cestou je řetězec zabalit do objektu `Latte\Runtime\Html`, druhou cestu představují [Kontextové filtry|#Kontextové filtry]. +Pokud filtr vrací řetězec v HTML, můžete jej označit tak, aby jej Latte automaticky (a tedy dvojitě) neescapovalo. Tím se vyhnete nutnosti používat v šabloně `|noescape`. +Nejjednodušší způsob je obalit řetězec do objektu `Latte\Runtime\Html`, alternativou jsou [Kontextové filtry|#Kontextové filtry]. ```php $latte->addFilter('money', fn(float $amount) => new Latte\Runtime\Html("$amount Kč")); @@ -82,19 +84,19 @@ Filtr musí v takovém případě zajistit správné escapování dat. Filtry pomocí třídy ------------------- -Druhým způsobem definice filtru je [využití třídy|develop#Parametry jako třída]. Vytvoříme metodu s atributem `TemplateFilter`: +Alternativním způsobem definice filtru je [využití třídy|develop#Parametry jako třída]. Vytvoříme metodu s atributem `TemplateFilter`: ```php class TemplateParameters { public function __construct( - // parameters + // parametry ) {} #[Latte\Attributes\TemplateFilter] public function shortify(string $s, int $len = 10): string { - return mb_substr($s, 0, $len); + return mb_substr($s, 0, $len) . (mb_strlen($s) > $len ? '...' : ''); } } @@ -102,11 +104,13 @@ $params = new TemplateParameters(/* ... */); $latte->render('template.latte', $params); ``` +Tento přístup je zvláště užitečný, když máte více filtrů nebo když filtry potřebují přístup ke sdíleným zdrojům. + Zavaděč filtrů -------------- -Místo registrace jednotlivých filtrů lze vytvořit tzv. zavaděč, což je funkce, které se zavolá s názvem filtru jako argumentem a vrátí jeho PHP callable, nebo null. +Místo registrace jednotlivých filtrů lze vytvořit tzv. zavaděč. Jde o funkci, která se volá s názvem filtru jako argumentem a vrací jeho PHP callable, nebo null. ```php $latte->addFilterLoader([new Filters, 'load']); @@ -131,11 +135,13 @@ class Filters } ``` +Tento přístup umožňuje dynamicky načítat filtry podle potřeby, což může být užitečné v rozsáhlých aplikacích. + Kontextové filtry ----------------- -Kontextový filtr je takový, který v prvním parametru přijímá objekt [api:Latte\Runtime\FilterInfo] a teprve po něm následují další parametry jako u klasických filtrů. Registruje se stejný způsobem, Latte samo rozpozná, že filtr je kontextový: +Kontextové filtry jsou speciální typ filtrů, které mají přístup k dodatečným informacím o kontextu, ve kterém jsou použity: ```php use Latte\Runtime\FilterInfo; @@ -147,13 +153,13 @@ $latte->addFilter('foo', function (FilterInfo $info, string $str): string { Kontextové filtry mohou zjišťovat a měnit content-type, který obdrží v proměnné `$info->contentType`. Pokud se filtr volá klasicky nad proměnnou (např. `{$var|foo}`), bude `$info->contentType` obsahovat null. -Filtr by měl nejprve ověřit, zda content-type vstupního řetězce podporuje. A může ho také změnit. Příklad filtru, který přijímá text (nebo null) a vrací HTML: +Filtr by měl nejprve ověřit, zda podporuje content-type vstupního řetězce. Může ho také změnit. Příklad filtru, který přijímá text (nebo null) a vrací HTML: ```php use Latte\Runtime\FilterInfo; $latte->addFilter('money', function (FilterInfo $info, float $amount): string { - // nejprve oveříme, zda je vstupem content-type text + // nejprve ověříme, zda je vstupem content-type text if (!in_array($info->contentType, [null, ContentType::Text])) { throw new Exception("Filter |money used in incompatible content type $info->contentType."); } @@ -173,9 +179,9 @@ Všechny filtry, které se používají nad [bloky|tags#block] (např. jako `{bl Funkce ====== -V Latte lze standardně používat všechny nativní funkce z PHP, pokud to nezakáže sandbox. Ale zároveň si můžete definovat funkce vlastní. Mohou přepsat funkce nativní. +V Latte lze standardně používat všechny nativní funkce PHP, pokud to nezakáže sandbox. Zároveň si můžete definovat vlastní funkce, které mohou přepsat i nativní funkce. -Funkci vytvoříme zaregistrováním jejího názvu a libovolného PHP callable: +Funkci vytvoříme registrací jejího názvu a libovolného PHP callable: ```php $latte = new Latte\Engine; @@ -184,7 +190,7 @@ $latte->addFunction('random', function (...$args) { }); ``` -Použití je pak stejné, jako když voláte PHP funkci: +Použití je pak stejné jako při volání PHP funkce: ```latte {random(jablko, pomeranč, citron)} // vypíše například: jablko @@ -194,13 +200,13 @@ Použití je pak stejné, jako když voláte PHP funkci: Funkce pomocí třídy ------------------- -Druhým způsobem definice funkce je [využití třídy|develop#Parametry jako třída]. Vytvoříme metodu s atributem `TemplateFunction`: +Alternativním způsobem definice funkce je [využití třídy|develop#Parametry jako třída]. Vytvoříme metodu s atributem `TemplateFunction`: ```php class TemplateParameters { public function __construct( - // parameters + // parametry ) {} #[Latte\Attributes\TemplateFunction] @@ -214,17 +220,19 @@ $params = new TemplateParameters(/* ... */); $latte->render('template.latte', $params); ``` +Tento přístup je užitečný pro organizaci souvisejících funkcí a sdílení zdrojů mezi nimi. + Loadery ======= -Loadery jsou zodpovědné za načítání šablon ze zdroje, například ze souborového systému. Nastaví se metodou `setLoader()`: +Loadery jsou zodpovědné za načítání šablon ze zdroje, například ze souborového systému. Nastavují se metodou `setLoader()`: ```php $latte->setLoader(new MyLoader); ``` -Vestavěné loadery jsou tyto: +Latte nabízí tyto vestavěné loadery: FileLoader @@ -232,7 +240,7 @@ FileLoader Výchozí loader. Načítá šablony ze souborového systému. -Přístup k souborům je možné omezit nastavením základního adresáře: +Přístup k souborům lze omezit nastavením základního adresáře: ```php $latte->setLoader(new Latte\Loaders\FileLoader($templateDir)); @@ -243,7 +251,7 @@ $latte->render('test.latte'); StringLoader ------------ -Načítá šablony z řetězců. Tento loader je velmi užitečný pro testování. Lze jej také použít pro malé projekty, kde může mít smysl ukládat všechny šablony do jediného souboru PHP. +Načítá šablony z řetězců. Tento loader je velmi užitečný pro testování. Lze jej také použít pro menší projekty, kde může být výhodné ukládat všechny šablony do jediného PHP souboru. ```php $latte->setLoader(new Latte\Loaders\StringLoader([ @@ -272,20 +280,20 @@ Loader je třída, která implementuje rozhraní [api:Latte\Loader]. Tagy (makra) ============ -Jednou z nejzajímavějších funkcí šablonovacího jádra je možnost definovat nové jazykové konstrukce pomocí značek. Je to také složitější funkčnost a je třeba pochopit, jak Latte interně funguje. +Jednou z nejzajímavějších funkcí šablonovacího jádra je možnost definovat nové jazykové konstrukce pomocí značek. Je to také složitější funkcionalita a vyžaduje pochopení vnitřního fungování Latte. -Většinou však značka není potřeba: -- pokud by měla generovat nějaký výstup, použijte místo ní [funkci|#funkce] -- pokud měla upravovat nějaký vstup a vracet ho, použijte místo toho [filtr|#filtry] -- pokud měla upravovat oblast textu, obalte jej značkou [`{block}`|tags#block] a použijte [filtr|#Kontextové filtry] -- pokud neměla nic vypisovat, ale pouze volat funkci, zavolejte ji pomocí [`{do}`|tags#do] +Ve většině případů však značka není potřeba: +- pokud má generovat nějaký výstup, použijte místo ní [funkci|#funkce] +- pokud má upravovat nějaký vstup a vracet ho, použijte [filtr|#filtry] +- pokud má upravovat oblast textu, obalte jej značkou [`{block}`|tags#block] a použijte [filtr|#Kontextové filtry] +- pokud nemá nic vypisovat, ale pouze volat funkci, použijte [`{do}`|tags#do] -Pokud přesto chcete vytvořit tag, skvěle! Vše podstatné najdete v kapitole [Vytváříme Extension|creating-extension]. +Pokud se přesto rozhodnete vytvořit tag, skvělé! Vše potřebné najdete v kapitole [Vytváříme Extension|creating-extension]. Průchody kompilátoru ==================== -Průchody kompilátoru jsou funkce, které modifikují AST nebo sbírají v nich informace. V Latte je takto implementován například sandbox: projde všechny uzly AST, najde volání funkcí a metod a nahradí je za jím kontrolované volání. +Průchody kompilátoru jsou funkce, které modifikují AST (abstraktní syntaktický strom) nebo z něj sbírají informace. V Latte je takto implementován například sandbox: projde všechny uzly AST, najde volání funkcí a metod a nahradí je za kontrolovaná volání. -Stejně jako v případě značek se jedná o složitější funkcionalitu a je potřeba pochopit, jak funguje Latte pod kapotou. Vše podstatné najdete v kapitole [Vytváříme Extension|creating-extension]. +Stejně jako v případě značek se jedná o složitější funkcionalitu, která vyžaduje pochopení vnitřního fungování Latte. Vše potřebné najdete v kapitole [Vytváříme Extension|creating-extension]. diff --git a/latte/cs/filters.texy b/latte/cs/filters.texy index 0fa1e5a14e..a480d9c021 100644 --- a/latte/cs/filters.texy +++ b/latte/cs/filters.texy @@ -2,113 +2,111 @@ Latte filtry ************ .[perex] -V šablonách můžeme používat funkce, které pomáhají upravit nebo přeformátovat data do výsledné podoby. Říkáme jim *filtry*. +Filtry v šablonách Latte pomáhají upravit nebo přeformátovat data do požadované podoby .[table-latte-filters] |## Transformace -| `batch` | [výpis lineárních dat do tabulky |#batch] -| `breakLines` | [Před konce řádku přidá HTML odřádkování |#breakLines] +| `batch` | [rozdělí lineární data do bloků |#batch] +| `breakLines` | [přidá HTML odřádkování za konce řádků |#breakLines] | `bytes` | [formátuje velikost v bajtech |#bytes] -| `clamp` | [ohraničí hodnotu do daného rozsahu |#clamp] -| `dataStream` | [konverze pro Data URI protokol |#datastream] -| `date` | [formátuje datum a čas|#date] +| `clamp` | [omezí hodnotu do daného rozsahu |#clamp] +| `dataStream` | [převede data do formátu Data URI |#datastream] +| `date` | [formátuje datum a čas |#date] | `explode` | [rozdělí řetězec na pole podle oddělovače |#explode] -| `first` | [vrací první prvek pole nebo znak řetězce |#first] -| `group` | [seskupí data podle různých kritérií |#group] +| `first` | [vrátí první prvek pole nebo znak řetězce |#first] +| `group` | [seskupí data podle zadaných kritérií |#group] | `implode` | [spojí pole do řetězce |#implode] -| `indent` | [odsadí text zleva o daný počet tabulátorů |#indent] +| `indent` | [odsadí text zleva |#indent] | `join` | [spojí pole do řetězce |#implode] -| `last` | [vrací poslední prvek pole nebo znak řetězce |#last] -| `length` | [vrací délku řetězce ve znacích nebo pole |#length] -| `localDate` | [formátuje datum a čas podle národního prostředí|#localDate] +| `last` | [vrátí poslední prvek pole nebo znak řetězce |#last] +| `length` | [vrátí délku řetězce nebo počet prvků pole |#length] +| `localDate` | [formátuje datum a čas podle národního prostředí |#localDate] | `number` | [formátuje číslo |#number] | `padLeft` | [doplní řetězec zleva na požadovanou délku |#padLeft] | `padRight` | [doplní řetězec zprava na požadovanou délku |#padRight] -| `random` | [vrací náhodný prvek pole nebo znak řetězce |#random] -| `repeat` | [opakování řetězce |#repeat] -| `replace` | [zamění výskyty hledaného řetězce |#replace] -| `replaceRE` | [zamění výskyty dle regulárního výrazu |#replaceRE] -| `reverse` | [obrátí UTF‑8 řetězec nebo pole |#reverse] +| `random` | [vrátí náhodný prvek pole nebo znak řetězce |#random] +| `repeat` | [opakuje řetězec |#repeat] +| `replace` | [nahradí výskyty hledaného řetězce |#replace] +| `replaceRE` | [nahradí výskyty podle regulárního výrazu |#replaceRE] +| `reverse` | [obrátí pořadí znaků v řetězci nebo prvků v poli |#reverse] | `slice` | [extrahuje část pole nebo řetězce |#slice] | `sort` | [seřadí pole |#sort] -| `spaceless` | [odstraní bílé místo |#spaceless], podobně jako značka [spaceless |tags] tag +| `spaceless` | [odstraní nadbytečné bílé znaky |#spaceless] | `split` | [rozdělí řetězec na pole podle oddělovače |#explode] -| `strip` | [odstraní bílé místo |#spaceless] -| `stripHtml` | [odstraní HTML značky a HTML entity převede na znaky |#stripHtml] +| `strip` | [odstraní nadbytečné bílé znaky |#spaceless] +| `stripHtml` | [odstraní HTML značky a převede entity na znaky |#stripHtml] | `substr` | [vrátí část řetězce |#substr] -| `trim` | [odstraní počáteční a koncové mezery či jiné znaky |#trim] -| `translate` | [překlad do jiných jazyků |#translate] -| `truncate` | [zkrátí délku se zachováním slov |#truncate] -| `webalize` | [upraví UTF‑8 řetězec do tvaru používaného v URL |#webalize] +| `trim` | [odstraní bílé znaky na začátku a konci řetězce |#trim] +| `translate` | [přeloží text do jiného jazyka |#translate] +| `truncate` | [zkrátí text na danou délku se zachováním slov |#truncate] +| `webalize` | [upraví řetězec pro použití v URL |#webalize] .[table-latte-filters] |## Velikost písmen -| `capitalize` | [malá písmena, první písmeno ve slovech velké |#capitalize] +| `capitalize` | [převede první písmeno každého slova na velké |#capitalize] | `firstUpper` | [převede první písmeno na velké |#firstUpper] -| `lower` | [převede na malá písmena |#lower] -| `upper` | [převede na velká písmena |#upper] +| `lower` | [převede text na malá písmena |#lower] +| `upper` | [převede text na velká písmena |#upper] .[table-latte-filters] |## Zaokrouhlování -| `ceil` | [zaokrouhlí číslo nahoru na danou přesnost |#ceil] -| `floor` | [zaokrouhlí číslo dolů na danou přesnost |#floor] -| `round` | [zaokrouhlí číslo na danou přesnost |#round] +| `ceil` | [zaokrouhlí číslo nahoru |#ceil] +| `floor` | [zaokrouhlí číslo dolů |#floor] +| `round` | [zaokrouhlí číslo |#round] .[table-latte-filters] |## Escapování | `escapeUrl` | [escapuje parametr v URL |#escapeUrl] -| `noescape` | [vypíše proměnnou bez escapování |#noescape] +| `noescape` | [vypne automatické escapování |#noescape] | `query` | [generuje query string v URL |#query] -Dále existují escapovací filtry pro HTML (`escapeHtml` a `escapeHtmlComment`), XML (`escapeXml`), JavaScript (`escapeJs`), CSS (`escapeCss`) a iCalendar (`escapeICal`), které Latte používá samo díky [kontextově sensitivnímu escapování|safety-first#Kontextově sensitivní escapování] a nemusíte je zapisovat. +Latte automaticky používá escapovací filtry pro HTML (`escapeHtml` a `escapeHtmlComment`), XML (`escapeXml`), JavaScript (`escapeJs`), CSS (`escapeCss`) a iCalendar (`escapeICal`) díky [kontextově sensitivnímu escapování|safety-first#Kontextově sensitivní escapování]. Tyto filtry není třeba explicitně zapisovat. .[table-latte-filters] |## Bezpečnost -| `checkUrl` | [ošetří URL adresu od nebezpečných vstupů |#checkUrl] -| `nocheck` | [předejde automatickému ošetření URL adresy |#nocheck] - -Latte atributy `src` a `href` [kontroluje automaticky |safety-first#Kontrola odkazů], takže filtr `checkUrl` téměř nemusíte používat. +| `checkUrl` | [zkontroluje a případně upraví URL adresu |#checkUrl] +| `nocheck` | [vypne automatickou kontrolu URL adresy |#nocheck] .[note] -Všechny výchozí filtry jsou určeny pro řetězce v kódování UTF‑8. +Všechny výchozí filtry jsou navrženy pro práci s řetězci v kódování UTF-8. Použití ======= -Filtry se zapisují za svislítko (může být před ním mezera): +Filtry se aplikují pomocí svislítka za proměnnou nebo výrazem: ```latte

{$heading|upper}

``` -Filtry (ve starších verzích helpery) lze zřetězit a poté se aplikují v pořadí od levého k pravému: +Filtry lze řetězit, v takovém případě se aplikují zleva doprava: ```latte

{$heading|lower|capitalize}

``` -Parametry se zadávají za jménem filtru oddělené dvojtečkami nebo čárkami: +Parametry filtrů se zadávají za dvojtečkou: ```latte

{$heading|truncate:20,''}

``` -Filtry lze aplikovat i na výraz: +Filtry lze použít i na výrazy: ```latte -{var $name = ($title|upper) . ($subtitle|lower)} +{var $name = ($title|upper) . ($subtitle|lower)} ``` -[Vlastní filtry|extending-latte#filtry] lze registrovat tímto způsobem: +[Vlastní filtry|extending-latte#filtry] se registrují následovně: ```php $latte = new Latte\Engine; $latte->addFilter('shortify', fn(string $s, int $len = 10) => mb_substr($s, 0, $len)); ``` -V šabloně se potom volá takto: +V šabloně se pak volají stejně jako vestavěné filtry: ```latte

{$text|shortify}

@@ -122,7 +120,7 @@ Filtry batch(int length, mixed item): array .[filter] ---------------------------------------------- -Filtr, který zjednodušuje výpis lineárních dat do podoby tabulky. Vrací pole polí se zadaným počtem položek. Pokud zadáte druhý parametr, použije se k doplnění chybějících položek na posledním řádku. +Filtr `batch` usnadňuje výpis lineárních dat do tabulkové struktury. Vrací pole polí s požadovaným počtem položek. Pokud zadáte druhý parametr, použije se k doplnění chybějících položek v posledním řádku. ```latte {var $items = ['a', 'b', 'c', 'd', 'e']} @@ -137,7 +135,7 @@ Filtr, který zjednodušuje výpis lineárních dat do podoby tabulky. Vrací po
``` -Vypíše: +Výstup: ```latte @@ -159,7 +157,7 @@ Viz také [#group] a značka [iterateWhile|tags#iterateWhile]. breakLines .[filter] -------------------- -Přidává před každý znak nového řádku HTML značku `
` +Filtr `breakLines` vkládá HTML značku `
` před každý znak nového řádku. ```latte {var $s = "Text & with \n newline"} @@ -169,17 +167,19 @@ Přidává před každý znak nového řádku HTML značku `
` bytes(int precision = 2) .[filter] ---------------------------------- -Formátuje velikost v bajtech do lidsky čitelné podoby. Pokud je nastavené [národní prostředí |develop#locale], použijí se odpovídající oddělovače desetinných míst a tisíců. +Filtr `bytes` formátuje velikost v bajtech do lidsky čitelné podoby. Pokud je nastaveno [národní prostředí |develop#locale], použijí se odpovídající oddělovače desetinných míst a tisíců. ```latte {$size|bytes} 0 B, 1.25 GB, … {$size|bytes:0} 10 B, 1 GB, … ``` +Viz také [#number]. + ceil(int precision = 0) .[filter] --------------------------------- -Zaokrouhlí číslo nahoru na danou přesnost. +Filtr `ceil` zaokrouhlí číslo nahoru na danou přesnost. ```latte {=3.4|ceil} {* vypíše 4 *} @@ -192,7 +192,7 @@ Viz také [#floor], [#round]. capitalize .[filter] -------------------- -Slova budou začínat velkými písmeny, všechny zbývající znaky budou malá. Vyžaduje PHP rozšíření `mbstring`. +Filtr `capitalize` upraví text tak, že první písmeno každého slova bude velké a zbývající malá. Vyžaduje PHP rozšíření `mbstring`. ```latte {='i like LATTE'|capitalize} {* vypíše 'I Like Latte' *} @@ -203,7 +203,7 @@ Viz také [#firstUpper], [#lower], [#upper]. checkUrl .[filter] ------------------ -Vynutí ošetření URL adresy. Kontroluje, zda proměnná obsahuje webovou URL (tj. protokol HTTP/HTTPS) a předchází vypsání odkazů, které mohou představovat bezpečnostní riziko. +Filtr `checkUrl` zajistí kontrolu a případné ošetření URL adresy. Ověří, zda proměnná obsahuje webovou URL (tj. protokol HTTP/HTTPS) a zabrání vypsání odkazů, které by mohly představovat bezpečnostní riziko. ```latte {var $link = 'javascript:window.close()'} @@ -211,38 +211,40 @@ Vynutí ošetření URL adresy. Kontroluje, zda proměnná obsahuje webovou URL nekontrolované ``` -Vypíše: +Výstup: ```latte kontrolovanénekontrolované ``` +Latte automaticky [kontroluje atributy |safety-first#Kontrola odkazů] `src` a `href`, takže filtr `checkUrl` většinou není nutné explicitně uvádět. + Viz také [#nocheck]. clamp(int|float min, int|float max) .[filter] --------------------------------------------- -Ohraničí hodnotu do daného inkluzivního rozsahu min a max. +Filtr `clamp` omezí hodnotu do zadaného inkluzivního rozsahu min a max. ```latte {$level|clamp: 0, 255} ``` -Existuje také jako [funkce|functions#clamp]. +K dispozici je také jako [funkce|functions#clamp]. dataStream(string mimetype = detect) .[filter] ---------------------------------------------- -Konvertuje obsah do data URI scheme. Pomocí něj lze do HTML nebo CSS vkládat obrázky bez nutnosti linkovat externí soubory. +Filtr `dataStream` konvertuje obsah do schématu data URI. To umožňuje vkládat obrázky přímo do HTML nebo CSS bez nutnosti odkazovat na externí soubory. -Mějme v proměnné obrázek `$img = Image::fromFile('obrazek.gif')`, poté +Pokud máme v proměnné obrázek `$img = Image::fromFile('obrazek.gif')`, potom ```latte ``` -Vypíše například: +vypíše například: ```latte {$name} @@ -278,13 +280,13 @@ Viz také [#query]. explode(string separator = '') .[filter] ---------------------------------------- -Rozdělí řetězec na pole podle oddělovače. Alias pro `split`. +Filtr `explode` rozdělí řetězec na pole podle zadaného oddělovače. Je to alias pro `split`. ```latte {='one,two,three'|explode:','} {* vrací ['one', 'two', 'three'] *} ``` -Pokud je oddělovač prázdný řetězec (výchozí hodnota), bude vstup rozdělen na jednotlivé znaky: +Pokud je oddělovač prázdný řetězec (výchozí hodnota), vstup se rozdělí na jednotlivé znaky: ```latte {='123'|explode} {* vrací ['1', '2', '3'] *} @@ -301,7 +303,7 @@ Viz také [#implode]. first .[filter] --------------- -Vrací první prvek pole nebo znak řetězce: +Filtr `first` vrací první prvek pole nebo první znak řetězce: ```latte {=[1, 2, 3, 4]|first} {* vypíše 1 *} @@ -313,7 +315,7 @@ Viz také [#last], [#random]. floor(int precision = 0) .[filter] ---------------------------------- -Zaokrouhlí číslo dolů na danou přesnost. +Filtr `floor` zaokrouhlí číslo dolů na danou přesnost. ```latte {=3.5|floor} {* vypíše 3 *} @@ -326,7 +328,7 @@ Viz také [#ceil], [#round]. firstUpper .[filter] -------------------- -Převede první písmeno na velká. Vyžaduje PHP rozšíření `mbstring`. +Filtr `firstUpper` převede první písmeno na velké. Vyžaduje PHP rozšíření `mbstring`. ```latte {='the latte'|firstUpper} {* vypíše 'The latte' *} @@ -337,7 +339,7 @@ Viz také [#capitalize], [#lower], [#upper]. group(string|int|\Closure by): array .[filter]{data-version:3.0.16} ------------------------------------------------------------------- -Filtr seskupí data podle různých kritérií. +Filtr `group` umožňuje seskupit data podle různých kritérií. V tomto příkladu se řádky v tabulce seskupují podle sloupce `categoryId`. Výstupem je pole polí, kde klíčem je hodnota ve sloupci `categoryId`. [Přečtěte si podrobný návod|cookbook/grouping]. @@ -356,7 +358,7 @@ Viz také [#batch], funkce [group|functions#group] a značka [iterateWhile|tags# implode(string glue = '') .[filter] ----------------------------------- -Vrátí řetězec, který je zřetězením položek sekvence. Alias pro `join`. +Filtr `implode` spojí prvky pole do řetězce. Je to alias pro `join`. ```latte {=[1, 2, 3]|implode} {* vypíše '123' *} @@ -372,7 +374,7 @@ Můžete také použít alias `join`: indent(int level = 1, string char = "\t") .[filter] --------------------------------------------------- -Odsadí text zleva o daný počet tabulátorů nebo jiných znaků, které můžeme uvést ve druhém argumentu. Prázdné řádky nejsou odsazeny. +Filtr `indent` odsadí text zleva o zadaný počet tabulátorů nebo jiných znaků. Prázdné řádky nejsou odsazeny. ```latte
@@ -382,7 +384,7 @@ Odsadí text zleva o daný počet tabulátorů nebo jiných znaků, které můž
``` -Vypíše: +Výstup: ```latte
@@ -393,7 +395,7 @@ Vypíše: last .[filter] -------------- -Vrací poslední prvek pole nebo znak řetězce: +Filtr `last` vrací poslední prvek pole nebo poslední znak řetězce: ```latte {=[1, 2, 3, 4]|last} {* vypíše 4 *} @@ -405,13 +407,12 @@ Viz také [#first], [#random]. length .[filter] ---------------- -Vrátí délku řetězce nebo pole. - -- pro řetězce vrátí délku v UTF‑8 znacích -- pro pole vrátí počet položek -- pro objekty, které implementují rozhraní Countable, použije návratovou hodnotu metody count() -- pro objekty, které implementují rozhraní IteratorAggregate, použije návratovou hodnotu funkce iterator_count() +Filtr `length` vrátí délku řetězce nebo počet prvků v poli. +- pro řetězce vrátí počet unicode znaků +- pro pole vrátí počet prvků +- pro objekty implementující rozhraní Countable použije návratovou hodnotu metody count() +- pro objekty implementující rozhraní IteratorAggregate použije návratovou hodnotu funkce iterator_count() ```latte {if ($users|length) > 10} @@ -422,7 +423,7 @@ Vrátí délku řetězce nebo pole. localDate(string format = null, string date = null, string time = null) .[filter] --------------------------------------------------------------------------------- -Formátuje datum a čas podle [národního prostředí |develop#locale], což zajišťuje konzistentní a lokalizované zobrazení časových údajů napříč různými jazyky a regiony. Filtr přijímá datum jako UNIX timestamp, řetězec nebo objekt typu `DateTimeInterface`. +Filtr `localDate` formátuje datum a čas podle [národního prostředí |develop#locale]. To zajišťuje konzistentní a lokalizované zobrazení časových údajů napříč různými jazyky a regiony. Filtr přijímá datum jako UNIX timestamp, řetězec nebo objekt typu `DateTimeInterface`. ```latte {$date|localDate} {* 15. dubna 2024 *} @@ -430,20 +431,20 @@ Formátuje datum a čas podle [národního prostředí |develop#locale], což za {$date|localDate: date: medium} {* 15. 4. 2024 *} ``` -Pokud použijete filtr bez parametrů, vypíše se datum v úrovní `long`, viz dále. +Bez parametrů se datum vypíše v úrovni `long` (viz dále). **a) použití formátu** -Parametr `format` popisuje, které časové složky se mají zobrazit. Používá pro ně písmenné kódy, jejichž počet opakování ovlivňuje šířku výstupu: +Parametr `format` definuje, které časové složky se mají zobrazit. Používá písmena jako kódy, jejichž počet opakování ovlivňuje šířku výstupu: | rok | `y` / `yy` / `yyyy` | `2024` / `24` / `2024` | měsíc | `M` / `MM` / `MMM` / `MMMM` | `8` / `08` / `srp` / `srpen` | den | `d` / `dd` / `E` / `EEEE` | `1` / `01` / `ne` / `neděle` -| hodina | `j` / `H` / `h` | preferovaný / 24hodinový / 12hodinový +| hodina | `j` / `H` / `h` | preferovaná / 24hodinová / 12hodinová | minuta | `m` / `mm` | `5` / `05` (2 číslice v kombinaci se sekundami) | sekunda | `s` / `ss` | `8` / `08` (2 číslice v kombinaci s minutami) -Na pořadí kódů ve formátu nezáleží, protože pořadí složek se vypíše podle zvyklostí národního prostředí. Formát je tedy na něm nezávislý. Například formát `yyyyMMMMd` v postředí `en_US` vypíše `April 15, 2024`, zatímco v prostředí `cs_CZ` vypíše `15. dubna 2024`: +Pořadí kódů ve formátu nemá vliv na pořadí složek ve výstupu, protože to se řídí zvyklostmi národního prostředí. Formát je tedy na něm nezávislý. Například formát `yyyyMMMMd` v prostředí `en_US` vypíše `April 15, 2024`, zatímco v prostředí `cs_CZ` vypíše `15. dubna 2024`: | locale: | cs_CZ | en_US |--- @@ -458,7 +459,7 @@ Na pořadí kódů ve formátu nezáleží, protože pořadí složek se vypíš **b) použití přednastavených stylů** -Parametry `date` a `time` určují, jak podrobně se má datum a čas vypsat. Můžete si vybrat z několika úrovní: `full`, `long`, `medium`, `short`. Lze nechat vypsat jen datum, jen čas, nebo obojí: +Parametry `date` a `time` určují úroveň podrobnosti pro výpis data a času. K dispozici jsou úrovně: `full`, `long`, `medium`, `short`. Můžete nechat vypsat jen datum, jen čas, nebo obojí: | locale: | cs_CZ | en_US |--- @@ -473,7 +474,7 @@ Parametry `date` a `time` určují, jak podrobně se má datum a čas vypsat. M | `date: medium, time: short` | 23. 1. 1978 8:30 | Jan 23, 1978, 8:30 AM | `date: long, time: short` | 23. ledna 1978 v 8:30 | January 23, 1978 at 8:30 AM -U data lze navíc použít prefix `relative-` (např. `relative-short`), který pro data blízká současnosti zobrazí `včera`, `dnes` nebo `zítra`, jinak se vypíše standardním způsobem. +Pro datum lze použít prefix `relative-` (např. `relative-short`), který pro data blízká současnosti zobrazí `včera`, `dnes` nebo `zítra`, jinak se vypíše standardním způsobem. ```latte {$date|localDate: date: relative-short} {* včera *} @@ -484,7 +485,7 @@ Viz také [#date]. lower .[filter] --------------- -Převede řetězec na malá písmena. Vyžaduje PHP rozšíření `mbstring`. +Filtr `lower` převede řetězec na malá písmena. Vyžaduje PHP rozšíření `mbstring`. ```latte {='LATTE'|lower} {* vypíše 'latte' *} @@ -495,9 +496,9 @@ Viz také [#capitalize], [#firstUpper], [#upper]. nocheck .[filter] ----------------- -Předejde automatickému ošetření URL adresy. Latte [automaticky kontroluje|safety-first#Kontrola odkazů], zda proměnná obsahuje webovou URL (tj. protokol HTTP/HTTPS) a předchází vypsání odkazů, které mohou představovat bezpečnostní riziko. +Filtr `nocheck` vypne automatickou kontrolu URL adresy. Latte standardně [kontroluje |safety-first#Kontrola odkazů], zda proměnná obsahuje webovou URL (tj. protokol HTTP/HTTPS) a brání vypsání potenciálně nebezpečných odkazů. -Pokud odkaz používá jiné schéma, např. `javascript:` nebo `data:`, a jste si jistí jeho obsahem, můžete kontrolu vypnout pomoci `|nocheck`. +Pokud odkaz používá jiné schéma, např. `javascript:` nebo `data:`, a jste si jisti jeho obsahem, můžete kontrolu vypnout pomocí `|nocheck`. ```latte {var $link = 'javascript:window.close()'} @@ -506,7 +507,7 @@ Pokud odkaz používá jiné schéma, např. `javascript:` nebo `data:`, a jste nekontrolované ``` -Vypíše: +Výstup: ```latte kontrolované @@ -518,7 +519,7 @@ Viz také [#checkUrl]. noescape .[filter] ------------------ -Zakáže automatické escapování. +Filtr `noescape` vypne automatické escapování. ```latte {var $trustedHtmlString = 'hello'} @@ -526,7 +527,7 @@ Escapovaný: {$trustedHtmlString} Neescapovaný: {$trustedHtmlString|noescape} ``` -Vypíše: +Výstup: ```latte Escapovaný: <b>hello</b> @@ -534,12 +535,12 @@ Neescapovaný: hello ``` .[warning] -Špatné použití filtru `noescape` může vést ke vzniku zranitelnosti XSS! Nikdy jej nepoužívejte, pokud si nejste **zcela jisti** co děláte, a že vypisovaný řetězec pochází z důvěryhodného zdroje. +Nesprávné použití filtru `noescape` může vést ke zranitelnosti XSS! Používejte jej pouze tehdy, když si jste **naprosto jisti**, že vypisovaný řetězec pochází z důvěryhodného zdroje. number(int decimals = 0, string decPoint = '.', string thousandsSep = ',') .[filter] ------------------------------------------------------------------------------------ -Formátuje číslo na určitý počet desetinných míst. Pokud je nastavené [národní prostředí |develop#locale], použijí se odpovídající oddělovače desetinných míst a tisíců. +Filtr `number` formátuje číslo na zadaný počet desetinných míst. Pokud je nastaveno [národní prostředí |develop#locale], použijí se odpovídající oddělovače desetinných míst a tisíců. ```latte {1234.20|number} 1,234 @@ -551,16 +552,16 @@ Formátuje číslo na určitý počet desetinných míst. Pokud je nastavené [n number(string format) .[filter] ------------------------------- -Parametr `format` umožňuje definovat vzhled čísel přesně podle vašich potřeb. K tomu je potřeba mít nastavené [národní prostředí |develop#locale]. Formát se skládá z několika speciálních znaků, jejichž kompletní popis najdete v dokumentaci "DecimalFormat":https://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns: +Parametr `format` umožňuje přesně definovat vzhled čísel podle vašich potřeb. K tomu je nutné mít nastavené [národní prostředí |develop#locale]. Formát se skládá z několika speciálních znaků, jejichž kompletní popis najdete v dokumentaci "DecimalFormat":https://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns: - `0` povinná číslice, vždy se zobrazí, i kdyby to byla nula - `#` volitelná číslice, zobrazí se jen tehdy, pokud na tomto místě číslo skutečně je - `@` významná číslice, pomáhá zobrazit číslo s určitým počtem platných číslic -- `.` označuje, kde má být desetinná čárka (nebo tečka, podle země) +- `.` označuje pozici desetinné čárky (nebo tečky, podle země) - `,` slouží k oddělení skupin číslic, nejčastěji tisíců - `%` číslo vynásobí 100× a přidá znak procenta -Pojďme se podívat na příklady. V prvním příkladu jsou dvě desetinná místa povinná, ve druhém volitelná. Třetí příklad ukazuje doplnění nulami zleva i zprava, čtvrtý zobrazuje jen existující číslice: +Podívejme se na příklady. V prvním příkladu jsou dvě desetinná místa povinná, ve druhém volitelná. Třetí příklad ukazuje doplnění nulami zleva i zprava, čtvrtý zobrazuje jen existující číslice: ```latte {1234.5|number: '#,##0.00'} {* 1,234.50 *} @@ -569,7 +570,7 @@ Pojďme se podívat na příklady. V prvním příkladu jsou dvě desetinná mí {1.2 |number: '##.##'} {* 1.2 *} ``` -Významné číslice určují, kolik číslic bez ohledu na desetinou čárku má být zobrazeno, přičemž se zaokrouhluje: +Významné číslice určují, kolik číslic bez ohledu na desetinnou čárku má být zobrazeno, přičemž dochází k zaokrouhlování: ```latte {1234|number: '@@'} {* 1200 *} @@ -585,7 +586,7 @@ Snadný způsob, jak zobrazit číslo jako procenta. Číslo se vynásobí 100× {0.1234|number: '#.##%'} {* 12.34% *} ``` -Můžeme definovat odlišný formát pro kladná a záporná čísla, odděluje je znak `;`. Tímto způsobem lze například nastavit, že kladná čísla se mají zobrazovat se znaménkem `+`: +Můžeme definovat odlišný formát pro kladná a záporná čísla, oddělené znakem `;`. Tímto způsobem lze například nastavit, že kladná čísla se mají zobrazovat se znaménkem `+`: ```latte {42|number: '#.##;(#.##)'} {* 42 *} @@ -594,12 +595,12 @@ Můžeme definovat odlišný formát pro kladná a záporná čísla, odděluje {-42|number: '+#.##;-#.##'} {* -42 *} ``` -Pamatujte, že skutečný vzhled čísel se může lišit podle nastavení země. Například v některých zemích se používá čárka místo tečky jako oddělovač desetinných míst. Tento filtr to automaticky zohlední a nemusíte se o nic starat. +Nezapomeňte, že skutečný vzhled čísel se může lišit podle nastavení země. Například v některých zemích se používá čárka místo tečky jako oddělovač desetinných míst. Tento filtr to automaticky zohlední, takže se o to nemusíte starat. padLeft(int length, string pad = ' ') .[filter] ----------------------------------------------- -Doplní řetězec do určité délky jiným řetězcem zleva. +Filtr `padLeft` doplní řetězec zleva na požadovanou délku jiným řetězcem. ```latte {='hello'|padLeft: 10, '123'} {* vypíše '12312hello' *} @@ -608,7 +609,7 @@ Doplní řetězec do určité délky jiným řetězcem zleva. padRight(int length, string pad = ' ') .[filter] ------------------------------------------------ -Doplní řetězec do určité délky jiným řetězcem zprava. +Filtr `padRight` doplní řetězec zprava na požadovanou délku jiným řetězcem. ```latte {='hello'|padRight: 10, '123'} {* vypíše 'hello12312' *} @@ -617,18 +618,18 @@ Doplní řetězec do určité délky jiným řetězcem zprava. query .[filter] --------------- -Dynamicky generuje query string v URL: +Filtr `query` dynamicky generuje query string v URL: ```latte -click -search +klikněte +hledat ``` -Vypíše: +Výstup: ```latte -click -search +klikněte +hledat ``` Klíče s hodnotou `null` se vynechají. @@ -638,7 +639,7 @@ Viz také [#escapeUrl]. random .[filter] ---------------- -Vrací náhodný prvek pole nebo znak řetězce: +Filtr `random` vrací náhodný prvek pole nebo náhodný znak řetězce: ```latte {=[1, 2, 3, 4]|random} {* vypíše např.: 3 *} @@ -650,7 +651,7 @@ Viz také [#first], [#last]. repeat(int count) .[filter] --------------------------- -Opakuje řetězec x-krát. +Filtr `repeat` opakuje řetězec zadaný počet krát. ```latte {='hello'|repeat: 3} {* vypíše 'hellohellohello' *} @@ -659,7 +660,7 @@ Opakuje řetězec x-krát. replace(string|array search, string replace = '') .[filter] ----------------------------------------------------------- -Nahradí všechny výskyty vyhledávacího řetězce náhradním řetězcem. +Filtr `replace` nahradí všechny výskyty hledaného řetězce náhradním řetězcem. ```latte {='hello world'|replace: 'world', 'friend'} {* vypíše 'hello friend' *} @@ -674,7 +675,7 @@ Lze provést i více záměn najednou: replaceRE(string pattern, string replace = '') .[filter] -------------------------------------------------------- -Provede vyhledávání regulárních výrazů s nahrazením. +Filtr `replaceRE` provádí nahrazování podle regulárních výrazů. ```latte {='hello world'|replaceRE: '/l.*/', 'l'} {* vypíše 'hel' *} @@ -683,19 +684,19 @@ Provede vyhledávání regulárních výrazů s nahrazením. reverse .[filter] ----------------- -Obrátí daný řetězec nebo pole. +Filtr `reverse` obrátí pořadí znaků v řetězci nebo prvků v poli. ```latte {var $s = 'Nette'} {$s|reverse} {* vypíše 'etteN' *} {var $a = ['N', 'e', 't', 't', 'e']} -{$a|reverse} {* returns ['e', 't', 't', 'e', 'N'] *} +{$a|reverse} {* vrátí ['e', 't', 't', 'e', 'N'] *} ``` round(int precision = 0) .[filter] ---------------------------------- -Zaokrouhlí číslo na danou přesnost. +Filtr `round` zaokrouhlí číslo na zadanou přesnost. ```latte {=3.4|round} {* vypíše 3 *} @@ -709,25 +710,25 @@ Viz také [#ceil], [#floor]. slice(int start, int length = null, bool preserveKeys = false) .[filter] ------------------------------------------------------------------------ -Extrahuje část pole nebo řetězce. +Filtr `slice` extrahuje část pole nebo řetězce. ```latte {='hello'|slice: 1, 2} {* vypíše 'el' *} {=['a', 'b', 'c']|slice: 1, 2} {* vypíše ['b', 'c'] *} ``` -Filtr funguje jako funkce PHP `array_slice` pro pole nebo `mb_substr` pro řetězce s fallbackem na funkci `iconv_substr` v režimu UTF‑8. +Tento filtr funguje jako funkce PHP `array_slice` pro pole nebo `mb_substr` pro řetězce s fallbackem na funkci `iconv_substr` v režimu UTF-8. -Pokud je start kladný, posloupnost začné posunutá o tento počet od začátku pole/řetezce. Pokud je záporný posloupnost začné posunutá o tolik od konce. +Pokud je `start` kladný, posloupnost začíná posunutá o tento počet od začátku pole/řetězce. Pokud je záporný, posloupnost začíná posunutá o tolik od konce. -Pokud je zadaný parametr length a je kladný, posloupnost bude obsahovat tolik prvků. Pokud je do této funkce předán záporný parametr length, posloupnost bude obsahovat všechny prvky původního pole, začínající na pozici start a končicí na pozici menší na length prvků od konce pole. Pokud tento parametr nezadáte, posloupnost bude obsahovat všechny prvky původního pole, začínající pozici start. +Pokud je zadán parametr `length` a je kladný, posloupnost bude obsahovat tolik prvků. Pokud je do této funkce předán záporný parametr `length`, posloupnost bude obsahovat všechny prvky původního pole, začínající na pozici `start` a končící na pozici menší o `length` prvků od konce pole. Pokud tento parametr nezadáte, posloupnost bude obsahovat všechny prvky původního pole, začínající pozicí `start`. -Ve výchozím nastavení filtr změní pořadí a resetuje celočíselného klíče pole. Toto chování lze změnit nastavením preserveKeys na true. Řetězcové klíče jsou vždy zachovány, bez ohledu na tento parametr. +Ve výchozím nastavení filtr změní pořadí a resetuje celočíselné klíče pole. Toto chování lze změnit nastavením `preserveKeys` na true. Řetězcové klíče jsou vždy zachovány, bez ohledu na tento parametr. sort(?Closure comparison, string|int|\Closure|null by=null, string|int|\Closure|bool byKey=false) .[filter] ----------------------------------------------------------------------------------------------------------- -Filtr seřadí prvky pole nebo iterátoru a zachová jejich asociační klíče. Při nastaveném [národním prostředí |develop#locale] se řazení řídí jeho pravidly, pokud není specifikována vlastní porovnávací funkce. +Filtr `sort` seřadí prvky pole nebo iterátoru a zachová jejich asociační klíče. Při nastaveném [národním prostředí |develop#locale] se řazení řídí jeho pravidly, pokud není specifikována vlastní porovnávací funkce. ```latte {foreach ($names|sort) as $name} @@ -735,7 +736,7 @@ Filtr seřadí prvky pole nebo iterátoru a zachová jejich asociační klíče. {/foreach} ``` -Řazené pole v opačném pořadí: +Pro řazení pole v opačném pořadí: ```latte {foreach ($names|sort|reverse) as $name} @@ -757,7 +758,7 @@ Filtr `|sort` také umožňuje řadit prvky podle klíčů: {/foreach} ``` -Pokud potřebujete seřadit tabulku podle konkrétního sloupce, můžete použít parametr `by`. Hodnota `'name'` v ukázce určuje, že se bude řadit podle `$item->name` nebo `$item['name']`, v závislosti na tom, zda je `$item` pole nebo objekt: +Pokud potřebujete seřadit tabulku podle konkrétního sloupce, můžete použít parametr `by`. Hodnota `'name'` v ukázce určuje, že se bude řadit podle `$item->name` nebo `$item['name']`, v závislosti na tom, zda je `$item` objekt nebo pole: ```latte {foreach ($items|sort: by: 'name') as $item} @@ -768,7 +769,7 @@ Pokud potřebujete seřadit tabulku podle konkrétního sloupce, můžete použ Můžete také definovat callback funkci, která určí hodnotu, podle které se má řadit: ```latte -{foreach ($items|sort: by: fn($items) => $items->category->name) as $item} +{foreach ($items|sort: by: fn($item) => $item->category->name) as $item} {$item->name} {/foreach} ``` @@ -778,7 +779,7 @@ Stejným způsobem lze využít i parametr `byKey`. spaceless .[filter] ------------------- -Odstraní zbytečné bílé místo (mezery) z výstupu. Můžete také použít alias `strip`. +Filtr `spaceless` odstraní nadbytečné bílé znaky z výstupu. Můžete také použít alias `strip`. ```latte {block |spaceless} @@ -788,7 +789,7 @@ Odstraní zbytečné bílé místo (mezery) z výstupu. Můžete také použít {/block} ``` -Vypíše: +Výstup: ```latte
  • Hello
@@ -797,7 +798,7 @@ Vypíše: stripHtml .[filter] ------------------- -Převádí HTML na čistý text. Tedy odstraní z něj HTML značky a HTML entity převede na text. +Filtr `stripHtml` převádí HTML na čistý text. Odstraní HTML značky a převede HTML entity na jejich textovou reprezentaci. ```latte {='

one < two

'|stripHtml} {* vypíše 'one < two' *} @@ -808,7 +809,7 @@ Výsledný čistý text může přirozeně obsahovat znaky, které představují substr(int offset, int length = null) .[filter] ----------------------------------------------- -Extrahuje část řetězce. Tento filtr byl nahrazen filtrem [#slice]. +Filtr `substr` extrahuje část řetězce. Tento filtr byl nahrazen filtrem [#slice]. ```latte {$string|substr: 1, 2} @@ -817,7 +818,7 @@ Extrahuje část řetězce. Tento filtr byl nahrazen filtrem [#slice]. translate(string message, ...args) .[filter] -------------------------------------------- -Překládá výrazy do jiných jazyků. Aby byl filtr k dispozici, je potřeba [nastavit překladač|develop#TranslatorExtension]. Můžete také použít [tagy pro překlad|tags#Překlady]. +Filtr `translate` překládá výrazy do jiných jazyků. Aby byl filtr k dispozici, je potřeba [nastavit překladač|develop#TranslatorExtension]. Můžete také použít [tagy pro překlad|tags#Překlady]. ```latte {='Košík'|translate} @@ -827,7 +828,7 @@ Překládá výrazy do jiných jazyků. Aby byl filtr k dispozici, je potřeba [ trim(string charlist = " \t\n\r\0\x0B\u{A0}") .[filter] ------------------------------------------------------- -Odstraní prázdné znaky (nebo jiné znaky) od začátku a konce řetězce. +Filtr `trim` odstraní bílé znaky (nebo jiné zadané znaky) od začátku a konce řetězce. ```latte {=' I like Latte. '|trim} {* vypíše 'I like Latte.' *} @@ -837,7 +838,7 @@ Odstraní prázdné znaky (nebo jiné znaky) od začátku a konce řetězce. truncate(int length, string append = '…') .[filter] --------------------------------------------------- -Ořízne řetězec na uvedenou maximální délku, přičemž se snaží zachovávat celá slova. Pokud dojde ke zkrácení řetězce, přidá nakonec trojtečku (lze změnit druhým parametrem). +Filtr `truncate` zkrátí řetězec na uvedenou maximální délku, přičemž se snaží zachovávat celá slova. Pokud dojde ke zkrácení řetězce, přidá nakonec trojtečku (lze změnit druhým parametrem). ```latte {var $title = 'Hello, how are you?'} @@ -849,7 +850,7 @@ Ořízne řetězec na uvedenou maximální délku, přičemž se snaží zachov upper .[filter] --------------- -Převede řetězec na velká písmena. Vyžaduje PHP rozšíření `mbstring`. +Filtr `upper` převede řetězec na velká písmena. Vyžaduje PHP rozšíření `mbstring`. ```latte {='latte'|upper} {* vypíše 'LATTE' *} @@ -860,9 +861,9 @@ Viz také [#capitalize], [#firstUpper], [#lower]. webalize .[filter] ------------------ -Upraví UTF‑8 řetězec do tvaru používaného v URL. +Filtr `webalize` upraví UTF-8 řetězec do tvaru používaného v URL. -Převádí se na ASCII. Převede mezery na pomlčky. Odstraní znaky, které nejsou alfanumerické, podtržítka ani pomlčky. Převede na malá písmena. Také odstraní přední a koncové mezery. +Převádí znaky na ASCII ekvivalenty. Převádí mezery na pomlčky. Odstraní znaky, které nejsou alfanumerické, podtržítka ani pomlčky. Převádí text na malá písmena. Také odstraní úvodní a koncové bílé znaky. ```latte {var $s = 'Náš 10. produkt'} diff --git a/latte/cs/functions.texy b/latte/cs/functions.texy index c765b63c79..7f4fd0e8e0 100644 --- a/latte/cs/functions.texy +++ b/latte/cs/functions.texy @@ -2,24 +2,24 @@ Latte funkce ************ .[perex] -V šablonách můžeme kromě běžných PHP funkcí používat i tyto další. +V šablonách Latte můžeme kromě běžných PHP funkcí využívat i další speciální funkce, které rozšiřují možnosti při práci s daty a šablonami. .[table-latte-filters] -| `clamp` | [ohraničí hodnotu do daného rozsahu |#clamp] -| `divisibleBy`| [zkontroluje, zda je proměnná dělitelná číslem |#divisibleBy] -| `even` | [zkontroluje, zda je dané číslo sudé |#even] -| `first` | [vrací první prvek pole nebo znak řetězce |#first] -| `group` | [seskupí data podle různých kritérií |#group] -| `hasBlock` | [zjistí existenci bloku |#hasBlock] -| `last` | [vrací poslední prvek pole nebo znak řetězce |#last] -| `odd` | [zkontroluje, zda je dané číslo liché |#odd] +| `clamp` | [omezí hodnotu do zadaného rozsahu |#clamp] +| `divisibleBy`| [ověří dělitelnost čísla |#divisibleBy] +| `even` | [zkontroluje, zda je číslo sudé |#even] +| `first` | [získá první prvek pole nebo znak řetězce |#first] +| `group` | [seskupí data podle zadaných kritérií |#group] +| `hasBlock` | [ověří existenci bloku |#hasBlock] +| `last` | [získá poslední prvek pole nebo znak řetězce |#last] +| `odd` | [zkontroluje, zda je číslo liché |#odd] | `slice` | [extrahuje část pole nebo řetězce |#slice] Použití ======= -Funkce se používají strejně jaké běžné PHP funkce a lze je použít ve všechn výrazech: +Funkce v Latte se používají stejně jako běžné PHP funkce a lze je využít ve všech výrazech: ```latte

{clamp($num, 1, 100)}

@@ -27,14 +27,14 @@ Funkce se používají strejně jaké běžné PHP funkce a lze je použít ve v {if odd($num)} ... {/if} ``` -[Vlastní funkce|extending-latte#funkce] lze registrovat tímto způsobem: +[Vlastní funkce|extending-latte#funkce] můžete do Latte přidat takto: ```php $latte = new Latte\Engine; $latte->addFunction('shortify', fn(string $s, int $len = 10) => mb_substr($s, 0, $len)); ``` -V šabloně se potom volá takto: +V šabloně pak tuto funkci můžete volat následovně: ```latte

{shortify($text)}

@@ -48,7 +48,7 @@ Funkce clamp(int|float $value, int|float $min, int|float $max): int|float .[method] ---------------------------------------------------------------------------- -Ohraničí hodnotu do daného inkluzivního rozsahu min a max. +Funkce `clamp` omezí hodnotu do zadaného inkluzivního rozsahu mezi `$min` a `$max`. ```latte {=clamp($level, 0, 255)} @@ -59,7 +59,7 @@ Viz také [filtr clamp|filters#clamp]. divisibleBy(int $value, int $by): bool .[method] ------------------------------------------------ -Zkontroluje, zda je proměnná dělitelná číslem. +Funkce `divisibleBy` ověří, zda je číslo `$value` dělitelné číslem `$by`. ```latte {if divisibleBy($num, 5)} ... {/if} @@ -68,7 +68,7 @@ Zkontroluje, zda je proměnná dělitelná číslem. even(int $value): bool .[method] -------------------------------- -Zkontroluje, zda je dané číslo sudé. +Funkce `even` zkontroluje, zda je dané číslo sudé. ```latte {if even($num)} ... {/if} @@ -77,7 +77,7 @@ Zkontroluje, zda je dané číslo sudé. first(string|iterable $value): mixed .[method] ---------------------------------------------- -Vrací první prvek pole nebo znak řetězce: +Funkce `first` vrací první prvek pole nebo první znak řetězce: ```latte {=first([1, 2, 3, 4])} {* vypíše 1 *} @@ -89,9 +89,9 @@ Viz také [#last], [filtr first|filters#first]. group(iterable $data, string|int|\Closure $by): array .[method]{data-version:3.0.16} ------------------------------------------------------------------------------------ -Funkce seskupí data podle různých kritérií. +Funkce `group` seskupí data podle zadaných kritérií. -V tomto příkladu se řádky v tabulce seskupují podle sloupce `categoryId`. Výstupem je pole polí, kde klíčem je hodnota ve sloupci `categoryId`. [Přečtěte si podrobný návod|cookbook/grouping]. +V tomto příkladu se řádky v tabulce seskupují podle sloupce `categoryId`. Výsledkem je pole polí, kde klíčem je hodnota ve sloupci `categoryId`. [Podrobný návod najdete zde|cookbook/grouping]. ```latte {foreach group($items, categoryId) as $categoryId => $categoryItems} @@ -108,7 +108,7 @@ Viz také filtr [group|filters#group]. hasBlock(string $name): bool .[method]{data-version:3.0.10} ----------------------------------------------------------- -Zjistí, zda blok uvedeného jména existuje: +Funkce `hasBlock` ověří, zda existuje blok s uvedeným názvem: ```latte {if hasBlock(header)} ... {/if} @@ -119,7 +119,7 @@ Viz také [kontrola existence bloků|template-inheritance#Kontrola existence blo last(string|array $value): mixed .[method] ------------------------------------------ -Vrací poslední prvek pole nebo znak řetězce: +Funkce `last` vrací poslední prvek pole nebo poslední znak řetězce: ```latte {=last([1, 2, 3, 4])} {* vypíše 4 *} @@ -131,7 +131,7 @@ Viz také [#first], [filtr last|filters#last]. odd(int $value): bool .[method] ------------------------------- -Zkontroluje, zda je dané číslo liché. +Funkce `odd` zkontroluje, zda je dané číslo liché. ```latte {if odd($num)} ... {/if} @@ -140,17 +140,17 @@ Zkontroluje, zda je dané číslo liché. slice(string|array $value, int $start, int $length=null, bool $preserveKeys=false): string|array .[method] ---------------------------------------------------------------------------------------------------------- -Extrahuje část pole nebo řetězce. +Funkce `slice` extrahuje část pole nebo řetězce. ```latte {=slice('hello', 1, 2)} {* vypíše 'el' *} {=slice(['a', 'b', 'c'], 1, 2)} {* vypíše ['b', 'c'] *} ``` -Filtr funguje jako funkce PHP `array_slice` pro pole nebo `mb_substr` pro řetězce s fallbackem na funkci `iconv_substr` v režimu UTF‑8. +Tato funkce funguje podobně jako PHP funkce `array_slice` pro pole nebo `mb_substr` pro řetězce (s fallbackem na `iconv_substr` v režimu UTF-8). -Pokud je start kladný, posloupnost začné posunutá o tento počet od začátku pole/řetezce. Pokud je záporný posloupnost začné posunutá o tolik od konce. +- Pokud je `$start` kladný, výsledek začíná od tohoto indexu od začátku pole/řetězce. Pokud je záporný, začíná se od konce. -Pokud je zadaný parametr length a je kladný, posloupnost bude obsahovat tolik prvků. Pokud je do této funkce předán záporný parametr length, posloupnost bude obsahovat všechny prvky původního pole, začínající na pozici start a končicí na pozici menší na length prvků od konce pole. Pokud tento parametr nezadáte, posloupnost bude obsahovat všechny prvky původního pole, začínající pozici start. +- Pokud je `$length` kladný, výsledek bude obsahovat tolik prvků. Pokud je záporný, výsledek bude obsahovat všechny prvky kromě posledních `$length` prvků. Pokud není zadán, výsledek bude obsahovat všechny prvky od `$start` do konce. -Ve výchozím nastavení filtr změní pořadí a resetuje celočíselného klíče pole. Toto chování lze změnit nastavením preserveKeys na true. Řetězcové klíče jsou vždy zachovány, bez ohledu na tento parametr. +- Parametr `$preserveKeys` určuje, zda zachovat původní klíče pole. Ve výchozím nastavení (false) jsou číselné klíče resetovány. Řetězcové klíče jsou vždy zachovány bez ohledu na toto nastavení. diff --git a/latte/cs/recipes.texy b/latte/cs/recipes.texy index 90d74badb3..11389d60c2 100644 --- a/latte/cs/recipes.texy +++ b/latte/cs/recipes.texy @@ -5,19 +5,19 @@ Tipy a triky Editory a IDE ============= -Pište šablony v editoru nebo IDE, který má podporu pro Latte. Bude to mnohem příjemnější. +Efektivní práce s Latte šablonami začíná u správně nastaveného vývojového prostředí. Vhodný editor nebo IDE s podporou Latte vám významně usnadní práci a zvýší produktivitu. -- NetBeans IDE má podporu vestavěnou -- PhpStorm: nainstalujte v `Settings > Plugins > Marketplace` [plugin Latte|https://plugins.jetbrains.com/plugin/7457-latte] -- VS Code: hledejte v marketplace [Nette Latte + Neon|https://marketplace.visualstudio.com/items?itemName=Kasik96.latte] nebo [Nette Latte templates|https://marketplace.visualstudio.com/items?itemName=smuuf.latte-lang] plugin -- Sublime Text 3: v Package Control najděte a nainstalujte balíček `Nette` a zvolte Latte ve `View > Syntax` -- ve starých editorech použijte pro soubory .latte zvýrazňování Smarty +- PhpStorm: v `Settings > Plugins > Marketplace` nainstalujte [plugin Latte|https://plugins.jetbrains.com/plugin/7457-latte] +- VS Code: vyhledejte a nainstalujte [Nette Latte + Neon|https://marketplace.visualstudio.com/items?itemName=Kasik96.latte] nebo [Nette Latte templates|https://marketplace.visualstudio.com/items?itemName=smuuf.latte-lang] plugin +- NetBeans IDE: nativní podpora Latte je součástí instalace +- Sublime Text 3: přes Package Control nainstalujte balíček `Nette` a v `View > Syntax` zvolte Latte +- Pro starší editory: použijte zvýrazňování syntaxe pro Smarty u souborů s příponou .latte -Plugin pro PhpStorm je velmi pokročilý a umí výborně napovídat PHP kód. Aby fungoval optimálně, používejte [typované šablony|type-system]. +Plugin pro PhpStorm vyniká pokročilými funkcemi a nabízí vynikající napovídání PHP kódu. Pro jeho optimální funkčnost doporučujeme používat [typované šablony|type-system]. [* latte-phpstorm-plugin.webp *] -Podporu pro Latte najdete také ve webovém zvýrazňovači kódu [Prism.js|https://prismjs.com/#supported-languages] a editoru [Ace|https://ace.c9.io]. +Podporu Latte najdete také v online zvýrazňovači kódu [Prism.js|https://prismjs.com/#supported-languages] a webovém editoru [Ace|https://ace.c9.io]. Latte uvnitř JavaScriptu nebo CSS @@ -37,9 +37,11 @@ Latte lze velmi pohodlně používat i uvnitř JavaScriptu nebo CSS. Jak se vša ``` -**Varianta 1** +Existuje několik řešení: -Vyhněte se situaci, kdy následuje písmeno hned za `{`, třeba tím, že před něj vložíte mezeru, odřádkování nebo uvozovku: +**Řešení 1: Oddělení závorek** + +Vložte mezeru, odřádkování nebo uvozovku mezi `{` a následující písmeno: ```latte `. Naopak v atributech `style` a `on***` se pomocí HTML entit escapuje. -A samozřejmě uvnitř vnořeného JavaScriptu nebo CSS platí escapovací pravidla těchto jazyků. Takže řetezec v atributu např. `onload` se nejprve escapuje podle pravidel JS a potom podle pravidel HTML atributu. +A samozřejmě uvnitř vnořeného JavaScriptu nebo CSS platí escapovací pravidla těchto jazyků. Řetězec v atributu například `onload` se nejprve escapuje podle pravidel JS a potom podle pravidel HTML atributu. -Uff... Jak vidíte, HTML je velmi komplexní dokument, kde se vrství kontexty, a bez uvědomění si, kde přesně data vypisuji (tj. v jakém kontextu), nelze říct, jak to správně udělat. +Jak vidíte, HTML je velmi komplexní dokument, kde se vrství kontexty. Bez uvědomění si, kde přesně data vypisuji (tj. v jakém kontextu), nelze říct, jak to správně udělat. Chcete příklad? --------------- -Mějme řetězec `Rock'n'Roll`. +Vezměme řetězec `Rock'n'Roll`. -Pokud jej budete vypisovat v HTML textu, zrovna v tomhle případě netřeba dělat žádné záměny, protože řetězec neobsahuje žádný znak se speciálním významem. Jiná situace nastane, pokud jej vypíšete uvnitř HTML atributu uvozeného do jednoduchých uvozovek. V takovém případě je potřeba escapovat uvozovky na HTML entity: +Pokud jej budete vypisovat v HTML textu, v tomto konkrétním případě není třeba provádět žádné záměny, protože řetězec neobsahuje žádný znak se speciálním významem. Jiná situace nastane, pokud jej vypíšete uvnitř HTML atributu ohraničeného jednoduchými uvozovkami. V takovém případě je potřeba escapovat uvozovky na HTML entity: ```html
``` -Tohle bylo jednoduché. Mnohem zajímavější situace nastane při vrstvení kontextů, například pokud řetězec bude součástí JavaScriptu. +To bylo jednoduché. Mnohem zajímavější situace nastane při vrstvení kontextů, například pokud řetězec bude součástí JavaScriptu. -Nejprve jej tedy vypíšeme do samotného JavaScriptu. Tj. obalíme jej do uvozovek a zároveň escapujeme pomocí znaku `\` uvozovky v něm obsažené: +Nejprve jej vypíšeme do samotného JavaScriptu. Obalíme jej do uvozovek a zároveň escapujeme pomocí znaku `\` uvozovky v něm obsažené: ```js 'Rock\'n\'Roll' ``` -Ještě můžeme doplnit volání nějaké funkce, ať kód něco dělá: +Doplňme volání nějaké funkce, ať kód něco dělá: ```js alert('Rock\'n\'Roll'); ``` -Pokud tento kód vložíme do HTML dokumentu pomocí ``: ```html @@ -174,13 +173,13 @@ Pokud bychom jej však chtěli vložit do HTML atributu, musíme ještě escapov
``` -Vnořeným kontextem ale nemusí být jen JS nebo CSS. Běžně jím je také URL. Parametry v URL se escapují tak, že se znaky se speciálním významen převádějí na sekvence začínající `%`. Příklad: +Vnořeným kontextem ale nemusí být jen JS nebo CSS. Běžně jím je také URL. Parametry v URL se escapují tak, že se znaky se speciálním významem převádějí na sekvence začínající `%`. Příklad: ``` https://example.org/?a=Jazz&b=Rock%27n%27Roll ``` -A když tento řetězec vypíšeme v atributu, ještě aplikujeme escapování podle tohoto kontextu a nahradíme `&` za `&`: +A když tento řetězec vypíšeme v atributu, ještě aplikujeme escapování podle tohoto kontextu a nahradíme `&` za `&`: ```html @@ -192,13 +191,13 @@ Pokud jste dočetli až sem, gratulujeme, bylo to vyčerpávající. Teď už m Latte vs naivní systémy ======================= -Ukázali jsem si, jak se správně escapuje v HTML dokumentu a jak zásadní je znalost kontextu, tedy místa, kde data vypisujeme. Jinými slovy, jak funguje kontextově sensitvní escapování. -Ačkoliv jde o nezbytný předpoklad funkční obrany před XSS, **Latte je jediný šablonovací systém pro PHP, který tohle umí.** +Ukázali jsme si, jak se správně escapuje v HTML dokumentu a jak zásadní je znalost kontextu, tedy místa, kde data vypisujeme. Jinými slovy, jak funguje kontextově sensitivní escapování. +Ačkoliv jde o nezbytný předpoklad funkční obrany před XSS, **Latte je jediný šablonovací systém pro PHP, který tohle umí**. Jak je to možné, když všechny systémy dnes tvrdí, že mají automatické escapování? -Automatické escapování bez znalosti kontextu je trošku bullshit, který **vytváří falešný dojem bezpečí**. +Automatické escapování bez znalosti kontextu je poněkud zavádějící a **vytváří falešný dojem bezpečí**. -Šablonovací systémy, jako je Twig, Laravel Blade a další, nevidí v šabloně žádnou HTML strukturu. Nevidí tudíž ani kontexty. Oproti Latte jsou slepé a naivní. Zpracovávají jen vlastní značky, vše ostatní je pro ně nepodstatný tok znaků: +Šablonovací systémy jako Twig, Laravel Blade a další nevidí v šabloně žádnou HTMLstrukturu. Nevidí tudíž ani kontexty. Oproti Latte jsou slepé a naivní. Zpracovávají jen vlastní značky, vše ostatní je pro ně nepodstatný tok znaků:
@@ -230,7 +229,7 @@ Automatické escapování bez znalosti kontextu je trošku bullshit, který **vy
-Naivní systémy jen mechanicky převádějí znaky `< > & ' "` na HTML entity, což je sice ve většině případů užití platný způsob escapování, ale zdaleka ne vždy. Nemohou tak odhalit ani předejít vzniku různých bezpečnostní děr, jak si ukážeme dále. +Naivní systémy pouze mechanicky převádějí znaky `< > & ' "` na HTML entity, což je sice ve většině případů platný způsob escapování, ale zdaleka ne vždy. Nemohou tak odhalit ani předejít vzniku různých bezpečnostních děr, jak si ukážeme dále. Latte šablonu vidí stejně jako vy. Chápe HTML, XML, rozeznává značky, atributy atd. A díky tomu rozlišuje jednotlivé kontexty a podle nich ošetřuje data. Nabízí tak opravdu efektivní ochranu proti kritické zranitelnosti Cross-site Scripting. @@ -270,63 +269,60 @@ Vlevo vidíte šablonu v Latte, vpravo je vygenerovaný HTML kód. Několikrát
-Není to skvělé! Latte dělá kontextově sensitivní escapování automaticky, takže programátor: +Není to skvělé! Latte provádí kontextově sensitivní escapování automaticky, takže programátor: - nemusí přemýšlet ani vědět, jak se kde escapuje - nemůže se splést - nemůže na escapování zapomenout -Tohle dokonce nejsou všechny kontexty, které Latte při vypisování rozlišuje a pro které přizpůsobuje ošetření dat. Další zajimavé případy si projdeme nyní. +Tohle dokonce nejsou všechny kontexty, které Latte při vypisování rozlišuje a pro které přizpůsobuje ošetření dat. Další zajímavé případy si projdeme nyní. Jak hacknout naivní systémy =========================== -Na několika praktických příkladech si ukážeme, jak je rozlišování kontextů důležité a proč naivní šablonovací systémy neposkytují dostatečnou ochranu před XSS, na rozdíl od Latte. -Jako zástupce naivního systému použijeme v ukázkách Twig, ale totéž platí i pro ostatní systémy. +Nyní si na praktických příkladech ukážeme, proč je rozlišování kontextů tak důležité a proč naivní šablonovací systémy neposkytují dostatečnou ochranu před XSS, na rozdíl od Latte. +V ukázkách použijeme Twig jako zástupce naivních systémů, ale podobné principy platí i pro ostatní systémy. -Zranitelnost atributem ----------------------- +Zranitelnost pomocí atributu +---------------------------- -Pokusíme se do stránky injektovat škodlivý kód pomocí HTML atributu, jak jsme si [ukazovali výše|#Jak zranitelnost vzniká]. Mějme šablonu v Twigu vykreslující obrázek: +Pokusme se injektovat škodlivý kód do stránky pomocí HTML atributu. Představme si šablonu v Twigu pro vykreslení obrázku: ```twig .{file:Twig} {{ ``` -Všimněte si, že okolo hodnot atributů nejsou uvozovky. Kodér na ně mohl zapomenout, což se prostě stává. Například v Reactu se kód píše takto, bez uvozovek, a kodér, který střídá jazyky, pak na uvozovky může snadno zapomenout. +Všimněte si chybějících uvozovek kolem hodnot atributů. Takové opomenutí se může snadno stát, zejména když vývojář střídá různé technologie (např. v Reactu se atributy píší bez uvozovek). -Útočník jako popisek obrázku vloží šikovně sestavený řetězec `foo onload=alert('Hacked!')`. Už víme, že Twig nemůže poznat, jestli se proměnná vypisuje v toku HTML textu, uvnitř atributu, HTML komentáře, atd., zkrátka nerozlišuje kontexty. A jen mechanicky převádí znaky `< > & ' "` na HTML entity. -Takže výsledný kód bude vypadat takto: +Útočník by mohl jako popisek obrázku vložit řetězec `foo onload=alert('Hacked!')`. Twig nedokáže rozpoznat kontext, ve kterém se proměnná vypisuje, a pouze mechanicky převede znaky `< > & ' "` na HTML entity. Výsledný kód bude vypadat takto: ```html foo ``` -**A vznikla bezpečností díra!** +**Vznikla bezpečnostní díra!** Do stránky se dostal podvržený atribut `onload`, který prohlížeč spustí ihned po načtení obrázku. -Součástí stránky se stal podvržený atribut `onload` a prohlížeč ihned po stažení obrázku jej spustí. - -Nyní se podíváme, jak si se stejnou šablonou poradí Latte: +Srovnejme to s Latte: ```latte .{file:Latte} {$imageAlt} ``` -Latte vidí šablonu stejně jako vy. Na rozdíl od Twigu chápe HTML a ví, že proměnná se vypisuje jako hodnota atributu, který není v uvozovkách. Proto je doplní. Když útočník vloží stejný popisek, výsledný kód bude vypadat takto: +Latte chápe strukturu HTML a rozpozná, že proměnná se vypisuje jako hodnota atributu bez uvozovek. Proto je automaticky doplní. I když útočník vloží stejný škodlivý řetězec, výsledek bude bezpečný: ```html foo onload=alert('Hacked!') ``` -**Latte úspěšně zabránilo XSS.** +**Latte úspěšně odvrátilo XSS útok.** -Vypsání proměnné v JavaScript ------------------------------ +Bezpečné použití proměnných v JavaScriptu +----------------------------------------- -Díky kontextově sensitivnímu escapování je možné zcela nativně používat PHP proměnné uvnitř JavaScriptu. +Díky kontextově citlivému escapování můžete v Latte bezpečně používat PHP proměnné přímo v JavaScriptu: ```latte

{$movie}

@@ -334,7 +330,7 @@ Díky kontextově sensitivnímu escapování je možné zcela nativně používa ``` -Pokud bude proměnná `$movie` obsahovat řetězec `'Amarcord & 8 1/2'`, vygeneruje se následující výstup. Všimněte si, že uvnitř HTML se použije jiné escapování, než uvnitř JavaScriptu a ještě jiné v atributu `onclick`: +Pokud `$movie` obsahuje řetězec `'Amarcord & 8 1/2'`, Latte vygeneruje následující kód: ```latte

Amarcord & 8 1/2

@@ -342,11 +338,13 @@ Pokud bude proměnná `$movie` obsahovat řetězec `'Amarcord & 8 1/2'`, vygener ``` +Všimněte si, jak Latte použilo různé metody escapování pro HTML text, JavaScript v atributu `onclick` a JavaScript uvnitř tagu ` ``` -To je také důvod, proč se kolem proměnné **nepíší uvozovky**: Latte je u řetězců doplní samo. A pokud byste chtěli řetězcovou proměnnou vložit do jiného řetězce, jednoduše je spojte: +To je také důvod, proč se kolem proměnné **nepíší uvozovky**: Latte je u řetězců doplní samo. Pokud chcete řetězcovou proměnnou vložit do jiného řetězce, jednoduše je spojte: ```latte ``` -Latte lze velmi pohodlně používat i uvnitř JavaScriptu, jen se stačí vynout konstrukcím jako v tomto příkladě, kdy následuje písmeno hned za `{`, viz [Latte uvnitř JavaScriptu nebo CSS|recipes#Latte uvnitř JavaScriptu nebo CSS]. +Latte lze velmi pohodlně používat i uvnitř JavaScriptu, jen se stačí vyhnout konstrukcím jako v tomto příkladě, kdy následuje písmeno hned za `{`, viz [Latte uvnitř JavaScriptu nebo CSS|recipes#Latte uvnitř JavaScriptu nebo CSS]. -Pokud Latte vypnete pomocí `{syntax off}` (tj. značkou, nikoliv n:atributem), bude důsledně ignorovat všechny značky až do `{/syntax}` +Pokud Latte vypnete pomocí `{syntax off}` (tj. značkou, nikoliv n:atributem), bude důsledně ignorovat všechny značky až do `{/syntax}`. {trace} @@ -941,7 +938,7 @@ n:class Díky `n:class` velice snadno vygenerujete HTML atribut `class` přesně podle představ. -Příklad: potřebuji, aby aktivní prvek měl třídu `active`: +Příklad: potřebujeme, aby aktivní prvek měl třídu `active`: ```latte {foreach $items as $item} @@ -971,7 +968,7 @@ A všechny prvky mají mít třídu `list-item`: n:attr ------ -Atribut `n:attr` umí se stejnou elegancí jako má [n:class|#n:class] generovat libovolné HTML atributy. +Atribut `n:attr` umí se stejnou elegancí jako [n:class|#n:class] generovat libovolné HTML atributy. ```latte {foreach $data as $item} diff --git a/latte/cs/template-inheritance.texy b/latte/cs/template-inheritance.texy index ab6e030bdb..6c62b34f1c 100644 --- a/latte/cs/template-inheritance.texy +++ b/latte/cs/template-inheritance.texy @@ -2,15 +2,15 @@ Dědičnost a znovupoužitelnost šablon ************************************ .[perex] -Mechanismy opětovného použití a dědičnosti šablon zvýší vaši produktivitu, protože každá šablona obsahuje pouze svůj jedinečný obsah a opakované prvky a struktury se znovupoužijí. Představujeme tři koncepty: [#layoutová dědičnost], [#horizontální znovupoužití] a [#jednotková dědičnost]. +Mechanismy dědičnosti a znovupoužitelnosti šablon v Latte významně zvyšují produktivitu vývojářů. Každá šablona tak může obsahovat pouze svůj jedinečný obsah, zatímco opakující se prvky a struktury se efektivně znovupoužívají. V této kapitole představíme tři klíčové koncepty: [layoutovou dědičnost|#layoutová dědičnost], [#horizontální znovupoužití] a [jednotkovou dědičnost|#jednotková dědičnost]. -Koncept dědičnosti šablon Latte je podobný dědičnosti tříd v PHP. Definujete **nadřazenou šablonu**, od které mohou dědit další **podřízené šablony** a mohou přepsat části nadřazené šablony. Funguje to skvěle, když prvky sdílejí společnou strukturu. Zní to komplikovaně? Nebojte se, je to velmi snadné. +Koncept dědičnosti šablon v Latte je analogický k dědičnosti tříd v PHP. Definujete **nadřazenou šablonu**, od které mohou další **podřízené šablony** dědit a případně přepisovat její části. Tento přístup je zvláště účinný, když různé prvky sdílejí společnou strukturu. Ačkoli to může znít složitě, v praxi jde o velmi intuitivní a snadno použitelný systém. Layoutová dědičnost `{layout}` .{toc:Layoutová dědičnost} ========================================================= -Podívejme se na dědičnost šablony rozložení, tedy layoutu, rovnou příkladem. Toto je nadřazená šablona, kterou budeme nazývat například `layout.latte` a která definuje kostru HTML dokumentu: +Podívejme se na layoutovou dědičnost na konkrétním příkladu. Následující ukázka představuje nadřazenou šablonu, kterou můžeme nazvat například `layout.latte`. Tato šablona definuje základní kostru HTML dokumentu: ```latte @@ -30,36 +30,36 @@ Podívejme se na dědičnost šablony rozložení, tedy layoutu, rovnou příkla ``` -Značky `{block}` definují tři bloky, které mohou podřízené šablony vyplnit. Značka block dělá jen to, že oznámí, že toto místo může podřízená šablona přepsat definováním vlastního bloku se stejným názvem. +Značky `{block}` zde vymezují tři bloky, které mohou podřízené šablony naplnit vlastním obsahem. Blok v tomto kontextu jednoduše označuje místo, které může podřízená šablona přepsat definováním vlastního bloku se stejným názvem. -Podřízená šablona může vypadat takto: +Podřízená šablona pak může vypadat například takto: ```latte {layout 'layout.latte'} -{block title}My amazing blog{/block} +{block title}Můj úžasný blog{/block} {block content} -

Welcome to my awesome homepage.

+

Vítejte na mé skvělé domovské stránce.

{/block} ``` -Klíčem je zde značka `{layout}`. Říká Latte, že tato šablona „rozšiřuje“ další šablonu. Když Latte vykresluje tuto šablonu, nejprve najde nadřazenou šablonu - v tomto případě `layout.latte`. +Klíčovým prvkem je zde značka `{layout}`. Ta Latte sděluje, že tato šablona "rozšiřuje" jinou šablonu. Při vykreslování této šablony Latte nejprve nalezne nadřazenou šablonu - v tomto případě `layout.latte`. -V tomto okamžiku si Latte všimne tří blokových značek v `layout.latte` a nahradí tyto bloky obsahem podřízené šablony. Vzhledem k tomu, že podřízená šablona nedefinovala blok *footer*, použije se místo toho obsah z nadřazené šablony. Obsah ve značce `{block}` v nadřazené šabloně se vždy používá jako záložní. +V tomto okamžiku Latte identifikuje tři blokové značky v `layout.latte` a nahradí tyto bloky obsahem z podřízené šablony. Vzhledem k tomu, že podřízená šablona nedefinovala blok *footer*, použije se pro tento blok obsah z nadřazené šablony. Obsah uvnitř značky `{block}` v nadřazené šabloně vždy slouží jako výchozí, pokud není přepsán. -Výstup může vypadat takto: +Výsledný výstup může vypadat následovně: ```latte - My amazing blog + Můj úžasný blog
-

Welcome to my awesome homepage.

+

Vítejte na mé skvělé domovské stránce.