{"id":13413846,"url":"https://github.com/goradd/got","last_synced_at":"2026-02-02T06:29:16.527Z","repository":{"id":34944173,"uuid":"163402145","full_name":"goradd/got","owner":"goradd","description":"GoT is a template engine that turns templates into Go code to compile into your app.","archived":false,"fork":false,"pushed_at":"2023-11-12T16:05:49.000Z","size":273,"stargazers_count":29,"open_issues_count":1,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-07-31T20:52:54.986Z","etag":null,"topics":["go","golang","template-engine","templates"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/goradd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-12-28T11:19:31.000Z","updated_at":"2024-07-14T20:30:29.000Z","dependencies_parsed_at":"2023-11-12T17:24:18.589Z","dependency_job_id":"eeee250c-06f9-4111-ad85-8716cf0836df","html_url":"https://github.com/goradd/got","commit_stats":null,"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goradd%2Fgot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goradd%2Fgot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goradd%2Fgot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goradd%2Fgot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/goradd","download_url":"https://codeload.github.com/goradd/got/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243641954,"owners_count":20323940,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","template-engine","templates"],"created_at":"2024-07-30T20:01:51.055Z","updated_at":"2026-02-02T06:29:16.507Z","avatar_url":"https://github.com/goradd.png","language":"Go","readme":"[![Go Reference](https://pkg.go.dev/badge/github.com/goradd/got.svg)](https://pkg.go.dev/github.com/goradd/got)\n![Build Status](https://img.shields.io/github/actions/workflow/status/goradd/got/go.yml?branch=main)\n[![codecov](https://codecov.io/gh/goradd/got/branch/main/graph/badge.svg?token=FHU0NR2N1V)](https://codecov.io/gh/goradd/got)\n[![Go Report Card](https://goreportcard.com/badge/github.com/goradd/got)](https://goreportcard.com/report/github.com/goradd/got)\n[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go#template-engines)\n# GoT\n\nGoT (short for Go Templates) is a flexible template engine that generates Go code.\n\nThis approach creates extremely fast templates. It also gives you much more freedom than Go's template\nengine, since at any time you can just switch to Go code to do what you want.\n\nGoT has:\n- Mustache-like syntax similar to Go's built-in template engine\n- The ability to define new tags, so you can create your own template syntax\n- Include files, so you can create a library of tags and templates \n\nThe GoT syntax is easy to learn. Get started in minutes.\n\n- [Features](#features)\n- [Installation](#installation)\n- [Command Line Usage](#command-line-usage)\n- [Basic Syntax](#basic-syntax)\n- [Template Syntax](#template-syntax)\n- [License](#license)\n- [Acknowledgements](#acknowledgements)\n\n## Features\n\n- **High performance**. Since the resulting template is go code, your template will be compiled to fast\nmachine code.\n- **Easy to use**. The templates themselves are embedded into your go code. The template language is pretty \nsimple and you can do a lot with only a few tags. You can switch into and out of go code at will. Tags are \nMustache-like, so similar to Go's template engine.\n- **Flexible**. The template language makes very few assumptions about the go environment it is in. Most other\ntemplate engines require you to call the template with a specific function signature. **GoT** gives you the\nfreedom to call your templates how you want.\n- **Translation Support**. You can specify that you want to send your strings to a translator before \noutput.\n- **Error Support**. You can call into go code that returns errors, and have the template stop at that\npoint and return an error to your wrapper function. The template will output its text up to that point,\nallowing you to easily see where in the template the error occurred.\n- **Include Files**. Templates can include other templates. You can specify\na list of search directories for the include files, allowing you to put include files in a variety of\nlocations, and have include files in one directory that override another directory.\n- **Custom Tags**. You can define named fragments that you can include at will, \nand you can define these fragments in include files. To use these fragments, you just\nuse the name of the fragment as the tag. This essentially gives you the ability to create your own template\nlanguage. When you use a custom tag, you can also include parameters that will \nreplace placeholders in your fragment, giving you even more power to your custom tags. \n- **Error Reporting**. Errors in your template files are identified by line and character\nnumber. No need to guess where the error is.\n\nUsing other go libraries, you can have your templates compile when they are changed, \nuse buffer pools to increase performance, and more. Since the\ntemplates become go code, you can do what you want.\n\n\n## Installation\n\n```shell\ngo install github.com/goradd/got/got@latest\n```\n\nWe also recommend installing `goimports` \nand passing GoT the -i flag on the command line. That will format your Go code and \nfix up the import lines of any generated go files.\n```shell\ngo install golang.org/x/tools/cmd/goimports@latest\n```\n\n## Command Line Usage\n\n```shell\ngot [options] [files]\n\noptions:\n\t- o: The output directory. If not specified, files will be output at the same \n\t     location as the corresponding template. If using the -r option, files will\n\t     be output in subdirectories matching the directory names of the input files.\n\t- t  fileType: If set, will process all files in the current directory with this suffix. \n\t     If not set, you must specify the files at the end of the command line.\n\t- i: Run `goimports` on the output files, rather than `go fmt`\n\t- I  directories and/or files:  A list of directories and/or files. \n\t     If a directory, it is used as the search path for include files. \n\t     If a file, it is automatically added to the front of every file that is processed.  \n\t     Directories are searched in the order specified and first matching file will be used. \n\t     It will always look in the current directory last unless the current directory \n\t     is specified in the list in another location. Relative paths must start with a dot (.) \n\t     or double-dot (..).  Directories can start with a module name, and based on the \n\t     current directory, the correct go.mod file will be searched to know where to look \n\t     for include files.\n\t- d  directory: When using the -t option, will specify a directory to search.\n\t- v  verbose: Prints information about files being processed\n\t- r  recursive: Recursively processes directories. Used with the -t option and possibly -d.\n\t- f  force: Output files are normally not over-written if they are newer than the input file.\n\t     This option will force all input files to over-write the output files.\n```\nIf a path described above starts with a module path, the actual disk location \nwill be substituted.\n\nexamples:\n```shell\n\tgot -t got -i -o ../templates\n\tgot -I .;../tmpl;example.com/projectTemplates file1.tmpl file2.tmpl\n```\n\n## Basic Syntax\nTemplate tags start with `{{` and end with `}}`.\n\nA template starts in go mode. To send simple text or html to output, surround the text with `{{` and `}}` tags\nwith a space or newline separating the tags from the surrounding text. Inside the brackets you will be in \ntext mode.\n\nIn the resulting Go code, text will get written to output by calling:\n\n ```_, err = io.WriteString(_w, \u003ctext\u003e)``` \n\nGoT assumes that the `_w` variable\nis available and satisfies the io.Writer interface\nand optionally the io.StringWriter interface.\nUsually you would do this by declaring a function at the top of your template that looks like this:\n\n``` func f(_w io.Writer) (err error) ```\n\nAfter compiling the template output together with your program, you call\nthis function to get the template output. \n\nAt a minimum, you will need to import the \"io\" package into the file with your template function.\nDepending on what tags you use, you might need to add \nadditional items to your import list. Those are mentioned below with each tag.\n\n### Example\nHere is how you might create a very basic template. For purposes of this example, we will call the file\n`example.got` and put it in the `template` package, but you can name the file and package whatever you want.\n```\npackage template\n\nimport \"io\"\n\nfunc OutTemplate(_w io.Writer) (err error) {\n\tvar world string = \"World\"\n{{\n\u003cp\u003e\n    Hello {{world}}!\n\u003c/p\u003e\n}}\n  return // make sure the error gets returned\n}\n```\n\nTo compile this template, call GoT:\n```shell\ngot example.got\n```\n\nThis will create an `example.go` file, which you include in your program. You then can call the function\nyou declared:\n```go\npackage main\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"mypath/template\"\n)\n\nfunc main() {\n\t_ = template.OutTemplate(os.Stdout)\n}\n```\n\nThis simple example shows a mix of go code and template syntax in the same file. Using GoT's include files,\nyou can separate your go code from template code.\n\n## Template Syntax\n\nThe following describes how the various open tags work. Most tags end with a ` }}`, unless otherwise indicated.\nMany tags have a short and a long form. Using the long form does not impact performance, its just there\nto help your templates have some human readable context to them.\n\n### Static Text\n    {{\u003cspace or newline\u003e   Begin to output text as written.\n    {{! or {{esc           Html escape the text. Html reserved characters, like \u003c or \u003e are \n                           turned into html entities first. This happens when the template is \n                           compiled, so that when the template runs, the string will already \n                           be escaped. \n    {{h or {{html          Html escape and html format double-newlines into \u003cp\u003e tags.\n    {{t or {{translate     Send the text to a translator\n\n\nThe `{{!` tag requires you to import the standard html package. `{{h` requires both the html and strings packages.\n\n`{{t` will wrap the static text with a call to t.Translate(). Its up to you to define this object and make it available to the template. The\ntranslation will happen during runtime of your program. We hope that a future implementation of GoT could\nhave an option to send these strings to an i18n file to make it easy to send these to a translation service.\n\n#### Example\nIn this example file, note that we start in Go mode, copying the text verbatim to the template file.\n```\npackage test\n\nimport (\n\t\"io\"\n\t\"fmt\"\n)\n\ntype Translater interface {\n\tTranslate(string) string\n}\n\nfunc staticTest(_w io.Writer) {\n{{\n\u003cp\u003e\n{{! Escaped html \u003c }}\n\u003c/p\u003e\n}}\n\n{{h\n\tThis is text that is both escaped.\n\t \n\tAnd has html paragraphs inserted.\n}}\n\n}\n\nfunc translateTest(t Translater, _w io.Writer) {\n\n{{t Translate me to some language }}\n\n{{!t Translate \u0026 escape me \u003e }}\n\n}\n```\n\n### Switching Between Go Mode and Template Mode\nFrom within any static text context described above you can switch into go context by using:\n\n    {{g or {{go     Change to straight go code.\n    \nGo code is copied verbatim to the final template. Use it to set up loops, call special processing functions, etc.\nEnd go mode using the `}}` closing tag. You can also include any other GoT tag inside of Go mode,\nmeaning you can nest Go mode and all the other template tags.\n\n#### Example\n```\n// We start a template in Go mode. The next tag switches to text mode, and then nests\n// switching back to go mode.\n{{ Here \n{{go \nio.WriteString(_w, \"is\") \n}} some code wrapping text escaping to go. }}\n```\n\n### Dynamic Text\nThe following tags are designed to surround go code that returns a go value. The value will be \nconverted to a string and sent to the buf. The go code could be a static value, or a function\nthat returns a value.\n\n    Tag                       Description                     Example\n    \n    {{=, {{s, or  {{string    A go string                     {{= fmt.Sprintf(\"%9.2f\", fVar) }}\n    {{i or {{int              An int                          {{ The value is: {{i iVar }} }}\n    {{u or {{uint             A uint                          {{ The value is: {{u uVar }} }}\n    {{f or {{float            A floating point number         {{ The value is: {{f fVar }} }}\n    {{b or {{bool             A boolean (\"true\" or \"false\")   {{ The value is: {{b bVar }} }}\n    {{w or {{bytes            A byte slice                    {{ The value is: {{w byteSliceVar }} }}\n    {{v or {{stringer or      Any value that implements       {{ The value is: {{objVar}} }}\n       {{goIdentifier}}       the Stringer interface.\n\nThe last tag can be slower than the other tags since they use fmt.Sprint() internally, \nso if this is a heavily used template, avoid it. Usually you will not notice a speed difference though,\nand the third option can be very convenient. This third option is simply any go variable surrounded by mustaches \nwith no spaces.\n\nThe i, u, and f tags use the strconv package, so be sure to include that in your template.\n\n#### Escaping Dynamic Text\n\nSome value types potentially could produce html reserved characters. The following tags will html escape\nthe output.\n\n    {{!=, {{!s or {{!string    HTML escape a go string\n    {{!w or {{!bytes           HTML escape a byte slice\n    {{!v or {{!stringer        HTML escape a Stringer\n    {{!h                       Escape a go string and html format breaks and newlines\n\nThese tags require you to import the \"html\" package. The `{{!h` tag also requires the \"strings\" package.\n\n#### Capturing Errors\n\nThese tags will receive two results, the first a value to send to output, and the second an error\ntype. If the error is not nil, processing will stop and the error will be returned by the template function. Therefore, these\ntags expect to be included in a function that returns an error. Any template text\nprocessed so far will still be sent to the output buffer.\n\n    {{=e, {{se, {{string,err      Output a go string, capturing an error\n    {{!=e, {{!se, {{!string,err   HTML escape a go string and capture an error\n    {{ie or {{int,err             Output a go int and capture an error\n    {{ue or {{uint,err            Output a go uint and capture an error\n    {{fe or {{float,err           Output a go float64 and capture an error\n    {{be or {{bool,err            Output a bool (\"true\" or \"false\") and capture an error\n    {{we, {{bytes,err             Output a byte slice and capture an error\n    {{!we or {{!bytes,err         HTML escape a byte slice and capture an error\n    {{ve, {{stringer,err          Output a Stringer and capture an error\n    {{!ve or {{!stringer,err      HTML escape a Stringer and capture an error\n    {{e, or {{err                 Execute go code that returns an error, and stop if the error is not nil\n\n##### Example\n```go\nfunc Tester(s string) (out string, err error) {\n\tif s == \"bad\" {\n\t\terr = errors.New(\"This is bad.\")\n\t}\n\treturn s\n}\n\nfunc OutTemplate(toPrint string, buf bytes.Buffer) error {\n{{=e Tester(toPrint) }}\n}\n```\n\n### Generating Go Code\n\nThese tags are useful if your templates will be generating Go code.\n\n    {{L      The value as a Go literal (uses %#v from fmt package)\n    {{T      The Go type of the value without package name (uses %T from the fmt package)\n    {{PT     The Go type of the value WITH the package name (uses %T from the fmt package)\n\nThe {{L tag will quote strings, but not quote numbers.\n\nThe {{PT tag will produce the Go type with a package name if given. Built in types will not\nhave a package name, but standard library types will. For example, a time.Time type will \nresult in the string \"time.Time\". The {{T tag will strip off the package name if there is one\nin the value's type.\n\n### Include Files\n#### Include a GoT source file\n\n    {{: \"fileName\" }} or \n    {{include \"fileName\" }}   Inserts the given file name into the template.\n\n The included file will start in whatever mode the receiving template is in, as if the text was inserted\n at that spot, so if the include tags are  put inside of go code, the included file will start in go mode. \n The file will then be processed like any other GoT file. Include files can refer to other include files,\n and so are recursive.\n \n Include files are searched for in the current directory, and in the list of include directories provided\n on the command line by the -I option.\n\nExample: `{{: \"myTemplate.inc\" }}`\n\n#### Include a text file\n\n    {{:! \"fileName\" }} or             Inserts the given file name into the template\n    {{includeEscaped \"fileName\" }}    and html escapes it.\n    {{:h \"fileName\" }} or             Inserts the given file name into the template,\n    {{includeAsHtml \"fileName\" }}     html escapes it, and converts newlines into html breaks.\n\nUse `{{:!` to include a file that you surround with a `\u003cpre\u003e` tag to include a text file\nand have it appear in an html document looking the same. Use `{{:h` to include a file\nwithout the `\u003cpre\u003e` tags, but if the file uses extra spaces for indent, those spaces will\nnot indent in the html. These kinds of include files will not be searched for GoT commands.\n \n### Defined Fragments\n\nDefined fragments start a block of text that can be included later in a template. The included text will\nbe sent as is, and then processed in whatever mode the template processor is in, as if that text was simply\ninserted into the template at that spot. You can include the `{{` or `{{g` tags inside of the fragment to\nforce the processor into the text or go modes if needed. The fragment can be defined\nany time before it is included, including being defined in other include files. \n\nYou can add optional parameters to a fragment that will be substituted for placeholders when the fragment is used. \nYou can have up to 9 placeholders ($1 - $9). Parameters should be separated by commas, and can be surrounded by quotes or backticks \nif needed to pass a parameter that has a quote or comma in it.\nIf a parameter is not included when using a fragment, an empty value will be substituted for the parameter in the fragment.\n\n    {{\u003c fragName }} or {{define fragName }}   Start a block called \"fragName\".\n    {{\u003c fragName \u003ccount\u003e}} or                 Start a block called \"fragName\" that will \n       {{define fragName \u003ccount\u003e}}            have \u003ccount\u003e parameters.\n    {{\u003e fragName param1,param2,...}} or       Substitute this tag for the given defined fragment.\n      {{put fragName param1,param2,...}} or   \n      {{fragName param1,param2,...}}\n    {{\u003e? fragName param1,param2,...}} or      Substitute this tag for the given defined fragment, \n      {{put? fragName param1,param2,...}}     but if the fragment is not defined, leave blank.\n\n \nIf you attempt to use a fragment that was not previously defined, GoT will panic and stop compiling,\nunless you use {{\u003e? or {{put? to include the fragment.\n\nThe fragment name is NOT surrounded by quotes, and cannot contain any whitespace in the name. Blocks are ended with a\n`{{end fragName}}` tag. The end tag must be just like that, with no spaces after the fragName.\n\nThe following fragments are predefined:\n* `{{templatePath}}` is the full path of the template file being processed\n* `{{templateName}}` is the base name of the template file being processed, including any extensions\n* `{{templateRoot}}` is the base name of the template file being processed without any extensions\n* `{{templateParent}}` is the directory name of the template file being processed, without the preceeding path\n* `{{includePath}}` is the full path of the file that the includePath fragment appears in.\n* `{{includeName}}` is the base name of the file that the includeName fragment appears in.\n* `{{includeRoot}}` is the base name of the file that the includeRoot fragment appears in without any extensions.\n* `{{includeParent}}` is the directory name of the file that the includeParent fragment appears in without any extensions.\n* `{{outPath}}` is the full path of the output file being written\n* `{{outName}}` is the base name of the output file being written, including any extensions\n* `{{outRoot}}` is the base name of the output file being written without any extensions\n* `{{outParent}}` is the directory name of the output file being written, without the preceeding path\n* `{{importPath}}` produces the import path of the output file\n* `{{importParent}}` produces the parent of the import path of the output file\n\nThe template* fragments refer to the top level file, the one sent to the got command to process,\nwhile the include* fragments refer to the file being processed currently. For example, if the\n\"a.tmpl\" file included the \"b.tmpl\" file, then {{includeName}} in the b.tmpl file would\nproduce \"b.tmpl\", while {{templateName}} in the b.tmpl file would produce \"a.tmpl\".\n\nimportPath and importParent are used to generate import paths to files that are relative\nto the output file, since go does not support relative import paths.\n\n#### Example\n```\n\n{{\u003c hFrag }}\n\u003cp\u003e\nThis is my html body.\n\u003c/p\u003e\n{{end hFrag}}\n\n{{\u003c writeMe 2}}\n{{// The g tag here forces us to process the text as go code, \n     no matter where the fragment is included }}\n{{g \nif \"$2\" != \"\" {\n\tio.WriteString(_w, \"$1\")\n}\n}}\n{{end writeMe}}\n\n\nfunc OutTemplate(_w io.Writer) (err error) {\n{{\n\t\u003chtml\u003e\n\t\t\u003cbody\u003e\n\t\t\t{{\u003e hFrag }}\n\t\t\u003c/body\u003e\n\t\u003c/html\u003e\n}}\n\n{{writeMe \"Help Me!\", a}}\n{{writeMe \"Help Me!\", }}\n return\n}\n```\n\n### Comment Tags\n\n    {{# or {{//       Comment the template. This is removed from the compiled template.\n\nThese tags and anything enclosed in them is removed from the compiled template.\n\n### Go Block Tags\n    \n    {{if \u003cgo condition\u003e}}\u003ctext block\u003e{{if}}                      \n                           A convenience tag for surrounding text with a go \"if\" statement.\n    {{if \u003cgo condition\u003e}}\u003ctext block\u003e{{else}}\u003ctext block\u003e{{if}}  \n                           Go \"if\" and \"else\" statement.\n    {{if \u003cgo condition\u003e}}\u003ctext block\u003e{{elseif \u003cgo condition\u003e}}\u003ctext block\u003e{{if}}    \n                           Go \"if\" and \"else if\" statement.\n    {{for \u003cgo condition and optional range statement\u003e}}\u003ctext block\u003e{{for}}                                   \n                           A convenience tag for surrounding text with a go \"for\" statement.\n\nThese tags are substitutes for switching into GO mode and using a `for` or `if` statements. \n`\u003ctext block\u003e` will be in text mode to begin with, so that whatever you put there\nwill be output, but you can switch to go mode if needed.\n\n####Example\n\n```\n{{\n{{for num,item := range items }}\n\u003cp\u003eItem {{num}} is {{item}}\u003c/p\u003e\n{{for}}\n}}\n```\n### Join Tags\n\n    {{join \u003cslice\u003e, \u003cstring\u003e}}\u003ctext block\u003e{{join}}    Joins the items of a slice with a string.\n\nJoin will output the `\u003ctext block\u003e` for each item of `\u003cslice\u003e`. Within `\u003ctext block\u003e` the variable\n`_i` will be an integer representing the index of the slice item, and `_j` will be the\nitem itself. `\u003ctext block\u003e` starts in text mode, but you can put GoT commands in it. `\u003cstring\u003e` will be output\nbetween the output of each item, creating an effect similar to joining a slice of strings.\n\n\n####Example\n\n```\n{{g\n  items := []string{\"a\", \"b\", \"c\"}\n}}\n{{join items,\", \"}}\n{{ {{_i}} = {{_j}} }}\n{{join}}\n```\n\n\n### Strict Text Block Tag\n\nFrom within most of the GoT tags, you can insert another GoT tag. GoT will be looking for these\nas it processes text. If you would like to turn off GoT's processing to output text \nthat is not processed by GoT, you can use:\n\n    {{begin *endTag*}}   Starts a strict text block and turns off the GoT parser. \n    \nOne thing this is useful for is to use GoT to generate GoT code.\nEnd the block with a `{{end *endTag*}}` tag, where `*endTag*` is whatever you specified in the begin tag. \nThere can be no space between the endTag and the final brackets\nThe following example will output the entire second line of code with no changes, \nincluding all brackets:\n\n```\n{{begin mystrict}}\n{{! This is verbatim code }}\n{{\u003c all included}}\n{{end mystrict}}\n```\n\n## Bigger Example\n\nIn this example, we will combine multiple files. One, a traditional html template with a place to fill in\nsome body text. Another, a go function declaration that we will use when we want to draw the template.\nThe function will use a traditional web server io.Writer pattern, including the use of a context parameter.\nFinally, there is an example main.go illustrating how our template function would be called.\n\n### index.html\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003cmeta charset=\"utf-8\"\u003e\n    \u003c/head\u003e\n\n    \u003cbody\u003e\n{{# The tag below declares that we want to substitute a named \n    fragment that is declared elsewhere }}\n{{put body }}\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\n### template.got\n\n```\npackage main\n\nimport {\n\t\"context\"\n\t\"bytes\"\n}\n\n\nfunc writeTemplate(ctx context.Context, _w io.Writer) {\n\n{{# Define the body that will be inserted into the template }}\n{{\u003c body }}\n\u003cp\u003e\nThe caller is: {{=s ctx.Value(\"caller\") }}\n\u003c/p\u003e\n{{end body}}\n\n{{# include the html template. Since the template is html, \n    we need to enter static text mode first }}\n{{ \n{{include \"index.html\"}}\n}}\n\n}\n```\n\n### main.go\n\n```html\ntype myHandler struct {}\n\nfunc (h myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)  {\n\tctx :=  context.WithValue(r.Context(), \"caller\", r.Referer())\n\twriteTemplate(ctx, w)\t// call the GoT template\n}\n\n\nfunc main() {\n\tvar r myHandler\n\tvar err error\n\n\t*local = \"0.0.0.0:8000\"\n\n\terr = http.ListenAndServe(*local, r)\n\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n}\n```\n\nTo compile the template:\n\n```shell\ngot template.got\n```\n\nBuild your application and go to `http://localhost:8000` in your browser, to see your results\n\n## License\nGoT is licensed under the MIT License.\n\n## Acknowldgements\n\nGoT was influenced by:\n\n- [hero](https://github.com/shiyanhui/hero)\n- [fasttemplate](https://github.com/valyala/fasttemplate)\n- [Rob Pike's Lexing/Parsing Talk](https://www.youtube.com/watch?v=HxaD_trXwRE)\n\n## Syntax Changes\n\n###v0.10.0\nThis was a major rewrite with the following changes:\n- defined fragments end with {{end fragName}} tags, rather than {{end}} tags\n- {{else if ...}} is now {{elseif ...}}\n- {{join }} tag will join items with a string\n- The backup tag {{- has been removed\n- Reorganized the lexer and parser to be easier to debug\n- Added many more unit tests. Code coverage \u003e 90%.\n- The output is sent to an io.Writer called _w. This allows more flexible use of the templates, and the ability to wrap them with middleware","funding_links":[],"categories":["Template Engines","模板引擎"],"sub_categories":["HTTP Clients","HTTP客户端","Other Software"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoradd%2Fgot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoradd%2Fgot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoradd%2Fgot/lists"}