web-dev-qa-db-fra.com

Comment découper le corps du texte (field_body)?

J'ai créé une vue pour un nœud qui montre le contenu comme entité rendue. Entre autres, je génère le champ du corps dans le modèle twig:

{{ content.field_body }}

Maintenant, je voudrais limiter le texte à 200 caractères et mettre trois points. J'ai testé trois façons différentes de le faire, mais rien n'a fonctionné. Le problème est que chaque manière compte et coupe également les caractères HTML.

1: J'ai ajouté le format "Trimmed" dans "Manage display" => Le texte est limité mais pas correct. Et je n'ai pas les trois points.

2: J'ai coupé le texte dans le modèle twig. Mais pour compter le texte, je dois d'abord le rendre. De ce fait, twig renvoie le texte comme HTML (je vois des balises HTML sur ma page!)

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

3: J'ai essayé de résoudre le problème dans template_preprocess_node (). Ici, j'ai le même problème avec le comptage du balisage HTML aussi.

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

Comment puis-je couper mon texte correctement?

Merci beaucoup pour votre aide!

10
marco-s

Il y a quelques solutions que vous pouvez essayer, mais prenez note que tronquer des chaînes avec du html est généralement une mauvaise idée en raison de la présence potentielle de balises non fermées ou mal formées.

1. Utiliser | raw pour sortir le html en html, peut produire des balises malformées:

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

2. Supprimer d'abord le code HTML, plus propre:

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

3. Enregistrez une extension twig (non testée):

https://Gist.github.com/leon/285788

Une autre extension utile que vous pouvez consulter est l'extension de texte, qui vous aide à éviter de couper des mots:

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

18
squall3d

Vous pouvez maintenant le faire avec le module twig_extender et utiliser |truncate.

Voici un exemple de la façon de l'utiliser dans le modèle .twig, notez que j'utilise également twig_field_value :

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

note: Je garde généralement mes paramètres de développement (./admin/config/development/devel) définis à utiliser Symfony var-dumper et peut comprendre la chaîne avec

c'est-à-dire: {{ devel_dump(content.field_name|field_value) }}

5
bdanin

Améliorations:

  1. si vous supprimez les balises, vous devez |trim à se débarrasser des espaces
  2. rogner sur la limite de Word - voir ci-dessous slice() et split()
  3. Utilisez points de suspension (…) Plutôt que "..."
  4. |raw La sortie

{% 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>

4
Duncanmoo

C'est ainsi que j'ai géré cela.

Exemple:
champ - nœud - corps - article.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 %}
...
3
Vagner