str_replace in Twig - und anwenden auf {{ content }}
am 26.04.2016 - 22:49 Uhr in
In Twig gibt es zwar ein replace Filter, allerdings funktioniert dieses Filter die halbe Zeit nicht, denn man weiß bei der Anwendung nie, ob man es gerade auf einen String, auf ein Array oder ein Objekt anwendet. Am ehesten funktioniert der replace Filter, wenn man ihn auf einen selbst gesetzten String anwendet. Man braucht aber meist eine andere Variante:
In einem Twig Template soll vor der Ausgabe von
{{ content }}
ein Teilstring in content durch einen anderen String ersetzt werden.
Wie macht man das?
Ein Ansatz:
{% set my_string = 'Das ist irgendein String' %}
{% set search = 'irgendein' %}
{% set replace = 'MEIN' %}
Ergebnis: {{ my_string|replace({ (search): replace }) }}
Mit ein wenig Glück funktioniert das.
Nun soll aber ein Teilstring in 'content' ersetzt werden.
Das geht nicht.
Denn dieser Befehl alleine ist schon unmöglich:
{% set my_string = content %}
Das geht anscheinend nicht, weil 'content' kein String sondern wohl ein Objekt (oder Array) ist.
Auch direkt ohne zuerst an Variablen zuzuweisen geht es nicht.
Man braucht Stunden um verschiedene Varianten auszutesten, denn man muss jedesmal eine halbe Minute lang oder länger den Cache löschen bei jedem Versuch. Dann kommt fast bei jedem zweiten Versuch eine nichtssagende Fehlermeldung
'Auf der Website ist ein unvorhergesehener Fehler aufgetreten. Bitte versuchen Sie es später nochmal.'
anstatt einer aussagekräftigen Twig-Fehlermeldung und man weiß wieder nicht, was falsch ist und lernt nichts dazu.
Und 'content' zuerst in einen String umzuwandeln um danach obigen Replace-Filter anwenden zu können geht auch nicht, denn es ist unmöglich 'content' in einen String umzuwandeln, dafür gibt es keine Lösung in Twig.
Falls hier schon jemand Erfahrung hat mit Twig:
Wie wandelt man 'content' in einen String um um dann diesen String der Variablen 'my_string' zuzuweisen?
Wie aktiviert sinnvolle man Twig-Fehlermeldungen?
Wie schafft man es, dass dump() nicht zum endlosen Laden der Webseite führt anstatt alle Variablen auszugeben? (kint() ist auch nicht die Lösung für alles, weil es nicht überall funktioniert. Ich möchte, dass dump() sinnvoll funktioniert, das muss doch möglich sein).
Und:
Wie kann man in 'content' vor der Ausgabe mit {{ content }} einen oder mehrere Teilstrings durch andere ersetzen?
Danke (Twig ist Programmieren wie in der Steinzeit!)
- Anmelden oder Registrieren um Kommentare zu schreiben
unerwünschter Inhalt sollte garnicht erst im Template landen
am 27.04.2016 - 07:08 Uhr
Inhalte sollte vor der Darestellung durch ein Template aufbereitet sein.
Die Nachbebastelung von Inhalten im Template war schon bisher eher unsaubere Programmierweise, und ist mit der Isolation des Templates von code nun erschwert.
Wer sauber programmiert, hat diese Probleme nicht.
Wenn ein String nicht passt, muss er vor der Übergabe an das Template bearbeitet werden.
In Twig sollte eine Programmierung nicht mehr nötig sein.
Grüße
Ronald
Ich gehe mal speziell hierauf
am 27.04.2016 - 07:52 Uhr
Ich gehe mal speziell hierauf ein:
Wie schafft man es, dass dump() nicht zum endlosen Laden der Webseite führt anstatt alle Variablen auszugeben? (kint() ist auch nicht die Lösung für alles, weil es nicht überall funktioniert. Ich möchte, dass dump() sinnvoll funktioniert, das muss doch möglich sein).
Das hat mich auch schon ein bisschen frustriert dass die Builtin-Debug-Funktion von Twig nicht funktioniert, obwohl kint für mich da schon seinen Zweck erfüllt.
Das Problem bei der dump-Funktion ist, dass diese bei großen Variablen (Objekten) wie sie in Drupal nicht selten vorkommen in eine Memory Limit Überschreitung hineinläuft. Das lässt sich teilweise auch nicht mit wirklich großen Memory Limits umgehen. Das Problem liegt hier aber nicht bei Drupal sondern bei Twig. Hier findet man einen sehr hilfreichen Post: http://stackoverflow.com/questions/14913859/twigs-dump-function-returns-...
In dem man also die Symfony Extension Vardumper installiert (https://packagist.org/packages/symfony/var-dumper) und dann den Code von Twig-Debug in vendor/twig/twig/lib/Twig/Extension/Debug.php so ändert, dass nicht var_dump sondern dump benutzt wird, erreicht man dass die Twig-Debug-Funktion auch mit großen Variablen klarkommt.
Twig - endloser Zeitaufwand
am 27.04.2016 - 09:33 Uhr
Inhalte sollte vor der Darestellung durch ein Template aufbereitet sein.
Die Nachbebastelung von Inhalten im Template war schon bisher eher unsaubere Programmierweise, und ist mit der Isolation des Templates von code nun erschwert.
Wer sauber programmiert, hat diese Probleme nicht.
Wenn ein String nicht passt, muss er vor der Übergabe an das Template bearbeitet werden.
In Twig sollte eine Programmierung nicht mehr nötig sein.
Ja, das habe ich mir auch gedacht. Ich möchte ja gar nicht etwas kompliziertes im Twig-Template programmieren, sondern lediglich einen kurzen String durch einen anderen ersetzen. In PHP wäre das ein str_replace() und fertig.
Da so etwas jetzt nicht mehr möglich ist, aber auch Designer und Nicht-Programmierer am Ende das Projekt fertig stellen müssen, werden auch Designer und Nicht-Programmierer solche einfache Dinge in Zukunft nicht im Template sondern in der _preprocess_..() Funktion in der .theme-Datei des Templates machen.
Dort können dann Designer und Nicht-Programmierer beliebig an der gesamten Datenstruktur Veränderungen machen und auch kritisch eingreifen. Jetzt erst recht wird dort gewütet und programmiert, was nur geht. Zuvor hatte kein Nicht-Programmierer eine Veranlassung an so kritischer Stelle einzufreigen. Jetzt lernt das aber jeder und daher ist der Sicherheitsaspekt, den Twig bringen sollte, dahin. Im Gegenteil, jeder Designer und Nicht-Programmierer lernt jetzt, wie man alles in PHP manipulieren kann und sobald man das kann, wird man es auch machen.
Der Vorteil von Twig ist also kein Vorteil mehr, es wird programmiert, was das Zeug hält, von jedem, auch von jemanden, der es eigentlich nicht kann.
Aber gleichzeitig sind die Nachteilte von Twig und der Rückfall in die Steinzeit der Programmierung bezüglich Twig-Debugging ein riesiges Probleme: Man verliert wegen winzigen Kleinigkeiten Stunden an Zeit, weil ein Debuggen nicht sinnvoll möglich ist. Dazu gibt es hier schon einige andere Twig-Postings, die sich mit dem Thema Debuggen beschäftigen.
Es wäre also schön, wenn mal jemand hier ein paar tatsächliche Vorteile von Twig aufzählen könnte? Solange Twig so umständlich in der Handhabung ist (keine sinnvolle Fehlermeldungen, ständiges Cache-Löschen nötig, extrem zeitaufwändig für Kleinigkeiten, ...) sind die wenigen Vorteile, die vielleicht noch bleiben, unbedeutend.
Aber zurück zum Thema:
Wie kann man nun das str_replace in der _preprocess - Funktion des Themes realisieren?
Twig dump-Lösung sollte sofort in Drupal 8.1 eingebaut werden
am 27.04.2016 - 09:36 Uhr
Ich gehe mal speziell hierauf ein:
Wie schafft man es, dass dump() nicht zum endlosen Laden der Webseite führt anstatt alle Variablen auszugeben? (kint() ist auch nicht die Lösung für alles, weil es nicht überall funktioniert. Ich möchte, dass dump() sinnvoll funktioniert, das muss doch möglich sein).
Das hat mich auch schon ein bisschen frustriert dass die Builtin-Debug-Funktion von Twig nicht funktioniert, obwohl kint für mich da schon seinen Zweck erfüllt.
Das Problem bei der dump-Funktion ist, dass diese bei großen Variablen (Objekten) wie sie in Drupal nicht selten vorkommen in eine Memory Limit Überschreitung hineinläuft. Das lässt sich teilweise auch nicht mit wirklich großen Memory Limits umgehen. Das Problem liegt hier aber nicht bei Drupal sondern bei Twig. Hier findet man einen sehr hilfreichen Post: http://stackoverflow.com/questions/14913859/twigs-dump-function-returns-...
In dem man also die Symfony Extension Vardumper installiert (https://packagist.org/packages/symfony/var-dumper) und dann den Code von Twig-Debug in vendor/twig/twig/lib/Twig/Extension/Debug.php so ändert, dass nicht var_dump sondern dump benutzt wird, erreicht man dass die Twig-Debug-Funktion auch mit großen Variablen klarkommt.
Und warum wurden diese Änderungen nicht in Drupal 8.1.0 eingebaut?
Wenn es eine Lösung gibt, sollte diese Lösung auch allen hunderttausenden Drupal-Nutzern zur Verfügung gestellt werden. Passiert das nicht, leidet das Image von Drupal 8 extrem unter diesem Twig-Problem. Tausenden könnten sich abwenden.
Hi, anstatt es so zu machen
am 27.04.2016 - 09:57 Uhr
Hi,
anstatt es so zu machen wie Du es gerade versuchst,
probier es einfach online mit http://twigfiddle.com/
,ob Du dort den String parsen kannst.
Da musst Du den Cache nicht löschen.
Es ist aber wie @Ronald gesagt hat, so etwas gehört nicht ins Template.
Gruss
Robert
https://awri.ch
Ich habe eine Schweizer Tastatur und daher kein scharfes ß ;-)
twigfiddle.com
am 27.04.2016 - 10:07 Uhr
Wie soll denn
http://twigfiddle.com
verwendet werden können, um hier lokal in meinem Template einen Teilstring in 'content' zu ersetzen durch einen anderen?
Ich weiß schon, komplexere Dinge wird man nicht in Twig programmieren, aber ein einfaches str_replace() angwendet auf einen anderen String ist nicht komplex.
Es geht ja auch darum, Twig kennen zu lernen, das Debugging kennen zu lernen usw. Dass man komplexere Programmierung in die preprocess-Function verlagern wird, ist klar, aber wie soll man mit Twig umgehen lernen, wenn do bei jedem kleinen Schritt Probleme auftreten und kein Debugging sinnvoll möglich ist (dazu gibt es mehrere andere Threads hier).
Zitat: Und warum wurden diese
am 27.04.2016 - 10:24 Uhr
Und warum wurden diese Änderungen nicht in Drupal 8.1.0 eingebaut?
Wenn es eine Lösung gibt, sollte diese Lösung auch allen hunderttausenden Drupal-Nutzern zur Verfügung gestellt werden. Passiert das nicht, leidet das Image von Drupal 8 extrem unter diesem Twig-Problem. Tausenden könnten sich abwenden.
Diese Frage kann ich nicht beantworten, aber wenn dann müsste das ja zunächst mal in den Issue Queues eingebracht werden und dort diskutiert werden. Das steht prinzipiell jedem offen ...
Die Problematik liegt bei allerdings bei TWIG, dort müsste der Code geändert werden. Und dass Drupal eine gepatchte TWIG-Version verwendet ist wohl eher nicht zu erwarten. Also wäre es eher eine Sache die beim TWIG-Projekt einzubringen wäre und von dort dann zu Drupal gelangen würde.
Ob das realistisch ist kann nicht beurteilen. Mein Gefühl sagt mir dass es eher in Richtung Devel und kint bzw. anderer Debug-Module geht und man die TWIG dump Funktion eher vernachlässigen wird.
Und hierzu: Zitat: Wie kann
am 27.04.2016 - 10:32 Uhr
Und hierzu:
Wie kann man nun das str_replace in der _preprocess - Funktion des Themes realisieren?
Du müsstest schon genauer sagen in welchem Template du was verändern willst. {{ content }} gibt es in verschiedenen Templates und der Aufbau und Inhalt ist unterschiedlich. Auf jeden Fall ist {{ content }} ja kein simpler String und ein str_replace in einer preprocess-Funktion wird dann auch auf einen bestimmten Teil von {{ content }} anzuwenden sein.
Im node-Template
am 27.04.2016 - 10:40 Uhr
Das wäre ganz einfach in einem Node-Template, z. Bsp. in node--blog.html.twig (oder ähnlich, man kann ja bliebige Inhaltstypen erstellen).
Und daher ist dir richtige Vorgangsweise in der .theme-Datei gesucht.
meintheme.theme:
function meintheme_preprocess_node() .. nehme ich an.
Und dann weiter?
Wie fragt man den richtigen Inhaltstyp ab?
Wie gelangt man an $content ?
Darin dann einen str_replace ..
und dann wohl über $variables['...'] zurückliefern ...
Ja: template_preprocess_node:
am 27.04.2016 - 11:28 Uhr
Ja: template_preprocess_node: https://api.drupal.org/api/drupal/core!modules!node!node.module/function/template_preprocess_node/8.0.x
Inhaltstyp:
$variables['node']->bundle()
Content ist in: $variables['content'], aber das ist genau das große Array (mit allen Feldern etc.) dass Du auch im TWIG-Template hast. Insofern musst Du hier schon schauen worauf Du ein str_replace machen willst.
getType()
am 29.04.2016 - 19:06 Uhr
$variables['node']->getType() ... so fragt man den Inhaltstyp ab
Zitat: $variables['node']->ge
am 01.05.2016 - 09:21 Uhr
$variables['node']->getType() ... so fragt man den Inhaltstyp ab
Das ist auch ein Weg zur Abfrage des Inhaltstyps. Das liefert das Gleiche zurück wie $variables['node']->bundle(), denn der Code von getType lautet:
public function getType() {
return $this->bundle();
}
Leichter zu merken
am 01.05.2016 - 11:12 Uhr
Das mag schon sein. Aber etwas, was unlogisch ist, merkt man sich keine zwei Minuten.
dazu muss man nur wissen
am 01.05.2016 - 19:42 Uhr
dass bundle ein synonym für content_type ist.
Grüße
Ronald