In golang, is there a way to truncate text in an html template?
For example, I have the following in my template:
{{ range .SomeContent }}
....
There are a lot of good answers, but sometimes it's more user-friendly to truncate without cutting words. Hugo offers template function for it. But it's difficult to use outside of Hugo, so I've implemented it:
func TruncateByWords(s string, maxWords int) string {
processedWords := 0
wordStarted := false
for i := 0; i < len(s); {
r, width := utf8.DecodeRuneInString(s[i:])
if !isSeparator(r) {
i += width
wordStarted = true
continue
}
if !wordStarted {
i += width
continue
}
wordStarted = false
processedWords++
if processedWords == maxWords {
const ending = "..."
if (i + len(ending)) >= len(s) {
// Source string ending is shorter than "..."
return s
}
return s[:i] + ending
}
i += width
}
// Source string contains less words count than maxWords.
return s
}
And here is a test for this function:
func TestTruncateByWords(t *testing.T) {
cases := []struct {
in, out string
n int
}{
{"a bcde", "a...", 1},
{"a b", "a b", 2},
{"a b", "a b", 3},
{"a b c", "a b c", 2},
{"a b cd", "a b cd", 2},
{"a b cde", "a b...", 2},
{" a b ", " a b...", 2},
{"AB09C_D EFGH", "AB09C_D...", 1},
{"Привет Гоферам", "Привет...", 1},
{"Here are unicode spaces", "Here are...", 2},
}
for i, c := range cases {
got := TruncateByWords(c.in, c.n)
if got != c.out {
t.Fatalf("#%d: %q != %q", i, got, c.out)
}
}
}