0

I am using Spring Boot with Thymeleaf, and I'm passing the post object to the view resolver. I only want to display a certain portion of the post.content field, meaning something like this

example:
This is the column from the database.
____
---------------
 content column
---------------
text text text t
ext text text
---------------

So I want to display only a certain number of characters in the .html page like here:

Your text: text text te... 'read more' 

I have tried

<p id="postcontent" th:utext="${#strings.substring(${post.content},0,12)}"></p>

However, I get a template parsing error and then I tried

<p id="postcontent" th:utext="${#strings.substring(post.content,0,12)}"></p>

This just prints the whole content of the expression.

L.E So, I found the correct syntax which is

th:utext="${#strings.substring(post.content,0,17)}"

The issue now is that, if the string is smaller than the desired length, I get a

Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: 17

Is there a way to fix this? Lets say this will never happen because there will never be a post content with such a short length, but I want to have a way to manage this exception.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
helloApp
  • 449
  • 1
  • 4
  • 21
  • PLease concider to update your question and provide the error you are getting from thymeleaf. – Marcinek Oct 25 '20 at 16:26
  • @Marcinek hello, i have made the modification and found the correct syntax but now i am having another issue. – helloApp Oct 25 '20 at 16:37
  • Is this something you are looking for: https://stackoverflow.com/questions/42599878/ava-lang-stringindexoutofboundsexception-string-index-out-of-range-9-at-java-l – Marcinek Oct 25 '20 at 16:45
  • @Marcinek not quite, i would like to know if there is a way to solve it on the frontend with thymeleaf.To make a check or something for length of String. – helloApp Oct 25 '20 at 17:35
  • In practical terms, your task would be simpler overall if you created your "abbreviator" as a distinct Java method and called that, either via static invocation or by adding your own `#thing` to the context, which is [pretty easy](https://www.thymeleaf.org/doc/articles/sayhelloextendingthymeleaf5minutes.html) (in Spring Boot, you don't even have to mess with the `@Bean` method, just make your `IDialect` a bean and it will get wired in). Among other things, this would make testing and reuse simpler. – chrylis -cautiouslyoptimistic- Oct 25 '20 at 17:38
  • 1
    @helloApp maybe abbreviate() will work better than substring() ?https://stackoverflow.com/questions/49897473/i-want-to-abbreviate-a-string-with-thymeleaf – Alexandre Levieux Oct 25 '20 at 17:50

2 Answers2

2

To understand your error, you have to know what strings are.

Strings in java are arrays of char:

char[] example = {'H', 'E', 'L', 'L', 'O');

You can manipulate strings in a similar why to arrays. Arrays first index is 0 and max Index length - 1

Let now assume the above example is an instance of String and you do:

example.subString (0, 3) // Return value would be "HEL". 

example.subString (0, 10) // StringIndexOutOfBoundsException

To prevent this, you have to use whats ever come first. Your cap at 17 or the cap defined by the length of the string.

example.subString (0, Math.min(17, example.length()));

While there is no built in function in Thymeleaf, you can use the special T(...) operator to call static methods (allowing you to use Java's Math.max(...) in your Thymeleaf).

<div th:with="maxNumber=${T(Math).min(8,12)}">
   <p th:text=${maxNumber}></p>
</div>

As mentioned in the comments, there is a more Thymeleaf special method to approach your goal:

I want to abbreviate a string with Thymeleaf

Marcinek
  • 2,144
  • 1
  • 19
  • 25
  • 1
    @Alexandre Levieux and Marcinek thank you ! abbreviate was just what i needed, it works perfectly no matter how long the string is ! – helloApp Oct 25 '20 at 22:44
1

You can also use a condition to take care of out of bounds e.g.

    <span th:if="${post.content.length()>17}">
    <span th:utext="${#strings.substring(post.content,0,17)}"></span>
    </span>
    <span th:if="${post.content.length()<17}">
    <span th:utext="${#strings.substring(post.content,0,post.content.length())}"></span>
    </span>
Procrastinator
  • 2,526
  • 30
  • 27
  • 36