func testing2(ctx app.Context) { ctx.T("Testing even more translations") var t1 i18n.String = "Var inside function" /// This is a var string declared via cast t2 := i18n.String("Testing var string") fmt.Println(t1, t2) }
) const ( notChosen = "___gondola_not_chosen" // NotChosen is used to indicate that a value from // a multiple choices input has not been chosen // by the user. See also Choose. NotChosen = notChosen ) var ( // Choose creates a choice entry with the text // "Please, choose" which generates an error when // the user does not choose anything. Choose = &Choice{ Name: i18n.String("form|Please, choose"), Value: NotChosen, } ) // Choice represents a choice in a select or radio field. type Choice struct { // Name must be either a string or an i18n.String // or a fmt.Stringer. // Other types will panic when rendering the form. Name interface{} Value interface{} } func (c *Choice) TranslatedName(lang i18n.Languager) string { switch x := c.Name.(type) {
func (f *Form) makeField(name string) (*Field, error) { var s *structs.Struct idx := -1 var fieldValue reflect.Value var sval reflect.Value for ii, v := range f.structs { pos, ok := v.QNameMap[name] if ok { if s != nil { return nil, fmt.Errorf("duplicate field %q (found in %v and %v)", name, s.Type, v.Type) } s = v idx = pos sval = f.values[ii] fieldValue = fieldByIndex(sval, s.Indexes[pos]) // Check the validation function, so if the function is not valid // the error is generated at form instantiation. if _, err := structs.ValidationFunction(sval, name); err != nil { return nil, err } } } if idx < 0 { return nil, fmt.Errorf("can't map form field %q", name) } tag := s.Tags[idx] label := tag.Value("label") if label == "" { label = stringutil.CamelCaseToWords(name, " ") } var typ Type if tag.Has("hidden") { typ = HIDDEN } else if tag.Has("radio") { typ = RADIO } else if tag.Has("select") { typ = SELECT } else { switch s.Types[idx].Kind() { case reflect.Func: return nil, nil case reflect.String: if s.Types[idx] == reflect.TypeOf(password.Password("")) || tag.Has("password") { typ = PASSWORD } else if tag.Has("email") { typ = EMAIL } else { if ml, ok := tag.MaxLength(); ok && ml > 0 { typ = TEXT } else if tag.Has("singleline") || tag.Has("line") { typ = TEXT } else if tag.Has("password") { typ = PASSWORD } else { typ = TEXTAREA } } case reflect.Bool: typ = CHECKBOX case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64: typ = TEXT default: if s.Types[idx] == fileType { typ = FILE break } return nil, fmt.Errorf("field %q has invalid type %v", name, s.Types[idx]) } } // Check if the struct implements the ChoicesProvider interface if typ == RADIO || typ == SELECT { container := sval.Addr().Interface() if _, ok := container.(ChoicesProvider); !ok { return nil, fmt.Errorf("field %q requires choices, but %T does not implement ChoicesProvider", name, container) } } htmlName := f.toHTMLName(name) field := &Field{ Type: typ, Name: name, HTMLName: htmlName, Label: i18n.String(label), Placeholder: i18n.String(tag.Value("placeholder")), Help: i18n.String(tag.Value("help")), id: htmlName, value: fieldValue, s: s, sval: sval, pos: idx, } return field, nil }
package app import ( "fmt" "net/http" "gnd.la/i18n" ) var ( defaultMessages = map[int]i18n.String{ http.StatusBadRequest: i18n.String("bad request"), http.StatusUnauthorized: i18n.String("unauthorized"), http.StatusPaymentRequired: i18n.String("payment required"), http.StatusForbidden: i18n.String("forbidden"), http.StatusNotFound: i18n.String("not found"), http.StatusMethodNotAllowed: i18n.String("method not allowed"), http.StatusNotAcceptable: i18n.String("not acceptable"), http.StatusProxyAuthRequired: i18n.String("proxy required"), http.StatusRequestTimeout: i18n.String("request timeout"), http.StatusConflict: i18n.String("conflict"), http.StatusGone: i18n.String("gone"), http.StatusLengthRequired: i18n.String("length required"), http.StatusPreconditionFailed: i18n.String("precondition failed"), http.StatusRequestEntityTooLarge: i18n.String("request entity too large"), http.StatusRequestURITooLong: i18n.String("request URI too long"), http.StatusUnsupportedMediaType: i18n.String("unsupported media type"), http.StatusRequestedRangeNotSatisfiable: i18n.String("request range not satisfiable"), http.StatusExpectationFailed: i18n.String("expectation failed"), http.StatusTeapot: i18n.String("i'm a teapot"),
/// This field should get its help extracted Id int `config:",help:This is the user id" forms:",label:Identifier"` } const ( /// This is a constant translatable string _ i18n.String = "Testing constant string" /// This constant string is created by concatenating two strings. _ i18n.String = "Concatenated" + " constant string" ) /// This is a var string declared via type var foo i18n.String = "Testing var string" /// This is a var string declared via cast var bar = i18n.String("Testing var casted string") func main() { /// Please, translate this. /// This comment is still part of the translation comment. // This comment is not part of the translation comment. fmt.Println(i18n.T(nil, "Hello world\n")) /// This translation has a context fmt.Println(i18n.Tc(nil, "second", "Hello world\n")) /// This is a long translation, to test line splitting in quoted strings. fmt.Println(i18n.T(nil, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sed ante ut massa ultrices auctor. Vivamus rutrum ut ante et aliquet. Proin ut rutrum enim, a elementum ligula. Morbi malesuada.")) // This is not part of the translation comment. //