{"id":13412882,"url":"https://github.com/monoculum/formam","last_synced_at":"2025-03-14T18:32:33.913Z","repository":{"id":22377695,"uuid":"25714210","full_name":"monoculum/formam","owner":"monoculum","description":"a package for decode form's values into struct in Go","archived":false,"fork":false,"pushed_at":"2022-11-06T14:05:09.000Z","size":185,"stargazers_count":188,"open_issues_count":3,"forks_count":18,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-07-31T20:51:36.528Z","etag":null,"topics":["decode","decode-form","decoding","form"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/monoculum.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}},"created_at":"2014-10-25T00:23:30.000Z","updated_at":"2024-06-28T14:40:41.000Z","dependencies_parsed_at":"2022-08-20T12:20:42.446Z","dependency_job_id":null,"html_url":"https://github.com/monoculum/formam","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monoculum%2Fformam","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monoculum%2Fformam/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monoculum%2Fformam/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monoculum%2Fformam/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/monoculum","download_url":"https://codeload.github.com/monoculum/formam/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221495313,"owners_count":16832458,"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":["decode","decode-form","decoding","form"],"created_at":"2024-07-30T20:01:30.556Z","updated_at":"2024-10-26T04:31:20.009Z","avatar_url":"https://github.com/monoculum.png","language":"Go","readme":"# formam\n\nA Go package to decode HTTP form and query parameters.\nThe only requirement is [Go 1.12](http://golang.org/doc/go1.12) or later.\n\n[![Build Status](https://travis-ci.org/monoculum/formam.svg?branch=master)](https://travis-ci.org/monoculum/formam)\n[![GoDoc](https://godoc.org/github.com/monoculum/formam/v3?status.svg)](https://pkg.go.dev/github.com/monoculum/formam/v3)\n\n## Install\n\n```\ngo get github.com/monoculum/formam/v3\n```\n\n## Features\n\n- Infinite nesting for `maps`, `structs` and `slices`.\n- Support `UnmarshalText()` interface in values and keys of maps.\n- Supported `map` keys are `string`, `int` and variants, `uint` and variants, `uintptr`, `float32`, `float64`, `bool`, `struct`, `custom types` to one of the above types registered by function or `UnmarshalText` method, a `pointer` to one of the above types\n- A field with `interface{}` that has a `map`, `struct` or `slice` as value is accessible.\n- Decode `time.Time` with format `2006-01-02` by its `UnmarshalText()` method.\n- Decode `url.URL`.\n- Append to `slice` and `array` types without explicitly indicating an index.\n- Register a function for a custom type.\n\n## Performance\n\nYou can see the performance in [formam-benchmark](https://github.com/monoculum/formam-benchmark) compared with [ajg/form](https://github.com/ajg/form), [gorilla/schema](https://github.com/gorilla/schema), [go-playground/form](https://github.com/go-playground/form) and [built-in/json](http://golang.org/pkg/encoding/json/).\n\n## Basic usage example\n\n### In form HTML\n\n- Use `.` to access a struct field (e.g. `struct.field1`).\n- Use `[\u003cindex\u003e]` to access tje specific slice/array index (e.g. `struct.array[0]`). It's not necessary to add an index to append data.\n- Use `[\u003ckey\u003e]` to access map keys (e.g.. `struct.map[es-ES]`).\n\n```html\n\u003cform method=\"POST\"\u003e\n  \u003cinput type=\"text\" name=\"Name\" value=\"Sony\" /\u003e\n  \u003cinput type=\"text\" name=\"Location.Country\" value=\"Japan\" /\u003e\n  \u003cinput type=\"text\" name=\"Location.City\" value=\"Tokyo\" /\u003e\n  \u003cinput type=\"text\" name=\"Products[0].Name\" value=\"Playstation 4\" /\u003e\n  \u003cinput type=\"text\" name=\"Products[0].Type\" value=\"Video games\" /\u003e\n  \u003cinput type=\"text\" name=\"Products[1].Name\" value=\"TV Bravia 32\" /\u003e\n  \u003cinput type=\"text\" name=\"Products[1].Type\" value=\"TVs\" /\u003e\n  \u003cinput type=\"text\" name=\"Founders[0]\" value=\"Masaru Ibuka\" /\u003e\n  \u003cinput type=\"text\" name=\"Founders[0]\" value=\"Akio Morita\" /\u003e\n  \u003cinput type=\"text\" name=\"Employees\" value=\"90000\" /\u003e\n  \u003cinput type=\"text\" name=\"public\" value=\"true\" /\u003e\n  \u003cinput type=\"url\" name=\"website\" value=\"http://www.sony.net\" /\u003e\n  \u003cinput type=\"date\" name=\"foundation\" value=\"1946-05-07\" /\u003e\n  \u003cinput type=\"text\" name=\"Interface.ID\" value=\"12\" /\u003e\n  \u003cinput type=\"text\" name=\"Interface.Name\" value=\"Go Programming Language\" /\u003e\n  \u003cinput type=\"submit\" /\u003e\n\u003c/form\u003e\n```\n\n### In Go\n\nYou can use the `formam` struct tag to ensure the form values are unmarshalled in the currect struct fields.\n\n```go\ntype InterfaceStruct struct {\n    ID   int\n    Name string\n}\n\ntype Company struct {\n  Public     bool      `formam:\"public\"`\n  Website    url.URL   `formam:\"website\"`\n  Foundation time.Time `formam:\"foundation\"`\n  Name       string\n  Location   struct {\n    Country  string\n    City     string\n  }\n  Products   []struct {\n    Name string\n    Type string\n  }\n  Founders   []string\n  Employees  int64\n\n  Interface interface{}\n}\n\nfunc MyHandler(w http.ResponseWriter, r *http.Request) error {\n  r.ParseForm()\n\n  m := Company{\n      // it's is possible to access to the fields although it's an interface field!\n      Interface: \u0026InterfaceStruct{},\n  }\n  dec := formam.NewDecoder(\u0026formam.DecoderOptions{TagName: \"formam\"})\n  return dec.Decode(r.Form, \u0026m)\n}\n```\n\n## Types\n\nSupported types in the destination struct are:\n\n- `string`\n- `bool`\n- `int`, `int8`, `int16`, `int32`, `int64`\n- `uint`, `uint8`, `uint16`, `uint32`, `uint64`\n- `float32`, `float64`\n- `slice`, `array`\n- `struct` and `struct anonymous`\n- `map`\n- `interface{}`\n- `time.Time`\n- `url.URL`\n- `custom types` to one of the above types\n- a `pointer` to one of the above types\n\n## Custom Marshaling\n\nYou can umarshal data and map keys by implementing the `encoding.TextUnmarshaler` interface.\n\nIf the forms sends multiple values then only the first value is passed to `UnmarshalText()`, but if the name ends with `[]` then it's called for all values.\n\n## Custom Type\n\nYou can register a function for a custom type using the `RegisterCustomType()` method. This will work for any number of given fields or all fields with the given type.\n\nRegistered type have preference over the UnmarshalText method unless the `PrefUnmarshalText` option is used.\n\n### All fields\n\n```go\ndecoder.RegisterCustomType(func(vals []string) (interface{}, error) {\n        return time.Parse(\"2006-01-02\", vals[0])\n}, []interface{}{time.Time{}}, nil)\n```\n\n### Specific fields\n\n```go\npackage main\n\ntype Times struct {\n    Timestamp   time.Time\n    Time        time.Time\n    TimeDefault time.Time\n}\n\nfunc main() {\n    var t Timestamp\n\n    dec := NewDecoder(nil)\n\n    // for Timestamp field\n    dec.RegisterCustomType(func(vals []string) (interface{}, error) {\n            return time.Parse(\"2006-01-02T15:04:05Z07:00\", vals[0])\n    }, []interface{}{time.Time{}}, []interface{}{\u0026t.Timestamp{}})\n\n    // for Time field\n    dec.RegisterCustomType(func(vals []string) (interface{}, error) {\n                return time.Parse(\"Mon, 02 Jan 2006 15:04:05 MST\", vals[0])\n    }, []interface{}{time.Time{}}, []interface{}{\u0026t.Time{}})\n\n    // for field that not be Time or Timestamp, e.g. in this example, TimeDefault.\n    dec.RegisterCustomType(func(vals []string) (interface{}, error) {\n                return time.Parse(\"2006-01-02\", vals[0])\n    }, []interface{}{time.Time{}}, nil)\n\n    dec.Decode(url.Values{}, \u0026t)\n}\n```\n\n## Notes\n\nVersion 2 is compatible with old syntax to access to maps (`map.key`), but brackets are the preferred way to access a map (`map[key])`.\n","funding_links":[],"categories":["Forms","表單","表单","表单`表单解析与绑定`","Relational Databases","\u003cspan id=\"表单-forms\"\u003e表单 Forms\u003c/span\u003e"],"sub_categories":["Advanced Console UIs","Search and Analytic Databases","高級控制台界面","检索及分析资料库","SQL 查询语句构建库","高级控制台界面","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonoculum%2Fformam","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmonoculum%2Fformam","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonoculum%2Fformam/lists"}