github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/gtf/README.md (about)

     1  # gtf - a useful set of Golang Template Functions
     2  
     3  [![Build Status](https://travis-ci.org/bingoohuang/gg/pkg/gtf.svg?branch=master)](https://travis-ci.org/bingoohuang/gg/pkg/gtf)
     4  [![Coverage Status](https://coveralls.io/repos/bingoohuang/gg/pkg/gtf/badge.svg?branch=master&service=github)](https://coveralls.io/github/bingoohuang/gg/pkg/gtf?branch=master)
     5  [![GoDoc](https://godoc.org/github.com/bingoohuang/gg/pkg/gtf?status.svg)](https://godoc.org/github.com/bingoohuang/gg/pkg/gtf)
     6  
     7  gtf is a useful set of Golang Template Functions. The goal of this project is implementing all built-in template filters
     8  of Django & Jinja2.
     9  
    10  ## Basic usages
    11  
    12  ### Method 1 : Uses gtf.New
    13  
    14  gtf.New is a wrapper function of [template.New](https://golang.org/pkg/html/template/#New). It automatically adds the
    15  gtf functions to the template's function map and
    16  returns [template.Template](http://golang.org/pkg/html/template/#Template).
    17  
    18  ```Go
    19  package main
    20  
    21  import (
    22  	"net/http"
    23  	"github.com/bingoohuang/gg/pkg/gtf"
    24  )
    25  
    26  func main() {
    27  	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    28  		filesize := 554832114
    29  		tpl, _ := gtf.New("test").Parse("{{ . | filesizeformat }}")
    30  		tpl.Execute(w, filesize)
    31  	})
    32  	http.ListenAndServe(":8080", nil)
    33  }
    34  ```
    35  
    36  ### Method 2 : Adds gtf functions to the existing template.
    37  
    38  You can also add the gtf functions to the existing template(html/template package). Just call ".Funcs(gtf.GtfFuncMap)".
    39  
    40  ```Go
    41  package main
    42  
    43  import (
    44  	"net/http"
    45  	"html/template"
    46  
    47  	"github.com/bingoohuang/gg/pkg/gtf"
    48  )
    49  
    50  func main() {
    51  	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    52  		filesize := 554832114
    53  		tpl, _ := template.New("test").Funcs(gtf.HtmlFuncMap).Parse("{{ . | filesizeformat }}")
    54  		tpl.Execute(w, filesize)
    55  	})
    56  	http.ListenAndServe(":8080", nil)
    57  }
    58  ```
    59  
    60  When you use the "text/template" package, call ".Funcs(gtf.GtfTextFuncMap)".
    61  
    62  ```Go
    63  package main
    64  
    65  import (
    66  	"os"
    67  	"text/template"
    68  
    69  	"github.com/bingoohuang/gg/pkg/gtf"
    70  )
    71  
    72  func main() {
    73  	filesize := 554832114
    74  	tpl, _ := template.New("test").Funcs(gtf.TextFuncMap).Parse("{{ . | filesizeformat }}")
    75  	tpl.Execute(os.Stdout, filesize)
    76  }
    77  ```
    78  
    79  ## Integration
    80  
    81  You can use gtf with any web frameworks (revel, beego, martini, gin, etc) which use the Golang's
    82  built-in [html/template package](http://golang.org/pkg/html/template/).
    83  
    84  ### Injection
    85  
    86  You can inject gtf functions into your webframework's original FuncMap by calling "gtf.Inject" / "gtf.ForceInject" / "
    87  gtf.InjectWithPrefix".
    88  
    89  #### gtf.Inject
    90  
    91  gtf.Inject injects gtf functions into the passed FuncMap. The second argument force determines whether it overwrite the
    92  original function which have same name as a gtf function.
    93  
    94  ```Go
    95  Inject(originalFuncMap, true, "gtf_") // prefix : gtf_
    96  ```
    97  
    98  ### [Revel](http://revel.github.io/) integration
    99  
   100  Calling "gtf.Inject(revel.TemplateFuncs)" injects gtf functions into revel.TemplateFuncs. Just add this one line in
   101  init() of init.go, and use gtf functions in your templates! :)
   102  
   103  ```Go
   104  // init.go
   105  
   106  package app
   107  
   108  import "github.com/revel/revel"
   109  import "github.com/bingoohuang/gg/pkg/gtf"
   110  
   111  func init() {
   112  	gtf.Inject(revel.TemplateFuncs)
   113  }
   114  ```
   115  
   116  ### [Beego](http://beego.me/) integration
   117  
   118  Add these three lines before "beego.Run()" in your main() function. This code snippet will inject gtf functions into
   119  beego's FuncMap.
   120  
   121  ```Go
   122  for k, v := range gtf.GtfFuncMap {
   123  	beego.AddFuncMap(k, v)
   124  }
   125  ```
   126  
   127  **Full example:**
   128  
   129  ```Go
   130  package main
   131  
   132  import (
   133  	"github.com/astaxie/beego"
   134  	"github.com/beego/i18n"
   135  
   136  	"github.com/beego/samples/WebIM/controllers"
   137  
   138  	"github.com/bingoohuang/gg/pkg/gtf"
   139  )
   140  
   141  const (
   142  	APP_VER = "0.1.1.0227"
   143  )
   144  
   145  func main() {
   146  	beego.Info(beego.AppName, APP_VER)
   147  
   148  	// Register routers.
   149  	beego.Router("/", &controllers.AppController{})
   150  	// Indicate AppController.Join method to handle POST requests.
   151  	beego.Router("/join", &controllers.AppController{}, "post:Join")
   152  
   153  	// Long polling.
   154  	beego.Router("/lp", &controllers.LongPollingController{}, "get:Join")
   155  	beego.Router("/lp/post", &controllers.LongPollingController{})
   156  	beego.Router("/lp/fetch", &controllers.LongPollingController{}, "get:Fetch")
   157  
   158  	// WebSocket.
   159  	beego.Router("/ws", &controllers.WebSocketController{})
   160  	beego.Router("/ws/join", &controllers.WebSocketController{}, "get:Join")
   161  
   162  	// Register template functions.
   163  	beego.AddFuncMap("i18n", i18n.Tr)
   164  
   165  	// Register gtf functions.
   166  	for k, v := range gtf.GtfFuncMap {
   167  		beego.AddFuncMap(k, v)
   168  	}
   169  
   170  	beego.Run()
   171  }
   172  ```
   173  
   174  ### Other web frameworks (TODO)
   175  
   176  I will add the detailed integration guides for other web frameworks soon!
   177  
   178  ## Safety
   179  
   180  All gtf functions have their own recovery logics. The basic behavior of the recovery logic is silently swallowing all
   181  unexpected panics. All gtf functions would not make any panics in runtime. (**Production Ready!**)
   182  
   183  If a panic occurs inside a gtf function, the function will silently swallow the panic and return "" (empty string). If
   184  you meet any unexpected empty output, [please make an issue](https://github.com/bingoohuang/gg/pkg/gtf/issues/new)! :)
   185  
   186  ## Reference
   187  
   188  ### Index
   189  
   190  * [contains](#contains)
   191  * [replace](#replace)
   192  * [findreplace](#findreplace)
   193  * [default](#default)
   194  * [length](#length)
   195  * [lower](#lower)
   196  * [upper](#upper)
   197  * [truncatechars](#truncatechars)
   198  * [urlencode](#urlencode)
   199  * [wordcount](#wordcount)
   200  * [divisibleby](#divisibleby)
   201  * [lengthis](#lengthis)
   202  * [trim](#trim)
   203  * [capfirst](#capfirst)
   204  * [pluralize](#pluralize)
   205  * [yesno](#yesno)
   206  * [rjust](#rjust)
   207  * [ljust](#ljust)
   208  * [center](#center)
   209  * [filesizeformat](#filesizeformat)
   210  * [apnumber](#apnumber)
   211  * [intcomma](#intcomma)
   212  * [ordinal](#ordinal)
   213  * [first](#first)
   214  * [last](#last)
   215  * [join](#join)
   216  * [slice](#slice)
   217  * [random](#random)
   218  * [striptags](#striptags)
   219  
   220  #### contains
   221  
   222  Detect an elements is contained as a struct field, map property or slice item.
   223  
   224  * supported value types : struct/map/slice/array
   225  * supported argument types : string
   226  
   227  `{{if contains . "FieldA"}}FieldA:{{.FieldA}}{{end}}`
   228  
   229  #### replace
   230  
   231  Removes all values of arg from the given string.
   232  
   233  * supported value types : string
   234  * supported argument types : string
   235  
   236  `{{ value | replace " " }}`
   237  
   238  If value is "The Go Programming Language", the output will be "TheGoProgrammingLanguage".
   239  
   240  #### findreplace
   241  
   242  Replaces all instances of the first argument with the second.
   243  
   244  * supported value types : string
   245  * supported argument types : string
   246  
   247  `{{ value | findreplace " " "-" }}`
   248  
   249  If value is "The Go Programming Language", the output will be "The-Go-Programming-Language".
   250  
   251  #### default
   252  
   253  1. If the given string is ""(empty string), uses the given default argument.
   254  1. If the given array/slice/map is empty, uses the given default argument.
   255  1. If the given boolean value is false, uses the given default argument.
   256  
   257  * supported value types : string, array, slice, map, boolean
   258  * supported argument types : all
   259  
   260  ```
   261  {{ value | default "default value" }}
   262  ```
   263  
   264  If value is ""(the empty string), the output will be "default value".
   265  
   266  #### length
   267  
   268  Returns the length of the given string/array/slice/map.
   269  
   270  * supported value types : string, array, slice, map
   271  
   272  This function also supports unicode strings.
   273  
   274  ```
   275  {{ value | length }}
   276  ```
   277  
   278  If value is "The Go Programming Language", the output will be 27.
   279  
   280  #### lower
   281  
   282  Converts the given string into all lowercase.
   283  
   284  * supported value types : string
   285  
   286  ```
   287  {{ value | lower }}
   288  ```
   289  
   290  If value is "The Go Programming Language", the output will be "the go programming language".
   291  
   292  #### upper
   293  
   294  Converts the given string into all uppercase.
   295  
   296  * supported value types : string
   297  
   298  ```
   299  {{ value | upper }}
   300  ```
   301  
   302  If value is "The Go Programming Language", the output will be "THE GO PROGRAMMING LANGUAGE".
   303  
   304  #### truncatechars
   305  
   306  Truncates the given string if it is longer than the specified number of characters. Truncated strings will end with a
   307  translatable ellipsis sequence ("...")
   308  
   309  * supported value types : string
   310  
   311  **Argument:** Number of characters to truncate to
   312  
   313  This function also supports unicode strings.
   314  
   315  ```
   316  {{ value | truncatechars 12 }}
   317  ```
   318  
   319  **Examples**
   320  
   321  1. If input is {{ "The Go Programming Language" | truncatechars 12 }}, the output will be "The Go Pr...". (basic string)
   322  1. If input is {{ "안녕하세요. 반갑습니다." | truncatechars 12 }}, the output will be "안녕하세요. 반갑...". (unicode)
   323  1. If input is {{ "안녕하세요. The Go Programming Language" | truncatechars 30 }}, the output will be "안녕하세요. The Go
   324     Programming L...". (unicode)
   325  1. If input is {{ "The" | truncatechars 30 }}, the output will be "The". (If the length of the given string is shorter
   326     than the argument, the output will be the original string.)
   327  1. If input is {{ "The Go Programming Language" | truncatechars 3 }}, the output will be "The". (If the argument is less
   328     than or equal to 3, the output will not contain "...".)
   329  1. If input is {{ "The Go" | truncatechars -1 }}, the output will be "The Go". (If the argument is less than 0, the
   330     argument will be ignored.)
   331  
   332  #### urlencode
   333  
   334  Escapes the given string for use in a URL.
   335  
   336  * supported value types : string
   337  
   338  ```
   339  {{ value | urlencode }}
   340  ```
   341  
   342  If value is "http://www.example.org/foo?a=b&c=d", the output will be "
   343  http%3A%2F%2Fwww.example.org%2Ffoo%3Fa%3Db%26c%3Dd".
   344  
   345  #### wordcount
   346  
   347  Returns the number of words.
   348  
   349  * supported value types : string
   350  
   351  ```
   352  {{ value | wordcount }}
   353  ```
   354  
   355  If value is "The Go Programming Language", the output will be 4.
   356  
   357  #### divisibleby
   358  
   359  Returns true if the value is divisible by the argument.
   360  
   361  * supported value types : int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64
   362  * supported argument types : int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64
   363  
   364  ```
   365  {{ value | divisibleby 3 }}
   366  ```
   367  
   368  **Examples**
   369  
   370  1. If input is {{ 21 | divisibleby 3 }}, the output will be true.
   371  1. If input is {{ 21 | divisibleby 4 }}, the output will be false.
   372  1. If input is {{ 3.0 | divisibleby 1.5 }}, the output will be true.
   373  
   374  #### lengthis
   375  
   376  Returns true if the value's length is the argument, or false otherwise.
   377  
   378  * supported value types : string, array, slice, map
   379  * supported argument types : int
   380  
   381  ```
   382  {{ value | lengthis 3 }}
   383  ```
   384  
   385  This function also supports unicode strings.
   386  
   387  **Examples**
   388  
   389  1. If input is {{ "Go" | lengthis 2 }}, the output will be true.
   390  1. If input is {{ "안녕하세요. Go!" | lengthis 10 }}, the output will be true.
   391  
   392  #### trim
   393  
   394  Strips leading and trailing whitespace.
   395  
   396  * supported value types : string
   397  
   398  ```
   399  {{ value | trim }}
   400  ```
   401  
   402  #### capfirst
   403  
   404  Capitalizes the first character of the given string.
   405  
   406  * supported value types : string
   407  
   408  ```
   409  {{ value | capfirst }}
   410  ```
   411  
   412  If value is "the go programming language", the output will be "The go programming language".
   413  
   414  #### pluralize
   415  
   416  Returns a plural suffix if the value is not 1. You can specify both a singular and plural suffix, separated by a comma.
   417  
   418  **Argument:** singular and plural suffix.
   419  
   420  1. "s" --> specify a singular suffix.
   421  2. "y,ies" --> specify both a singular and plural suffix.
   422  
   423  * supported value types : int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64
   424  * supported argument types : string
   425  
   426  ```
   427  {{ value | pluralize "s" }}
   428  {{ value | pluralize "y,ies" }}
   429  ```
   430  
   431  **Examples**
   432  
   433  1. You have 0 message{{ 0 | pluralize "s" }} --> You have 0 messages
   434  2. You have 1 message{{ 1 | pluralize "s" }} --> You have 1 message
   435  3. 0 cand{{ 0 | pluralize "y,ies" }} --> 0 candies
   436  4. 1 cand{{ 1 | pluralize "y,ies" }} --> 1 candy
   437  5. 2 cand{{ 2 | pluralize "y,ies" }} --> 2 candies
   438  
   439  #### yesno
   440  
   441  Returns argument strings according to the given boolean value.
   442  
   443  * supported value types : boolean
   444  * supported argument types : string
   445  
   446  **Argument:** any value for true and false
   447  
   448  ```
   449  {{ value | yesno "yes!" "no!" }}
   450  ```
   451  
   452  #### rjust
   453  
   454  Right-aligns the given string in a field of a given width. This function also supports unicode strings.
   455  
   456  * supported value types : string
   457  
   458  ```
   459  {{ value | rjust 10 }}
   460  ```
   461  
   462  **Examples**
   463  
   464  1. If input is {{ "Go" | rjust 10 }}, the output will be "        Go".
   465  1. If input is {{ "안녕하세요" | rjust 10 }}, the output will be "     안녕하세요".
   466  
   467  #### ljust
   468  
   469  Left-aligns the given string in a field of a given width. This function also supports unicode strings.
   470  
   471  * supported value types : string
   472  
   473  ```
   474  {{ value | ljust 10 }}
   475  ```
   476  
   477  **Examples**
   478  
   479  1. If input is {{ "Go" | ljust 10 }}, the output will be "Go        ".
   480  1. If input is {{ "안녕하세요" | ljust 10 }}, the output will be "안녕하세요     ".
   481  
   482  #### center
   483  
   484  Centers the given string in a field of a given width. This function also supports unicode strings.
   485  
   486  * supported value types : string
   487  
   488  ```
   489  {{ value | center 10 }}
   490  ```
   491  
   492  **Examples**
   493  
   494  1. If input is {{ "Go" | center 10 }}, the output will be "    Go    ".
   495  1. If input is {{ "안녕하세요" | center 10 }}, the output will be "  안녕하세요   ".
   496  
   497  #### filesizeformat
   498  
   499  Formats the value like a human readable file size.
   500  
   501  * supported value types : int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64
   502  
   503  ```
   504  {{ value | filesizeformat }}
   505  ```
   506  
   507  **Examples**
   508  
   509  1. {{ 234 | filesizeformat }} --> "234 bytes"
   510  1. {{ 12345 | filesizeformat }} --> "12.1 KB"
   511  1. {{ 12345.35335 | filesizeformat }} --> "12.1 KB"
   512  1. {{ 1048576 | filesizeformat } --> "1 MB"
   513  1. {{ 554832114 | filesizeformat }} --> "529.1 MB"
   514  1. {{ 14868735121 | filesizeformat }} --> "13.8 GB"
   515  1. {{ 14868735121365 | filesizeformat }} --> "13.5 TB"
   516  1. {{ 1486873512136523 | filesizeformat }} --> "1.3 PB"
   517  
   518  #### apnumber
   519  
   520  For numbers 1-9, returns the number spelled out. Otherwise, returns the number.
   521  
   522  * supported value types : int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64
   523  
   524  ```
   525  {{ value | apnumber }}
   526  ```
   527  
   528  **Examples**
   529  
   530  1. {{ 1 | apnumber }} --> one
   531  1. {{ 2 | apnumber }} --> two
   532  1. {{ 3 | apnumber }} --> three
   533  1. {{ 9 | apnumber }} --> nine
   534  1. {{ 10 | apnumber }} --> 10
   535  1. {{ 1000 | apnumber }} --> 1000
   536  
   537  #### intcomma
   538  
   539  Converts an integer to a string containing commas every three digits.
   540  
   541  * supported value types : int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64
   542  
   543  ```
   544  {{ value | intcomma }}
   545  ```
   546  
   547  **Examples**
   548  
   549  1. {{ 1000 | intcomma }} --> 1,000
   550  1. {{ -1000 | intcomma }} --> -1,000
   551  1. {{ 1578652313 | intcomma }} --> 1,578,652,313
   552  
   553  #### ordinal
   554  
   555  Converts an integer to its ordinal as a string.
   556  
   557  * supported value types : int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64
   558  
   559  ```
   560  {{ value | ordinal }}
   561  ```
   562  
   563  **Examples**
   564  
   565  1. {{ 1 | ordinal }} --> 1st
   566  1. {{ 2 | ordinal }} --> 2nd
   567  1. {{ 3 | ordinal }} --> 3rd
   568  1. {{ 11 | ordinal }} --> 11th
   569  1. {{ 12 | ordinal }} --> 12th
   570  1. {{ 13 | ordinal }} --> 13th
   571  1. {{ 14 | ordinal }} --> 14th
   572  
   573  #### first
   574  
   575  Returns the first item in the given value.
   576  
   577  * supported value types : string, slice, array
   578  
   579  This function also supports unicode strings.
   580  
   581  ```
   582  {{ value | first }}
   583  ```
   584  
   585  **Examples**
   586  
   587  1. If value is the string "The go programming language", the output will be the string "T".
   588  1. If value is the string "안녕하세요", the output will be the string "안". (unicode)
   589  1. If value is the slice []string{"go", "python", "ruby"}, the output will be the string "go".
   590  1. If value is the array [3]string{"go", "python", "ruby"}, the output will be the string "go".
   591  
   592  #### last
   593  
   594  Returns the last item in the given value.
   595  
   596  * supported value types : string, slice, array
   597  
   598  This function also supports unicode strings.
   599  
   600  ```
   601  {{ value | last }}
   602  ```
   603  
   604  **Examples**
   605  
   606  1. If value is the string "The go programming language", the output will be the string "e".
   607  1. If value is the string "안녕하세요", the output will be the string "요". (unicode)
   608  1. If value is the slice []string{"go", "python", "ruby"}, the output will be the string "ruby".
   609  1. If value is the array [3]string{"go", "python", "ruby"}, the output will be the string "ruby".
   610  
   611  #### join
   612  
   613  Concatenates the given slice to create a single string. The given argument (separator) will be placed between elements
   614  in the resulting string.
   615  
   616  ```
   617  {{ value | join " " }}
   618  ```
   619  
   620  If value is the slice []string{"go", "python", "ruby"}, the output will be the string "go python ruby"
   621  
   622  #### slice
   623  
   624  Returns a slice of the given value. The first argument is the start position, and the second argument is the end
   625  position.
   626  
   627  * supported value types : string, slice
   628  * supported argument types : int
   629  
   630  This function also supports unicode strings.
   631  
   632  ```
   633  {{ value | slice 0 2 }}
   634  ```
   635  
   636  **Examples**
   637  
   638  1. If input is {{ "The go programming language" | slice 0 6 }}, the output will be "The go".
   639  1. If input is {{ "안녕하세요" | slice 0 2 }}, the output will be "안녕". (unicode)
   640  1. If input is {{ []string{"go", "python", "ruby"} | slice 0 2 }}, the output will be []string{"go", "python"}.
   641  
   642  #### random
   643  
   644  Returns a random item from the given value.
   645  
   646  * supported value types : string, slice, array
   647  
   648  This function also supports unicode strings.
   649  
   650  ```
   651  {{ value | random }}
   652  ```
   653  
   654  **Examples**
   655  
   656  1. If input is {{ "The go programming language" | random }}, the output could be "T".
   657  1. If input is {{ "안녕하세요" | random }}, the output could be "안". (unicode)
   658  1. If input is {{ []string{"go", "python", "ruby"} | random }}, the output could be "go".
   659  1. If input is {{ [3]string{"go", "python", "ruby"} | random }}, the output could be "go".
   660  
   661  #### randomintrange
   662  
   663  Returns a random integer value between the first and second argument
   664  
   665  * supported value types : int
   666  
   667  ```
   668  {{ value | randomintrange 0 5}}
   669  ```
   670  
   671  **Examples**
   672  
   673  1. If input is {{ randomintrange 0 5 }}, the output could be "4".
   674  
   675  #### striptags
   676  
   677  Makes all possible efforts to strip all [X]HTML tags from given value.
   678  
   679  * supported value types : string
   680  
   681  This function also supports unicode strings.
   682  
   683  ```
   684  {{ value | striptags }}
   685  ```
   686  
   687  **Examples**
   688  
   689  1. If input is {{ "<strong>text</strong>" | striptags }}, the output will be "text".
   690  1. If input is {{ "<strong><em>안녕하세요</em></strong>" |
   691     striptags }}, the output will be "안녕하세요". (unicode)
   692  1. If input is {{ "<a href="/link">text
   693     <strong>안녕하세요</strong></a>" | striptags }}, the output will be "
   694     text 안녕하세요".
   695  
   696  ## Goal
   697  
   698  The first goal is implementing all built-in template filters of Django & Jinja2.
   699  
   700  * [Django | Built-in filter reference](https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#built-in-filter-reference)
   701  * [Jinja2 | List of Builtin Filters](http://jinja.pocoo.org/docs/dev/templates/#builtin-filters)
   702  
   703  The final goal is building a ultimate set which contains hundreds of useful template functions.
   704  
   705  ## Contributing
   706  
   707  I love pull requests :) You can add any useful template functions by submitting a pull request!
   708  
   709  ## Giant shoulders
   710  
   711  1. [Sprig: Template functions for Go templates](https://github.com/Masterminds/sprig)