Como aparar o texto do corpo (field_body)?

10

Eu criei uma exibição para um nó que mostra o conteúdo como entidade renderizada. Entre outros, eu mostro o campo body no modelo de galho:

{{ content.field_body }}

Agora, gostaria de limitar o texto a 200 caracteres e colocar três pontos. Eu testei três maneiras diferentes de fazer isso, mas nada funcionou. O problema é que cada caminho conta e apara os caracteres HTML também.

1: Adicionei o formato "Aparado" em "Gerenciar exibição" => O texto é limitado, mas não está correto. E eu não tenho os três pontos.

2: Eu aparei o texto no modelo de galho. Mas para contar o texto, tenho que renderizá-lo primeiro. Assim, o twig gera o texto como HTML (vejo tags HTML na minha página!)

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

3: Tentei resolver o problema em template_preprocess_node (). Aqui também tenho o mesmo problema em contar a marcação HTML.

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

Como posso aparar meu texto corretamente?

Muito obrigado pela sua ajuda!

marco-s
fonte

Respostas:

18

Existem algumas soluções que você pode tentar, mas observe que truncar cadeias de caracteres com html geralmente é uma má idéia devido a possíveis tags não fechadas ou malformadas.

1. Use | raw para gerar o html como html, pode produzir tags malformadas:

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

2. Remova o html primeiro, mais limpo:

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

3. Registre uma extensão de galho (não testada):

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

Outra extensão útil que você pode conferir é a extensão de texto, que ajuda a evitar a quebra de palavras:

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

squall3d
fonte
2
primeira solução tags malformados e segunda solução tira todas as tags html.
Yusef
1
@zhilevan sim, conforme descrito na resposta.
squall3d
1
@ squall3d Qual é a sua solução para cortá-la sem strip htmls?
Yusef
1
@zhilevan normalmente, quando eu quero exibir texto truncado, é para um teaser, onde raramente quero html. Mas se você precisa preservar o html, pode tentar esta extensão: gist.github.com/leon/2857883
squall3d 25/16
1
Se eu usar a imagem no campo do corpo. Nº 2, não está funcionando para imagens. Existe algum outro código, irá imprimir a imagem bem
logeshvaran
5

Agora você pode fazer isso com o módulo twig_extender e usá-lo |truncate.

Aqui está um exemplo de como usá-lo no modelo .twig, observe que também estou usando twig_field_value :

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

Nota: Normalmente, mantenho minhas configurações de desenvolvimento (./admin/config/development/devel) definidas para usar o varfumper dumper Symfony e posso descobrir a cadeia com

ou seja: {{ devel_dump(content.field_name|field_value) }}

bdanin
fonte
4

Melhorias:

  1. se você tira tags que você deve |trimpara se livrar de espaço em branco
  2. aparar no limite da palavra - veja abaixo slice()esplit()
  3. Use reticências ( …) em vez de "..."
  4. |raw a saída

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

É assim que eu lidei com isso.

Exemplo:
campo - nó - corpo - 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 %}
...
Vagner
fonte