diff --git a/README.md b/README.md index c975351..23ca9d8 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Build Status](https://travis-ci.org/flosch/pongo2-addons.svg?branch=master)](https://travis-ci.org/flosch/pongo2-addons) [![Gratipay](http://img.shields.io/badge/gratipay-support%20pongo-brightgreen.svg)](https://gratipay.com/flosch/) -Official filter and tag add-ons for [pongo2](https://github.com/flosch/pongo2). Since this package uses +Official filter and tag add-ons for [pongo2](https://github.com/flosch/pongo2). Since this package uses 3rd-party-libraries, it's in its own package. ## How to install and use @@ -24,10 +24,11 @@ All additional filters/tags will be registered automatically. - **[filesizeformat](https://docs.djangoproject.com/en/dev/ref/templates/builtins/#filesizeformat)** (human-readable filesize; takes bytes as input) - **[slugify](https://docs.djangoproject.com/en/dev/ref/templates/builtins/#slugify)** (creates a slug for a given input) - **truncatesentences** / **truncatesentences_html** (returns the first X sentences [like truncatechars/truncatewords]; please provide X as a parameter) + - **random** (returns a random element of the input slice) - Markup - **markdown** - + - Humanize - **[intcomma](https://docs.djangoproject.com/en/dev/ref/contrib/humanize/#intcomma)** (put decimal marks into the number) - **[ordinal](https://docs.djangoproject.com/en/dev/ref/contrib/humanize/#ordinal)** (convert integer to its ordinal as string) diff --git a/filters.go b/filters.go index 0091981..6474eff 100644 --- a/filters.go +++ b/filters.go @@ -3,6 +3,7 @@ package pongo2addons import ( "bytes" "fmt" + "math/rand" "regexp" "strings" "time" @@ -17,11 +18,14 @@ import ( ) func init() { + rand.Seed(time.Now().UTC().UnixNano()) + // Regulars pongo2.RegisterFilter("slugify", filterSlugify) pongo2.RegisterFilter("filesizeformat", filterFilesizeformat) pongo2.RegisterFilter("truncatesentences", filterTruncatesentences) pongo2.RegisterFilter("truncatesentences_html", filterTruncatesentencesHTML) + pongo2.RegisterFilter("random", filterRandom) // Markup pongo2.RegisterFilter("markdown", filterMarkdown) @@ -218,6 +222,24 @@ func filterTruncatesentencesHTML(in *pongo2.Value, param *pongo2.Value) (*pongo2 return pongo2.AsSafeValue(newOutput.String()), nil } +func filterRandom(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { + if !in.CanSlice() { + return nil, &pongo2.Error{ + Sender: "filter:random", + OrigError: errors.New("input is not sliceable"), + } + } + + if in.Len() <= 0 { + return nil, &pongo2.Error{ + Sender: "filter:random", + OrigError: errors.New("input slice is empty"), + } + } + + return in.Index(rand.Intn(in.Len())), nil +} + func filterTimeuntilTimesince(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { basetime, isTime := in.Interface().(time.Time) if !isTime { diff --git a/filters_test.go b/filters_test.go index b2b45ca..6d146f5 100644 --- a/filters_test.go +++ b/filters_test.go @@ -89,4 +89,10 @@ func (s *TestSuite1) TestFilters(c *C) { c.Assert(getResult("{{ text|truncatesentences_html:3 }}", pongo2.Context{ "text": `
`}), Equals, `
`) + + // Random + c.Assert(getResult("{{ array|random }}", + pongo2.Context{"array": []int{42}}), + Equals, "42") + }