1
0
mirror of https://github.com/danog/liquid.git synced 2024-11-30 05:48:56 +01:00

Implement #15 truncate_words filter

This commit is contained in:
Oliver Steele 2017-07-10 16:47:11 -04:00
parent 06e0833633
commit fdfc5d3a81
3 changed files with 34 additions and 8 deletions

View File

@ -32,19 +32,24 @@ In brief, these aren't implemented:
- The `cycle` and `tablerow` tags
- `{% case %}…{% else %}` and `{% when a or b %}`
- The `escape`, `sort_natural`, `truncatewords`, `url_decode`, and `url_encode` filters
- The `sort_natural`, `url_decode`, and `url_encode` filters
- Loop ranges `{% for a in 1...10 %}`
- Error modes
- Whitespace control
These are opinionated differences that unlikely to change:
- The expression parser accepts parentheses in more locations
- The `truncatewords` filter leaves whitespace prior to the truncation point unchanged.
## Stability Guarantees
This library is at an early stage of development.
It has been mostly used by its author.
Until it reaches 1.0, breaking changes will accompanied by a bump in the minor version, not the major version. For example, use `go get gopkg.in/osteele/liquid.v0.2` to stay at versions that are compatible with the v0.2 API. The v0.3 release will not in general be compatible with version 0.2.
Until it reaches 1.0, breaking changes will accompanied by a bump in the minor version, not the major version. For example, tag `v0.2` is incompatible with `v0.1` and (hypothetical) `v0.1.1`. ([gopkg.in](http://gopkg.in) doesn't work this way, so you won't can't use `gopkg.in/osteele/liquid.v0.1` to specify version 0.1.)
Even within these parameters, only the liquid package itself, and the sub-package APIs that it documents, are guaranteed stable. For example, `render.Context` is documented as the parameter type for tag definitions; it therefore has the same stability guarantees as `liquid.Engine` and `liquid.Template`. Other "public" definitions in `render` and other sub-packages are public only to the implementation of packages in the repo; they are not generally stable.
Even within these parameters, only the liquid package itself, and the sub-package APIs that it documents, are guaranteed stable. For example, `render.Context` is documented as the parameter type for tag definitions; it therefore has the same stability guarantees as `liquid.Engine` and `liquid.Template`. Other "public" definitions in `render` and in other sub-packages are intended only for use in other packages in this repo; they are not generally stable between even sub-minor releases.
## Install

View File

@ -126,7 +126,6 @@ func AddStandardFilters(fd FilterDictionary) { // nolint: gocyclo
fd.AddFilter("escape_once", func(s, suffix string) string {
return html.EscapeString(html.UnescapeString(s))
})
// TODO test case for this
fd.AddFilter("newline_to_br", func(s string) string {
return strings.Replace(s, "\n", "<br />", -1)
})
@ -170,11 +169,23 @@ func AddStandardFilters(fd FilterDictionary) { // nolint: gocyclo
fd.AddFilter("rstrip", func(s string) string {
return strings.TrimRightFunc(s, unicode.IsSpace)
})
fd.AddFilter("truncate", func(s string, n int, ellipsis func(string) string) string {
fd.AddFilter("truncate", func(s string, length func(int) int, ellipsis func(string) string) string {
n := length(50)
el := ellipsis("...")
// runes aren't bytes; don't use slice
p := regexp.MustCompile(fmt.Sprintf(`^(.{%d})..{%d,}`, n-len(el), len(el)))
return p.ReplaceAllString(s, `$1`+el)
re := regexp.MustCompile(fmt.Sprintf(`^(.{%d})..{%d,}`, n-len(el), len(el)))
return re.ReplaceAllString(s, `$1`+el)
})
fd.AddFilter("truncatewords", func(s string, length func(int) int, ellipsis func(string) string) string {
el := ellipsis("...")
n := length(15)
// re := regexp.MustCompile(fmt.Sprintf(`^\s*(?:\S+\s+){%d}`, n))
re := regexp.MustCompile(fmt.Sprintf(`^(?:\s*\S+){%d}`, n))
m := re.FindString(s)
if m == "" {
return s
}
return m + el
})
fd.AddFilter("upcase", func(s, suffix string) string {
return strings.ToUpper(s)

View File

@ -52,7 +52,6 @@ var filterTests = []struct {
{`"apples, oranges, peaches, plums" | split: ", " | size`, 4},
// string filters
// TODO escape, truncatewords, url_decode, url_encode
{`"Take my protein pills and put my helmet on" | replace: "my", "your"`, "Take your protein pills and put your helmet on"},
{`"Take my protein pills and put my helmet on" | replace_first: "my", "your"`, "Take your protein pills and put my helmet on"},
{`"/my/fancy/url" | append: ".html"`, "/my/fancy/url.html"},
@ -62,6 +61,7 @@ var filterTests = []struct {
{`"Parker Moore" | downcase`, "parker moore"},
{`"Have you read 'James & the Giant Peach'?" | escape`, "Have you read &#39;James &amp; the Giant Peach&#39;?"},
{`"1 < 2 & 3" | escape_once`, "1 &lt; 2 &amp; 3"},
{`string_with_newlines | newline_to_br`, "<br />Hello<br />there<br />"},
{`"1 &lt; 2 &amp; 3" | escape_once`, "1 &lt; 2 &amp; 3"},
{`"apples, oranges, and bananas" | prepend: "Some fruit: "`, "Some fruit: apples, oranges, and bananas"},
{`"I strained to see the train through the rain" | remove: "rain"`, "I sted to see the t through the "},
@ -75,6 +75,15 @@ var filterTests = []struct {
{`"Ground control to Major Tom." | truncate: 25, ", and so on"`, "Ground control, and so on"},
{`"Ground control to Major Tom." | truncate: 20, ""`, "Ground control to Ma"},
{`"Ground" | truncate: 20`, "Ground"},
{`"Ground control to Major Tom." | truncatewords: 3`, "Ground control to..."},
{`"Ground control to Major Tom." | truncatewords: 3, "--"`, "Ground control to--"},
{`"Ground control to Major Tom." | truncatewords: 3, ""`, "Ground control to"},
{`"Ground control" | truncatewords: 3, ""`, "Ground control"},
{`"Ground" | truncatewords: 3, ""`, "Ground"},
{`" Ground" | truncatewords: 3, ""`, " Ground"},
{`"" | truncatewords: 3, ""`, ""},
{`" " | truncatewords: 3, ""`, " "},
{`"Parker Moore" | upcase`, "PARKER MOORE"},
{`" So much room for activities! " | strip`, "So much room for activities!"},
{`" So much room for activities! " | lstrip`, "So much room for activities! "},
@ -157,6 +166,7 @@ var filterTestBindings = map[string]interface{}{
{"weight": 3},
{"weight": nil},
},
"string_with_newlines": "\nHello\nthere\n",
"page": map[string]interface{}{
"title": "Introduction",
},