Skip to content

Commit

Permalink
Add some functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
leekchan committed Jul 20, 2015
1 parent f453f4a commit 62c4614
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 3 deletions.
80 changes: 80 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ If a panic occurs inside a gtf function, the function will silently swallow the
* [apnumber](#apnumber)
* [intcomma](#intcomma)
* [ordinal](#ordinal)
* [first](#first)
* [last](#last)
* [join](#join)
* [slice](#slice)



Expand Down Expand Up @@ -459,6 +463,82 @@ Converts an integer to its ordinal as a string.



#### first

Returns the first item in the given value.

* supported value types : string, slice, array

This function also supports unicode strings.

```
{{ value | first }}
```

**Examples**

1. If value is the string "The go programming language", the output will be the string "T".
1. If value is the string "안녕하세요", the output will be the string "안". (unicode)
1. If value is the slice []string{"go", "python", "ruby"}, the output will be the string "go".
1. If value is the array [3]string{"go", "python", "ruby"}, the output will be the string "go".



#### last

Returns the last item in the given value.

* supported value types : string, slice, array

This function also supports unicode strings.

```
{{ value | last }}
```

**Examples**

1. If value is the string "The go programming language", the output will be the string "e".
1. If value is the string "안녕하세요", the output will be the string "요". (unicode)
1. If value is the slice []string{"go", "python", "ruby"}, the output will be the string "ruby".
1. If value is the array [3]string{"go", "python", "ruby"}, the output will be the string "ruby".




#### join

Concatenates the given slice to create a single string. The given argument (separator) will be placed between elements in the resulting string.

```
{{ value | join " " }}
```

If value is the slice []string{"go", "python", "ruby"}, the output will be the string "go python ruby"




#### slice

Returns a slice of the given value. The first argument is the start position, and the second argument is the end position.

* supported value types : string, slice
* supported argument types : int

This function also supports unicode strings.

```
{{ value | slice 0 2 }}
```

**Examples**

1. If input is {{ "The go programming language" | slice 0 6 }}, the output will be "The go".
1. If input is {{ "안녕하세요" | slice 0 2 }}, the output will be "안녕". (unicode)
1. If input is {{ []string{"go", "python", "ruby"} | slice 0 2 }}, the output will be []string{"go", "python"}.



## Goal
The first goal is implementing all built-in template filters of Django & Jinja2.
Expand Down
57 changes: 57 additions & 0 deletions gtf.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,63 @@ var GtfFuncMap = template.FuncMap{

return fmt.Sprintf("%d%s", x, suffixes[x%10])
},
"first": func(value interface{}) interface{} {
defer recovery()

v := reflect.ValueOf(value)

switch v.Kind() {
case reflect.String:
return string([]rune(v.String())[0])
case reflect.Slice, reflect.Array:
return v.Index(0).Interface()
}

return ""
},
"last": func(value interface{}) interface{} {
defer recovery()

v := reflect.ValueOf(value)

switch v.Kind() {
case reflect.String:
str := []rune(v.String())
return string(str[len(str)-1])
case reflect.Slice, reflect.Array:
return v.Index(v.Len() - 1).Interface()
}

return ""
},
"join": func(arg string, value []string) string {
defer recovery()

return strings.Join(value, arg)
},
"slice": func(start int, end int, value interface{}) interface{} {
defer recovery()

v := reflect.ValueOf(value)

if start < 0 {
start = 0
}

switch v.Kind() {
case reflect.String:
str := []rune(v.String())

if end > len(str) {
end = len(str)
}

return string(str[start:end])
case reflect.Slice:
return v.Slice(start, end).Interface()
}
return ""
},
}

// gtf.New is a wrapper function of template.New(http://golang.org/pkg/text/template/#New).
Expand Down
51 changes: 48 additions & 3 deletions gtf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,13 +281,58 @@ func TestGtfFuncMap(t *testing.T) {

ParseTest(&buffer, "{{ 14 | ordinal }}", "")
AssertEqual(t, &buffer, "14th")

ParseTest(&buffer, "{{ -1 | ordinal }}", "")
AssertEqual(t, &buffer, "")

ParseTest(&buffer, "{{ . | ordinal }}", uint(14))
AssertEqual(t, &buffer, "14th")

ParseTest(&buffer, "{{ . | ordinal }}", false)
AssertEqual(t, &buffer, "")

ParseTest(&buffer, "{{ . | first }}", "The go programming language")
AssertEqual(t, &buffer, "T")

ParseTest(&buffer, "{{ . | first }}", "안녕하세요")
AssertEqual(t, &buffer, "안")

ParseTest(&buffer, "{{ . | first }}", []string{"go", "python", "ruby"})
AssertEqual(t, &buffer, "go")

ParseTest(&buffer, "{{ . | first }}", [3]string{"go", "python", "ruby"})
AssertEqual(t, &buffer, "go")

ParseTest(&buffer, "{{ . | first }}", false)
AssertEqual(t, &buffer, "")

ParseTest(&buffer, "{{ . | last }}", "The go programming language")
AssertEqual(t, &buffer, "e")

ParseTest(&buffer, "{{ . | last }}", "안녕하세요")
AssertEqual(t, &buffer, "요")

ParseTest(&buffer, "{{ . | last }}", []string{"go", "python", "ruby"})
AssertEqual(t, &buffer, "ruby")

ParseTest(&buffer, "{{ . | last }}", false)
AssertEqual(t, &buffer, "")

ParseTest(&buffer, "{{ . | join \" \" }}", []string{"go", "python", "ruby"})
AssertEqual(t, &buffer, "go python ruby")

ParseTest(&buffer, "{{ . | slice 0 2 }}", []string{"go", "python", "ruby"})
AssertEqual(t, &buffer, "[go python]")

ParseTest(&buffer, "{{ . | slice 0 6 }}", "The go programming language")
AssertEqual(t, &buffer, "The go")

ParseTest(&buffer, "{{ . | slice 0 2 }}", "안녕하세요")
AssertEqual(t, &buffer, "안녕")

ParseTest(&buffer, "{{ . | slice -10 10 }}", "안녕하세요")
AssertEqual(t, &buffer, "안녕하세요")

ParseTest(&buffer, "{{ . | slice 0 2 }}", false)
AssertEqual(t, &buffer, "")
}

0 comments on commit 62c4614

Please sign in to comment.