symfony 2 twig limit the length of the text and put three dots
Asked Answered
S

16

155

How can I limit the length of the text, e.g., 50, and put three dots in the display?

{% if myentity.text|length > 50 %}

{% block td_text %} {{ myentity.text}}{% endblock %}

{%endif%}
Shelbashelbi answered 30/10, 2012 at 16:0 Comment(1)
The "three dots" is actually a single character called an Ellipsis. This is three full stops ... and this is an Ellipsis Grata
V
235
{{ myentity.text|length > 50 ? myentity.text|slice(0, 50) ~ '...' : myentity.text  }}

You need Twig 1.6

Vulcanism answered 30/10, 2012 at 16:6 Comment(8)
this should be the answer, still working till now ;)Colonize
How can we add a link to ... ?Capstan
Additionally, if you want to crop on a word, you can do it like this: {{ text > 50 ? text|slice(0, 51)|split(' ')|slice(0, -1)|join(' ') ~ '…' : text }}. I also recommend using the ellipsis character () instead of 3 real dots (...)Luminary
Shorter: {{ myentity.text[:50] ~ (myentity.text|length > 50 ? '...') }}Crosswalk
@Luminary you're just missing the |length after the first text but that's perfect, thank you!Modiolus
Yes don't forget "|length" {{ text|length > 50 ? text|slice(0, 51)|split(' ')|slice(0, -1)|join(' ') ~ '…' : text }}Escurial
Thanks it works {{ item.text|length > 50 ? item.text|slice(0, 50) ~ '...' : item.text }}Daye
@martias reply above (the shorter option) worked well for me. Drupal 8.6.Accredit
N
128

why not use twig's truncate or wordwrap filter? It belongs to twig extensions and lib is part of Symfony2.0 as i see.

{{ text|truncate(50) }}
Nickelplate answered 30/10, 2012 at 16:43 Comment(5)
I'm using Symfony 2.3 and the truncate filter is not part of the default extensions. Therefore, I resorted to Manuel's solution instead.Crinkly
To enable the extension in Symfony add this to one of your configuration files: gist.github.com/pschultz/f33bfff72692ca0b6916Estoppel
To append ..., the second parameter should be set to true such as {{ text|truncate(50, true)Englert
Actually setting the second parameter to true would make it preserve whole words. It adds the ellipses by default. The third parameter can change the ellipses to anything you want. twig-extensions.readthedocs.io/en/latest/…Bradberry
Using Symfony 2.8, I had to install this extension to use it. require twig/extensionsBradberry
L
39

Another one is:

{{ myentity.text[:50] ~ '...' }}
Longshoreman answered 15/6, 2013 at 0:0 Comment(3)
the only problem is that it always shows the dots... :/ think i will go with the first solution.Schrick
Please, can you share the link where the doc about this [x:x] is located ?Babineaux
Always with the three dots there... doesn't really answer the question.Kinesiology
S
21

I know this is a very old question, but from twig 1.6 you can use the slice filter;

{{ myentity.text|slice(0, 50) ~ '...' }}

The second part from the tilde is optional for if you want to add something for example the ellipsis.

Edit: My bad, I see the most up-voted answer do make use of the slice filter.

Spendthrift answered 11/5, 2016 at 21:15 Comment(0)
O
16

Update for Twig 2 and Twig 3.

truncate filter is not available, instead of it you may use u-filter

here is an example:

{{ 'Lorem ipsum'|u.truncate(8) }}
Lorem ip

{{ 'Lorem ipsum'|u.truncate(8, '...') }}
Lorem...

Note: this filter is part of StringExtension that can be required by

twig/string-extra
Osrick answered 19/6, 2020 at 22:44 Comment(2)
Had to add Twig\Extra\String\StringExtension: null in the twig_extensions.yamlDevitrify
Yes. composer require twig/string-extraRocky
A
14

@olegkhuss solution with named UTF-8 Elipsis: {{ (my.text|length > 50 ? my.text|slice(0, 50) ~ '…' : my.text) }}

Acred answered 16/12, 2016 at 14:24 Comment(2)
Please keep in mind this solution enables HTML injection through the text variable.Impeccant
@michael-zukowski Your are right. I have changed my solution.Acred
P
10

@mshobnr / @olegkhuss solution made into a simple macro:

{% macro trunc(txt, len) -%}
    {{ txt|length > len ? txt|slice(0, len) ~ '…' : txt }}
{%- endmacro %}

Usage example:

{{ tools.trunc('This is the text to truncate. ', 50) }}

N.b. I import a Twig template containing macros and import it as 'tools' like this (Symfony):

{% import "@AppBundle/tools.html.twig" as tools -%}

Also, I replaced the html character code with the actual character, this should be no problem when using UTF-8 as the file encoding. This way you don't have to use |raw (as it could cause a security issue).

Prevalent answered 28/4, 2017 at 9:39 Comment(0)
S
7

Use the truncate filter to cut off a string after limit is reached

{{ "Hello World!"|truncate(5) }} // default separator is ...

Hello...

You can also tell truncate to preserve whole words by setting the second parameter to true. If the last Word is on the the separator, truncate will print out the whole Word.

 {{ "Hello World!"|truncate(7, true) }} // preserve words

Here Hello World!

If you want to change the separator, just set the third parameter to your desired separator.

{{ "Hello World!"|truncate(7, false, "??") }} 

Hello W??

Stupe answered 20/1, 2020 at 14:18 Comment(0)
P
6

An even more elegant solution is to limit the text by the number of words (and not by number of characters). This prevents ugly tear throughs (e.g. 'Stackov...').

Here's an example where I shorten only text blocks longer than 10 words:

{% set text = myentity.text |split(' ') %} 

{% if text|length > 10 %} 
    {% for t in text|slice(0, 10) %}
        {{ t }} 
    {% endfor %}
    ...
{% else %}
    {{ text|join(' ') }}
{% endif %}
Prohibitionist answered 1/12, 2015 at 11:50 Comment(0)
S
2

You can limit in following way. First is starting index and second is number of characters.

**{{ results['text'][4:2] }}**
Senary answered 10/12, 2014 at 13:50 Comment(0)
A
1

if anyone needs this from the modern world, since this question is so old, I would do it this way: I would definitely not want to have an incomplete word at the end, therefor I prefer to do it with the following steps: limiting the wanted length of characters, exploid my text into a bunch of arrays of sentences separated with a comma or a dot depends on your text, remove the last array which represent the incomplete word then joining or imploiding those arrays together and of course do not forget to join them with that dot we removed when exploiding the string of characters, and outside of the twig {{}} add your three dots, with that been said it will look something like this:

{{myentity.text|slice(0,50)|split('.')|slice(0,-1)|join('.')}}...

<a href="#">readeMore</a>

Ambages answered 22/6, 2021 at 18:5 Comment(1)
Only prints out "..." whenever the text doesn't have a dot in the first 50 characters, it seems.Excurvate
R
1

u.truncate could be a modern option. An example from docs:

{{ 'Lorem ipsum dolor'|u.truncate(10, '...', false) }}
Lorem ipsum...

This solution requires string-extra:

composer require twig/string-extra
Rodomontade answered 8/5, 2023 at 19:6 Comment(0)
T
0

I wrote this simple marco for the same purpose, hope it helps:

{%- macro stringMaxLength(str, maxLength) -%}
    {%- if str | length < maxLength -%}
        {{ str }}
    {%- else -%}
        {{ str|slice(0, maxLength) }}...
    {%- endif -%}
{%- endmacro -%}

Usage Example #1 (Output: "my long string here ..."):

{{ _self.stringMaxLength("my long string here bla bla bla la", 20) }}

Usage Example #2 (Output: "shorter string!"):

{{ _self.stringMaxLength("shorter string!", 20) }}
Tryparsamide answered 11/9, 2015 at 5:47 Comment(0)
W
0

Bugginess* in the new Drupal 8 capabilities here inspired us to write our own:

<a href="{{ view_node }}">{% if title|length > 32 %}{% set title_array = title|split(' ') %}{% set title_word_count = 0 %}{% for ta in title_array %}{% set word_count = ta|length %}{% if title_word_count < 32 %}{% set title_word_count = title_word_count + word_count %}{{ ta }} {% endif %}{% endfor %}...{% else %}{{ title }}{% endif %}</a>

This takes into consideration both words and characters (*the "word boundary" setting in D8 was displaying nothing).

Windowsill answered 27/7, 2018 at 0:57 Comment(0)
K
0

In addition to Nemo64's comment under olegkhuss's response, I'd like to add that if you need to make the partial text to finishes on a word not a character, u can do this:

entity.text|split(' ', 11)|length > 10 ? entty.text|split(' ', 11)|slice(0, 10)|join(' ') ~ '…' : entity.text

In this example, all text with more than 10 words will be cuted after the 10th word.

Kinky answered 7/4, 2021 at 22:41 Comment(0)
T
-1

It is better to use an HTML character

{{ entity.text[:50] }}&#8230;
Tortricid answered 13/5, 2018 at 19:57 Comment(4)
Can you add some explanation to your answer? Why should one use a HTML entity? And why do you append it to the text in each and every case, even if the text is less than 50 characters long?Abominable
Hi, if you write three dots it's three separate dots but the "three dots" character is called an ellipsis. The ellipsis html entity is &#8230;.Rist
And why not use the unicode character for that ellipsis?Abominable
You can use it too ! this comment was an answer to that comment https://mcmap.net/q/151263/-symfony-2-twig-limit-the-length-of-the-text-and-put-three-dots but that move was locked because of my reputationRist

© 2022 - 2024 — McMap. All rights reserved.