How to truncate a string in a Golang template

后端 未结 7 555
轮回少年
轮回少年 2021-01-01 09:16

In golang, is there a way to truncate text in an html template?

For example, I have the following in my template:

{{ range .SomeContent }}
 ....
             


        
7条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-01 10:12

    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)
            }
        }
    }
    

提交回复
热议问题