twigtruncatetwig-filter

How to add "Read More" in text displayed on several lines but only a certain number of lines with twig


I am using the following function in twig to show a part of the content of the description of a news item saved in a database:

{{ new.description|striptags|truncate(300,true)|raw|nl2br }}

With this function inside a p element in the html, I get the text whose characters do not exceed 300 and then I add "Read More" with an element a:

<p >{{  new.description|striptags|truncate(200,true)|raw|nl2br }}
  <a class="href_blue" href="{{ path('new', {'id': new.id}) }}">
  <strong> [Read More] </strong></a>
</p>

This code works for text that comes in a paragraph with more than 300 characters, but if for example I have another one with several "p" elements that are then changed in twig to
elements and I need it to only show me several lines because I have A maximum elevation of the container where it is displayed, I would not know how to do it, since it shows me all line breaks until it does not exceed 300 characters.

To clarify it a little more, I show an image of the result: enter image description here

What I need is that in the case of Title2 having many line breaks, just show some and add the "Read More" before so that the height of the div is equal to the previous one (to show the example I removed the max- Height and overflow: hidden).

How could I get that?

I greet your help in advance.


Solution

  • You could do something like this in Twig:

    {% set paragraphs = new.description|split('</p>') %}
    {% set summary = '' %}
    {% for i in 1..10 %}
        {% set summary = summary ~ paragraphs[i] %}
    {% endfor %}
    
    {% set summary = summary ~ '[Read More]' %}
    

    Now you can use the summary variable in your twig file to show the truncated summary.

    EDIT #2 based on comments

    Then try this instead:

    {% set paragraphs = new.description|split('</p>') %}
    {% set summary = '' %}
    {% for i in 1..(paragraphs|length) %}
        {% set summary = summary ~ paragraphs[i] %}
        {% if summary|length > 300 %}
            {% set shortsummary = summary %}
        {% endif %}
    {% endfor %}
    
    {% set final_summary = shortsummary|slice(:300) ~ '[Read More]' %}
    

    EDIT #3 Code modified with the solution to the problem

    {% set paragraphs = new.description|striptags|truncate(300,true)|raw|nl2br %}
    
    {% set paragraphs = paragraphs|split('<br />') %}
    
    {% set summary = "" %}
    {% set cont = 90 %}
    {% set type = "" %}
    
    {% if paragraphs|length == 1 %}
       {% set summary =  paragraphs[0] %}
       {% if summary|length <= 300 %}
          {% set type = "" %}
       {% else %}
          {% set type = "anything" %}
       {% endif %}
    {% else %}
       {% for i in 1..(paragraphs|length) %}
          {% if summary|length + cont + paragraphs[i-1]|length  <= 500 %}
              {% set summary = summary  ~ "<br>" ~ paragraphs[i-1] %}
              {% set cont = cont + 90 %}
          {% else %}
              {% set type = "anything" %}
          {% endif %}
       {% endfor %}
    {% endif %}
    
    //In the case of a description with less than 300 characters the option "Read More" is not shown
    {% if type != "" %}
      <p>{{ summary|striptags|truncate(300,true)|raw|nl2br }}<a class="href_blue" href="{{ path('new', {'id': new.id}) }}"> <strong> [Read More] </strong></a></p>
    {% else %}
      <p>{{ summary|striptags|truncate(300,true)|raw|nl2br }}<a class="href_blue" href="{{ path('new', {'id': new.id}) }}"></a></p>
    {% endif %}