{"id":13413841,"url":"https://github.com/benbjohnson/ego","last_synced_at":"2025-04-13T02:12:43.059Z","repository":{"id":14402923,"uuid":"17113616","full_name":"benbjohnson/ego","owner":"benbjohnson","description":"An ERB-style templating language for Go.","archived":false,"fork":false,"pushed_at":"2023-03-15T07:38:13.000Z","size":84,"stargazers_count":582,"open_issues_count":10,"forks_count":40,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-04-11T16:06:40.385Z","etag":null,"topics":["erb","go","template-language"],"latest_commit_sha":null,"homepage":null,"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/benbjohnson.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-02-23T18:14:41.000Z","updated_at":"2025-03-02T17:47:51.000Z","dependencies_parsed_at":"2024-06-18T13:56:11.619Z","dependency_job_id":null,"html_url":"https://github.com/benbjohnson/ego","commit_stats":{"total_commits":51,"total_committers":7,"mean_commits":7.285714285714286,"dds":"0.27450980392156865","last_synced_commit":"609b6f511286e696f59a5075a8ad9d2e6b444919"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benbjohnson%2Fego","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benbjohnson%2Fego/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benbjohnson%2Fego/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benbjohnson%2Fego/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benbjohnson","download_url":"https://codeload.github.com/benbjohnson/ego/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248654094,"owners_count":21140236,"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":["erb","go","template-language"],"created_at":"2024-07-30T20:01:50.926Z","updated_at":"2025-04-13T02:12:43.025Z","avatar_url":"https://github.com/benbjohnson.png","language":"Go","funding_links":[],"categories":["Go","模板引擎","Misc","Template Engines","\u003cspan id=\"模板引擎-template-engines\"\u003e模板引擎 Template Engines\u003c/span\u003e","模板引擎`模版渲染和模版生成处理库`","Relational Databases"],"sub_categories":["交流","HTTP Clients","Advanced Console UIs","HTTP客户端","查询语","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e"],"readme":"Ego [![GoDoc](https://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square)](https://godoc.org/github.com/benbjohnson/ego)\n===\n\nEgo is an [ERb](http://ruby-doc.org/stdlib-2.1.0/libdoc/erb/rdoc/ERB.html) style templating language for Go. It works by transpiling templates into pure Go and including them at compile time. These templates are light wrappers around the Go language itself.\n\n## Install\n\nYou can find a release build of ego for Linux on the [Releases page](https://github.com/benbjohnson/ego/releases).\n\nTo install ego from source, you can run this command outside of the `GOPATH`:\n\n```sh\n$ go get github.com/benbjohnson/ego/...\n```\n\n\n## Usage\n\nRun `ego` on a directory. Recursively traverse the directory structure and generate Go files for all matching `.ego` files.\n\n```sh\n$ ego mypkg\n```\n\n\n## How to Write Templates\n\nAn ego template lets you write text that you want to print out but gives you some handy tags to let you inject actual Go code.\nThis means you don't need to learn a new scripting language to write ego templates—you already know Go!\n\n### Raw Text\n\nAny text the `ego` tool encounters that is not wrapped in `\u003c%` and `%\u003e` tags is considered raw text.\nIf you have a template like this:\n\n```\nhello!\ngoodbye!\n```\n\nThen `ego` will generate a matching `.ego.go` file:\n\n```\nio.WriteString(w, \"hello!\\ngoodbye!\")\n```\n\nUnfortunately that file won't run because we're missing a `package` line at the top.\nWe can fix that with _code blocks_.\n\n\n### Code Blocks\n\nA code block is a section of your template wrapped in `\u003c%` and `%\u003e` tags.\nIt is raw Go code that will be inserted into our generate `.ego.go` file as-is.\n\nFor example, given this template:\n\n```\n\u003c%\npackage myapp\n\nfunc Render(ctx context.Context, w io.Writer) {\n%\u003e\nhello!\ngoodbye!\n\u003c% } %\u003e\n```\n\nThe `ego` tool will generate:\n\n```\npackage myapp\n\nimport (\n\t\"context\"\n\t\"io\"\n)\n\nfunc Render(ctx context.Context, w io.Writer) {\n\tio.WriteString(w, \"hello!\\ngoodbye!\")\n}\n```\n\n_Note the `context` and `io` packages are automatically imported to your template._\n_These are the only packages that do this._\n_You'll need to import any other packages you use._\n\n\n### Print Blocks\n\nOur template is getting more useful.\nWe now have actually runnable Go code.\nHowever, our templates typically need output text frequently so there are blocks specifically for this task called _print blocks_.\nThese print blocks wrap a Go expression with `\u003c%=` and `%\u003e` tags.\n\nWe can expand our previous example and add a type and fields to our code:\n\n\n```\n\u003c%\npackage myapp\n\ntype NameRenderer struct {\n\tName  string\n\tGreet bool\n}\n\nfunc (r *NameRenderer) Render(ctx context.Context, w io.Writer) {\n%\u003e\n\t\u003c% if r.Greet { %\u003e\n\t\thello, \u003c%= r.Name %\u003e!\n\t\u003c% } else { %\u003e\n\t\tgoodbye, \u003c%= r.Name %\u003e!\n\t\u003c% } %\u003e\n\u003c% } %\u003e\n```\n\nWe now have a conditional around our `Greet` field and we are printing the `Name` field.\nOur generated code will look like:\n\n\n```\npackage myapp\n\nimport (\n\t\"context\"\n\t\"io\"\n)\n\ntype NameRenderer struct {\n\tName  string\n\tGreet bool\n}\n\nfunc Render(ctx context.Context, w io.Writer) {\n\tif r.Greet {\n\t\tio.WriteString(w, \"hello, \")\n\t\tio.WriteString(w, html.EscapeString(fmt.Sprint(r.Name)))\n\t\tio.WriteString(w, \"!\")\n\t} else {\n\t\tio.WriteString(w, \"goodbye, \")\n\t\tio.WriteString(w, html.EscapeString(fmt.Sprint(r.Name)))\n\t\tio.WriteString(w, \"!\")\n\t}\n}\n```\n\n\n#### Printing unescaped HTML\n\nThe `\u003c%= %\u003e` block will print your text as escaped HTML, however, sometimes you need the raw text such as when you're writing JSON.\nTo do this, simply wrap your Go expression with `\u003c%==` and `%\u003e` tags.\n\n\n### Components\n\nSimple code and print tags work well for simple templates but it can be difficult to make reusable functionality.\nYou can use the component syntax to print types that implement this `Renderer` interface:\n\n```\ntype Renderer interface {\n\tRender(context.Context, io.Writer)\n}\n```\n\nComponent syntax look likes HTML.\nYou specify the type you want to instantiate as the node name and then use attributes to assign values to fields.\nThe body of your component will be assigned as a closure to a field called `Yield` on your component type.\n\nFor example, let's say you want to make a reusable button that outputs [Bootstrap 4.0](http://getbootstrap.com/) code:\nWe can write this component as an ego template or in pure Go code.\nHere we'll write the component in Go:\n\n```\npackage myapp\n\nimport (\n\t\"context\"\n\t\"io\"\n)\n\ntype Button struct {\n\tStyle string\n\tYield func()\n}\n\nfunc (r *Button) Render(ctx context.Context, w io.Writer) {\n\tfmt.Fprintf(w, `\u003cdiv class=\"btn btn-%s\"\u003e`, r.Style)\n\tif r.Yield {\n\t\tr.Yield()\n\t}\n\tfmt.Fprintf(w, `\u003c/div\u003e`)\n}\n```\n\nNow we can use that component from a template in the same package like this:\n\n```\n\u003c%\npackage myapp\n\ntype MyTemplate struct {}\n\nfunc (r *MyTemplate) Render(ctx context.Context, w io.Writer) {\n%\u003e\n\t\u003cdiv class=\"container\"\u003e\n\t\t\u003cego:Button Style=\"danger\"\u003eDon't click me!\u003c/ego:Button\u003e\n\t\u003c/div\u003e\n\u003c% } %\u003e\n```\n\nOur template automatically convert our component syntax into an instance and invocation of `Button`:\n\n```\nvar EGO Button\nEGO.Style = \"danger\"\nEGO.Yield = func() { io.WriteString(w, \"Don't click me!\") }\nEGO.Render(ctx, w)\n```\n\nField values can be specified as any Go expression.\nFor example, you could specify a function to return a value for `Button.Style`:\n\n```\n\u003cego:Button Style=r.ButtonStyle()\u003eDon't click me!\u003c/ego:Button\u003e\n```\n\n#### Named closures\n\nThe `Yield` is a special instance of a closure, however, you can also specify named closures using the `::` syntax.\n\nGiven a component type:\n\n```\ntype MyView struct {\n\tHeader func()\n\tYield  func()\n}\n```\n\nWe can specify the separate closures like this:\n\n```\n\u003cego:MyView\u003e\n\t\u003cego::Header\u003e\n\t\tThis content will go in the Header closure.\n\t\u003c/ego::Header\u003e\n\n\tThis content will go in the Yield closure.\n\u003c/ego:MyView\u003e\n```\n\n#### Importing components from other packages\n\nYou can import components from other packages by using a namespace that matches the package name\nThe `ego` namespace is reserved to import types in the current package.\n\nFor example, you can import components from a library such as [bootstrap-ego](https://github.com/benbjohnson/bootstrap-ego):\n\n```\n\u003c%\npackage myapp\n\nimport \"github.com/benbjohnson/bootstrap-ego\"\n\ntype MyTemplate struct {}\n\nfunc (r *MyTemplate) Render(ctx context.Context, w io.Writer) {\n%\u003e\n\t\u003cbootstrap:Container\u003e\n\t\t\u003cbootstrap:Row\u003e\n\t\t\t\u003cdiv class=\"col-md-3\"\u003e\n\t\t\t\t\u003cbootstrap:Button Style=\"danger\" Size=\"lg\"\u003eDon't click me!\u003c/bootstrap:Button\u003e\n\t\t\t\u003c/div\u003e\n\t\t\u003c/bootstrap:Row\u003e\n\t\u003c/bootstrap:Container\u003e\n\u003c% } %\u003e\n```\n\n\n## Caveats\n\nUnlike other runtime-based templating languages, ego does not support ad hoc templates. All templates must be generated before compile time.\n\nEgo does not attempt to provide any security around the templates. Just like regular Go code, the security model is up to you.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenbjohnson%2Fego","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenbjohnson%2Fego","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenbjohnson%2Fego/lists"}