{"id":13412878,"url":"https://github.com/leebenson/conform","last_synced_at":"2025-04-05T09:08:03.106Z","repository":{"id":47005847,"uuid":"49083043","full_name":"leebenson/conform","owner":"leebenson","description":"Trims, sanitizes \u0026 scrubs data based on struct tags (go, golang)","archived":false,"fork":false,"pushed_at":"2023-12-23T10:20:04.000Z","size":56,"stargazers_count":320,"open_issues_count":5,"forks_count":36,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-12T00:42:21.635Z","etag":null,"topics":[],"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/leebenson.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}},"created_at":"2016-01-05T18:00:06.000Z","updated_at":"2024-10-09T07:31:58.000Z","dependencies_parsed_at":"2024-01-08T15:02:50.883Z","dependency_job_id":"e992cb81-b3a8-443a-b986-5ee14fc395de","html_url":"https://github.com/leebenson/conform","commit_stats":null,"previous_names":["leebenson/sanitize"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leebenson%2Fconform","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leebenson%2Fconform/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leebenson%2Fconform/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leebenson%2Fconform/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leebenson","download_url":"https://codeload.github.com/leebenson/conform/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247312081,"owners_count":20918344,"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":[],"created_at":"2024-07-30T20:01:30.510Z","updated_at":"2025-04-05T09:08:03.066Z","avatar_url":"https://github.com/leebenson.png","language":"Go","readme":"# Conform- keep user input in check (go, golang)\n\nTrim, sanitize, and modify struct string fields in place, based on tags.\n\n**Now also works with embedded structs**\n\nTurns this...\n\n``` go\ntype Person struct {\n\tFirstName string `conform:\"name\"`\n\tLastName  string `conform:\"ucfirst,trim\"`\n\tEmail     string `conform:\"email\"`\n\tCamelCase string `conform:\"camel\"`\n\tUserName  string `conform:\"snake\"`\n\tSlug      string `conform:\"slug\"`\n\tBlurb     string `conform:\"title\"`\n\tLeft      string `conform:\"ltrim\"`\n\tRight     string `conform:\"rtrim\"`\n\n \tSkills   []string          `conform:\"upper\"`\n\tExamples map[string]string `conform:\"!html\"`\n}\n\np1 := Person{\n\t\" LEE \",\n\t\"     Benson\",\n\t\"   LEE@LEEbenson.com  \",\n\t\"I love new york city\",\n\t\"lee benson\",\n\t\"LeeBensonWasHere\",\n\t\"this is a little bit about me...\",\n\t\"    Left trim   \",\n\t\"    Right trim  \",\n\t[]string{\"HtmL\", \"Yaml\"},\n\tmap[string]string{\"\u003cbest\u003e\":\"\u003cbody\u003e\u003cp\u003eI know this \u0026 that.\u003c/p\u003e\u003c/body\u003e\"},\n}\n\n```\n\nInto this...\n\n``` go\np2 := p1 // \u003c-- copy the Person struct into a new one, to see the difference\nconform.Strings(\u0026p2) // \u003c-- this does the work\n\n/*\n\tp1 (left) vs. p2 (right)\n\n\tFirstName: ' LEE ' -\u003e 'Lee'\n\tLastName: '     Benson' -\u003e 'Benson'\n\tEmail: '   LEE@LEEbenson.com  ' -\u003e 'lee@leebenson.com'\n\tCamelCase: 'I love new york city' -\u003e 'ILoveNewYorkCity'\n\tUserName: 'lee benson' -\u003e 'lee_benson'\n\tSlug: 'LeeBensonWasHere' -\u003e 'lee-benson-was-here'\n\tBlurb: 'this is a little bit about me...' -\u003e 'This Is A Little Bit About Me...'\n\tLeft: '    Left trim   ' -\u003e 'Left trim   '\n\tRight: '    Right trim  ' -\u003e '    Right trim',\n\tSkills: { 'HtmL', 'Yaml' } -\u003e { 'HTML', 'YAML' },\n\tExamples: { '\u003cbest\u003e': '\u003cbody\u003e\u003cp\u003eI know this \u0026 that.\u003c/p\u003e\u003c/body\u003e' } -\u003e { '\u003cbest\u003e': '\u0026lt;body\u0026gt;\u0026lt;p\u0026gt;I know this \u0026amp; that.\u0026lt;/p\u0026gt;\u0026lt;/body\u0026gt;' }\n*/\n```\n**Note: No map keys are changed.**\n\n## Why?\n\nConform helps you fix and format user strings quickly, without writing functions.\n\nIf you do form processing with [Gorilla Schema](http://www.gorillatoolkit.org/pkg/schema) or similar, you probably shuttle user data into structs using tags. Adding a `conform` tag to your string field gives you \"first pass\" clean up against user input.\n\nUse it for names, e-mail addresses, URL slugs, or any other form field where formatting matters.\n\nConform doesn't attempt any kind of validation on your fields. Check out [govalidator](https://github.com/asaskevich/govalidator) for a slew of common validation funcs, or [validator](https://github.com/go-playground/validator) which is an uber-flexible Swiss Army knife for validating pretty much any kind of data you can imagine. Both have struct tag syntax and can be used with conform.\n\n## How to use\n\nGrab the package from the command line with:\n\n`go get github.com/leebenson/conform`\n\nAnd import in the usual way in your Go app:\n\n`import \"github.com/leebenson/conform\"`\n\nAdd a `conform` tag to your structs, for all of the string fields that you want Conform to transform. Add the name of the transform (known as the \"tag\") in double quotes, and separate multiple tags with commas. Example: `conform:\"trim,lowercase\"`\n\nTo format in place, pass your struct pointer to `conform.Strings`.\n\n**Note: your struct will be edited _in place_. This will OVERWRITE any data that is already stored in your string fields.**\n\nHere's an example that formats e-mail addresses:\n\n``` go\npackage main\n\nimport (\n\t\t\"fmt\"\n\t\t\"github.com/leebenson/conform\"\n)\n\ntype UserForm struct {\n\tEmail string `conform:\"email\"`\n}\n\nfunc main() {\n\tinput := UserForm{\n\t\tEmail: \"   POORLYFormaTTED@EXAMPlE.COM  \",\n\t}\n\tconform.Strings(\u0026input) // \u003c-- pass in a pointer to your struct\n\tfmt.Println(input.Email) // prints \"poorlyformatted@example.com\"\n}\n\n```\n\n## Using with Gorilla Schema\n\nJust add a `conform` tag along with your Gorilla `schema` tags:\n\n``` go\n// ...\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/gorilla/schema\"\n\t\"github.com/leebenson/conform\"\n)\n\n// the struct that will be filled from the post request...\ntype newUserForm struct {\n\tFirstName string    `schema:\"firstName\" conform:\"name\"`\n\tEmail     string    `schema:\"emailAddress\" conform:\"email\"`\n\tPassword  string    `schema:\"password\"`    // \u003c-- no tag? no change\n\tDob       time.Time `schema:\"dateOfBirth\"` // \u003c-- non-strings ignored by conform\n}\n\n// ProcessNewUser attempts to register a new user\nfunc ProcessNewUser(r *http.Request) error {\n\tform := new(newUserForm)\n\tschema.NewDecoder().Decode(form, r.PostForm) // \u003c-- Gorilla Schema\n\tconform.Strings(form)                       // \u003c-- Conform.  Pass in the same pointer that Schema used\n\t// ...\n}\n\n// HTTP handlers, etc...\n\n```\n\n## Godoc\nSee the [public API / exported methods on Godoc](https://godoc.org/github.com/leebenson/conform).\n\n## Tags\n\nYou can use multiple tags in the format of `conform:\"tag1,tag2\"`\n\n### trim\n---------------------------------------\nTrims leading and trailing spaces. Example: `\"   string   \"` -\u003e `\"string\"`\n\n### ltrim\n---------------------------------------\nTrims leading spaces only. Example: `\"   string   \"` -\u003e `\"string   \"`\n\n### rtrim\n---------------------------------------\nTrims trailing spaces only. Example: `\"   string   \"` -\u003e `\"   string\"`\n\n### lower\n---------------------------------------\nConverts string to lowercase. Example: `\"STRING\"` -\u003e `\"string\"`\n\n### upper\n---------------------------------------\nConverts string to uppercase. Example: `\"string\"` -\u003e `\"STRING\"`\n\n### title\n---------------------------------------\nConverts string to Title Case, e.g. `\"this is a sentence\"` -\u003e `\"This Is A Sentence\"`\n\n### camel\n---------------------------------------\nConverts to camel case via [stringUp](https://github.com/etgryphon/stringUp), Example provided by library: `this is it =\u003e thisIsIt, this\\_is\\_it =\u003e thisIsIt, this-is-it =\u003e thisIsIt`\n\n### snake\n---------------------------------------\nConverts to snake_case. Example: `\"CamelCase\"` -\u003e `\"camel_case\"`, `\"regular string\"` -\u003e `\"regular_string\"`\nSpecial thanks to [snaker](https://github.com/serenize/snaker/) for inspiration (credited in license)\n\n### slug\n---------------------------------------\nTurns strings into slugs.  Example: `\"CamelCase\"` -\u003e `\"camel-case\"`, `\"blog title here\"` -\u003e `\"blog-title-here\"`\n\n### ucfirst\n---------------------------------------\nUppercases first character.  Example: `\"all lower\"` -\u003e `\"All lower\"`\n\n### name\n---------------------------------------\nTrims, strips numbers and special characters (except dashes and spaces separating names), converts multiple spaces and dashes to single characters, title cases multiple names. Example: `\"3493€848Jo-s$%£@Ann   \"` -\u003e `\"Jo-Ann\"`, `\"  ~~  The       Dude ~~\"` -\u003e `\"The Dude\"`, `\"**susan**\"` -\u003e `\"Susan\"`, `\"    hugh fearnley-whittingstall\"` -\u003e `\"Hugh Fearnley-Whittingstall\"`\n\n### email\n---------------------------------------\nTrims and lowercases the domain portion of the string.  Example: `\"UNSIGHTLY-EMAIL@EXamPLE.com \"` -\u003e `\"UNSIGHTLY-EMAIL@example.com\"`\n\n### num\n---------------------------------------\nRemoves all non-numeric characters. Example: `\"the price is €30,38\"` -\u003e `\"3038\"`\n\n_Note: The struct field will remain a string. No type conversion takes place._\n\n### !num\n---------------------------------------\nRemoves all numbers. Example `\"39472349D34a34v69e8932747\"` -\u003e `\"Dave\"`\n\n### alpha\n---------------------------------------\nRemoves non-alpha unicode characters. Example: `\"!@£$%^\u0026'()Hello 1234567890 World+[];\\\"` -\u003e `\"HelloWorld\"`\n\n### !alpha\n---------------------------------------\nRemoves alpha unicode characters. Example: `\"Everything's here but the letters!\"` -\u003e `\"'    !\"`\n\n### !html\n---------------------------------------\n\nEscapes HTML so that it is safe for display. Characters are substituted by their respective HTML codes. Internally uses _template.HTMLEscapeString_.\nExample: `\"' \" \u0026 \u003c \u003e \\000\"` -\u003e `\"\u0026#39; \u0026#34; \u0026amp; \u0026lt; \u0026gt; \\uFFFD\"`\n\n### !js\n---------------------------------------\n\nEscapes JavaScript. Internally uses _template.JSEscapeString_. Example: `\"\\ ' \" \u003c \u003e \u0026 =\"` -\u003e `\"\\\\ \\' \\u003C \\u003E \\u0026 \\u003D\"`\n\n### LICENSE\n[MIT](https://github.com/leebenson/conform/blob/master/LICENSE)\n","funding_links":[],"categories":["Forms","表单","表單","\u003cspan id=\"表单-forms\"\u003e表单 Forms\u003c/span\u003e","表单`表单解析与绑定`","Relational Databases"],"sub_categories":["Search and Analytic Databases","SQL 查询语句构建库","Advanced Console UIs","检索及分析资料库","高級控制台界面","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e","高级控制台界面"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleebenson%2Fconform","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleebenson%2Fconform","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleebenson%2Fconform/lists"}