Wie schneide ich Körpertext (field_body)?

10

Ich habe eine Ansicht für einen Knoten erstellt, in der der Inhalt als gerenderte Entität angezeigt wird. Unter anderem gebe ich das Körperfeld in der Zweigvorlage aus:

{{ content.field_body }}

Jetzt möchte ich den Text auf 200 Zeichen beschränken und drei Punkte setzen. Ich habe drei verschiedene Möglichkeiten getestet, aber nichts hat funktioniert. Das Problem ist, dass jeder Weg auch die HTML-Zeichen zählt und trimmt.

1: Ich habe das Format "Beschnitten" in "Anzeige verwalten" hinzugefügt => Der Text ist begrenzt, aber nicht korrekt. Und ich habe die drei Punkte nicht.

2: Ich habe den Text in der Zweigvorlage zugeschnitten. Aber um den Text zu zählen, muss ich ihn zuerst rendern. Dabei gibt twig den Text als HTML aus (ich sehe HTML-Tags auf meiner Seite!)

{% set text = content.field_body|render %}
{{ text|length > 200 ? text|slice(0, 200) ~ '...' : text }}

3: Ich habe versucht, das Problem in template_preprocess_node () zu lösen. Hier habe ich das gleiche Problem beim Zählen des HTML-Markups.

$body_text = $node->get('field_body')->getValue()[0]['value'];
$trimmed_text = substr($body_text, 0, 200) . '...';

Wie kann ich meinen Text richtig zuschneiden?

Vielen Dank für Ihre Hilfe!

marco-s
quelle

Antworten:

18

Es gibt einige Lösungen, die Sie ausprobieren können. Beachten Sie jedoch, dass das Abschneiden von Zeichenfolgen mit HTML im Allgemeinen eine schlechte Idee ist, da möglicherweise nicht geschlossene oder fehlerhafte Tags vorhanden sind.

1. Verwenden Sie | raw, um den HTML-Code als HTML auszugeben. Dies kann zu fehlerhaften Tags führen:

{% set text = content.field_body|render %}
{{ text|length > 200 ? text|slice(0, 200)|raw ~ '...' : text|raw }}

2. Zuerst HTML entfernen, sauberer:

{% set text = content.field_body|render|striptags %}
{{ text|length > 200 ? text|slice(0, 200) ~ '...' : text }}

3. Registrieren Sie eine Zweigerweiterung (ungetestet):

https://gist.github.com/leon/2857883

Eine weitere hilfreiche Erweiterung, die Sie auschecken können, ist die Text-Erweiterung, mit der Sie verhindern können, dass Wörter zerhackt werden:

http://twig.sensiolabs.org/doc/extensions/text.html

squall3d
quelle
2
fehlerhafte Tags der ersten Lösung und zweite Lösung entfernen alle HTML-Tags.
Yusef
1
@zhilevan yep, wie in der Antwort beschrieben.
squall3d
1
@ squall3d Was ist deine Lösung für Slice It ohne Strip Htmls?
Yusef
1
@zhilevan normalerweise, wenn ich abgeschnittenen Text anzeigen möchte, dient dies dem Zweck eines Teasers, bei dem ich selten HTML möchte. Aber wenn Sie HTML beibehalten müssen, können Sie diese Erweiterung versuchen: gist.github.com/leon/2857883
squall3d
1
Wenn ich das Bild im Körperfeld verwende. Nr. 2 funktioniert nicht für Bilder. Gibt es einen anderen Code, wird das Bild auch
gedruckt
5

Sie können dies jetzt mit dem Modul twig_extender tun und verwenden |truncate.

Hier ist ein Beispiel für die Verwendung in der .twig-Vorlage. Beachten Sie, dass ich auch twig_field_value verwende :

{{ content.field_name|field_value|first['#text']|truncate(15, true, '....') }}

Hinweis: Normalerweise behalte ich meine Entwicklungseinstellungen (./admin/config/development/devel) für die Verwendung von Symfony var-dumper bei und kann die Kette mit herausfinden

dh: {{ devel_dump(content.field_name|field_value) }}

Bdanin
quelle
4

Verbesserungen:

  1. Wenn Sie Tags Streifen sollten Sie |trimzu von Leerzeichen loszuwerden
  2. Trimmen Sie an der Wortgrenze - siehe unten slice()undsplit()
  3. Verwenden Sie Ellipsen ( …) anstelle von "..."
  4. |raw die Ausgabe

{% set text = content.field_header_intro|render|striptags|trim %}

{{ (text|length > 200 ? text|slice(0, 201)|split(' ')|slice(0, -1)|join(' ') ~ '&hellip;' : text)|raw }}</code>

Duncanmoo
quelle
3

So habe ich damit umgegangen.

Beispiel:
Feld - Knoten - Körper - Artikel.html.twig

{% set mode = element['#view_mode'] %}
...
{% for item in items %}
  {% if mode == 'full' %}
    <div{{ attributes.addClass('texto') }}>{{ item.content }}</div>
  {% elseif mode == 'teaser' %}
    {# if there is something about trim_length in field formatter #}
    {% if item.content['#text_summary_trim_length'] %}
      {# first remove html tags then you slice with trim_length #}
      {% set texto = item.content['#text']|striptags|slice(0, item.content['#text_summary_trim_length']) %}
      <p {{ attributes }}>{{ texto }}...</p>
    {% else %}
      <p {{ attributes }}>{{ item.content }}</p>
    {% endif %}
  {% endif %}
{% endfor %}
...
Vagner
quelle