Documentation ¶
Index ¶
- Constants
- Variables
- func ActionInvoker(c *Controller, _ []Filter)
- func Bind(params *Params, name string, typ reflect.Type) reflect.Value
- func BindFile(fileHeader *multipart.FileHeader, typ reflect.Type) reflect.Value
- func BindValue(val string, typ reflect.Type) reflect.Value
- func CheckInit()
- func CompressFilter(c *Controller, fc []Filter)
- func ContainsString(list []string, target string) bool
- func ContentTypeByFilename(filename string) string
- func DirExists(filename string) bool
- func Equal(a, b interface{}) bool
- func ExecuteTemplate(tmpl ExecutableTemplate, data interface{}) string
- func FilterConfiguringFilter(c *Controller, fc []Filter)
- func FilterEq(a, b Filter) bool
- func FindMethod(recvType reflect.Type, funcVal reflect.Value) *reflect.Method
- func FirstNonEmpty(strs ...string) string
- func FlashFilter(c *Controller, fc []Filter)
- func I18nFilter(c *Controller, fc []Filter)
- func Init(mode, importPath, srcPath string)
- func InterceptFunc(intc InterceptorFunc, when When, target interface{})
- func InterceptMethod(intc InterceptorMethod, when When)
- func InterceptorFilter(c *Controller, fc []Filter)
- func LoadMimeConfig()
- func Message(locale, message string, args ...interface{}) string
- func MessageLanguages() []string
- func MustReadLines(filename string) []string
- func OnAppStart(f func())
- func PanicFilter(c *Controller, fc []Filter)
- func ParamsFilter(c *Controller, fc []Filter)
- func ParseKeyValueCookie(val string, cb func(key, val string))
- func ParseParams(params *Params, req *Request)
- func ReadLines(filename string) ([]string, error)
- func RegisterController(c interface{}, methods []*MethodType)
- func ResolveContentType(req *http.Request) string
- func ResolveFormat(req *http.Request) string
- func ResolveImportPath(importPath string) (string, error)
- func ReverseUrl(args ...interface{}) (string, error)
- func RouterFilter(c *Controller, fc []Filter)
- func Run(port int)
- func SessionFilter(c *Controller, fc []Filter)
- func Sign(message string) string
- func Slug(text string) string
- func Unbind(output map[string]string, name string, val interface{})
- func ValidationFilter(c *Controller, fc []Filter)
- func ValueBinder(f func(value string, typ reflect.Type) reflect.Value) func(*Params, string, reflect.Type) reflect.Value
- func Verify(message, sig string) bool
- type AcceptLanguage
- type AcceptLanguages
- type ActionDefinition
- type BinaryResult
- type Binder
- type CompressResponseWriter
- type ContentDisposition
- type Controller
- func (c *Controller) FlashParams()
- func (c *Controller) Forbidden(msg string, objs ...interface{}) Result
- func (c *Controller) Message(message string, args ...interface{}) (value string)
- func (c *Controller) NotFound(msg string, objs ...interface{}) Result
- func (c *Controller) Redirect(val interface{}, args ...interface{}) Result
- func (c *Controller) Render(extraRenderArgs ...interface{}) Result
- func (c *Controller) RenderBinary(memfile io.Reader, filename string, delivery ContentDisposition, ...) Result
- func (c *Controller) RenderError(err error) Result
- func (c *Controller) RenderFile(file *os.File, delivery ContentDisposition) Result
- func (c *Controller) RenderHtml(html string) Result
- func (c *Controller) RenderJson(o interface{}) Result
- func (c *Controller) RenderJsonP(callback string, o interface{}) Result
- func (c *Controller) RenderTemplate(templatePath string) Result
- func (c *Controller) RenderText(text string, objs ...interface{}) Result
- func (c *Controller) RenderXml(o interface{}) Result
- func (c *Controller) SetAction(controllerName, methodName string) error
- func (c *Controller) SetCookie(cookie *http.Cookie)
- func (c *Controller) Todo() Result
- type ControllerType
- type DiscerningListener
- type Email
- type Error
- type ErrorResult
- type ExecutableTemplate
- type Field
- type Filter
- type FilterConfigurator
- type Flash
- type GoTemplate
- type InterceptTarget
- type Interception
- type InterceptorFunc
- type InterceptorMethod
- type Length
- type Listener
- type Match
- type Max
- type MaxSize
- type MergedConfig
- func (c *MergedConfig) Bool(option string) (result, found bool)
- func (c *MergedConfig) BoolDefault(option string, dfault bool) bool
- func (c *MergedConfig) HasSection(section string) bool
- func (c *MergedConfig) Int(option string) (result int, found bool)
- func (c *MergedConfig) IntDefault(option string, dfault int) int
- func (c *MergedConfig) Options(prefix string) []string
- func (c *MergedConfig) Raw() *config.Config
- func (c *MergedConfig) SetOption(name, value string)
- func (c *MergedConfig) SetSection(section string)
- func (c *MergedConfig) String(option string) (result string, found bool)
- func (c *MergedConfig) StringDefault(option, dfault string) string
- type MethodArg
- type MethodType
- type Min
- type MinSize
- type Module
- type Params
- type PlaintextErrorResult
- type Range
- type RedirectToActionResult
- type RedirectToUrlResult
- type RenderHtmlResult
- type RenderJsonResult
- type RenderTemplateResult
- type RenderTextResult
- type RenderXmlResult
- type Request
- type Required
- type Response
- type Result
- type Route
- type RouteMatch
- type Router
- type Session
- type Template
- type TemplateLoader
- type TestSuite
- func (t *TestSuite) Assert(exp bool)
- func (t *TestSuite) AssertContains(s string)
- func (t *TestSuite) AssertContainsRegex(regex string)
- func (t *TestSuite) AssertContentType(contentType string)
- func (t *TestSuite) AssertEqual(expected, actual interface{})
- func (t *TestSuite) AssertHeader(name, value string)
- func (t *TestSuite) AssertNotFound()
- func (t *TestSuite) AssertOk()
- func (t *TestSuite) AssertStatus(status int)
- func (t *TestSuite) Assertf(exp bool, formatStr string, args ...interface{})
- func (t *TestSuite) BaseUrl() string
- func (t *TestSuite) Delete(path string)
- func (t *TestSuite) Get(path string)
- func (t *TestSuite) Host() string
- func (t *TestSuite) MakeRequest(req *http.Request)
- func (t *TestSuite) MakeRequestSession(req *http.Request)
- func (t *TestSuite) Post(path string, contentType string, reader io.Reader)
- func (t *TestSuite) PostForm(path string, data url.Values)
- func (t *TestSuite) WebSocket(path string) *websocket.Conn
- func (t *TestSuite) WebSocketUrl() string
- type Validation
- func (v *Validation) Check(obj interface{}, checks ...Validator) *ValidationResult
- func (v *Validation) Clear()
- func (v *Validation) Email(str string) *ValidationResult
- func (v *Validation) Error(message string, args ...interface{}) *ValidationResult
- func (v *Validation) ErrorMap() map[string]*ValidationError
- func (v *Validation) HasErrors() bool
- func (v *Validation) Keep()
- func (v *Validation) Length(obj interface{}, n int) *ValidationResult
- func (v *Validation) Match(str string, regex *regexp.Regexp) *ValidationResult
- func (v *Validation) Max(n int, max int) *ValidationResult
- func (v *Validation) MaxSize(obj interface{}, max int) *ValidationResult
- func (v *Validation) Min(n int, min int) *ValidationResult
- func (v *Validation) MinSize(obj interface{}, min int) *ValidationResult
- func (v *Validation) Range(n, min, max int) *ValidationResult
- func (v *Validation) Required(obj interface{}) *ValidationResult
- type ValidationError
- type ValidationResult
- type Validator
- type Watcher
- type When
- type WriteFlusher
Constants ¶
const ( DEFAULT_DATE_FORMAT = "2006-01-02" DEFAULT_DATETIME_FORMAT = "2006-01-02 15:04" )
const ( SESSION_ID_KEY = "_ID" TIMESTAMP_KEY = "_TS" )
const (
CurrentLocaleRenderArg = "currentLocale" // The key for the current locale render arg value
)
const DefaultFileContentType = "application/octet-stream"
const (
REVEL_IMPORT_PATH = "github.com/robfig/revel"
)
Variables ¶
var ( // These are the lookups to find a Binder for any type of data. // The most specific binder found will be used (Type before Kind) TypeBinders = make(map[reflect.Type]Binder) KindBinders = make(map[reflect.Kind]Binder) // Applications can add custom time formats to this array, and they will be // automatically attempted when binding a time.Time. TimeFormats = []string{} DateFormat string DateTimeFormat string IntBinder = Binder{ Bind: ValueBinder(func(val string, typ reflect.Type) reflect.Value { if len(val) == 0 { return reflect.Zero(typ) } intValue, err := strconv.ParseInt(val, 10, 64) if err != nil { WARN.Println(err) return reflect.Zero(typ) } pValue := reflect.New(typ) pValue.Elem().SetInt(intValue) return pValue.Elem() }), Unbind: func(output map[string]string, key string, val interface{}) { output[key] = fmt.Sprintf("%d", val) }, } UintBinder = Binder{ Bind: ValueBinder(func(val string, typ reflect.Type) reflect.Value { if len(val) == 0 { return reflect.Zero(typ) } uintValue, err := strconv.ParseUint(val, 10, 64) if err != nil { WARN.Println(err) return reflect.Zero(typ) } pValue := reflect.New(typ) pValue.Elem().SetUint(uintValue) return pValue.Elem() }), Unbind: func(output map[string]string, key string, val interface{}) { output[key] = fmt.Sprintf("%d", val) }, } FloatBinder = Binder{ Bind: ValueBinder(func(val string, typ reflect.Type) reflect.Value { if len(val) == 0 { return reflect.Zero(typ) } floatValue, err := strconv.ParseFloat(val, 64) if err != nil { WARN.Println(err) return reflect.Zero(typ) } pValue := reflect.New(typ) pValue.Elem().SetFloat(floatValue) return pValue.Elem() }), Unbind: func(output map[string]string, key string, val interface{}) { output[key] = fmt.Sprintf("%f", val) }, } StringBinder = Binder{ Bind: ValueBinder(func(val string, typ reflect.Type) reflect.Value { return reflect.ValueOf(val) }), Unbind: func(output map[string]string, name string, val interface{}) { output[name] = val.(string) }, } // Booleans support a couple different value formats: // "true" and "false" // "on" and "" (a checkbox) // "1" and "0" (why not) BoolBinder = Binder{ Bind: ValueBinder(func(val string, typ reflect.Type) reflect.Value { v := strings.TrimSpace(strings.ToLower(val)) switch v { case "true", "on", "1": return reflect.ValueOf(true) } return reflect.ValueOf(false) }), Unbind: func(output map[string]string, name string, val interface{}) { output[name] = fmt.Sprintf("%t", val) }, } PointerBinder = Binder{ Bind: func(params *Params, name string, typ reflect.Type) reflect.Value { return Bind(params, name, typ.Elem()).Addr() }, Unbind: func(output map[string]string, name string, val interface{}) { Unbind(output, name, reflect.ValueOf(val).Elem().Interface()) }, } TimeBinder = Binder{ Bind: ValueBinder(func(val string, typ reflect.Type) reflect.Value { for _, f := range TimeFormats { if r, err := time.Parse(f, val); err == nil { return reflect.ValueOf(r) } } return reflect.Zero(typ) }), Unbind: func(output map[string]string, name string, val interface{}) { var ( t = val.(time.Time) format = DateTimeFormat h, m, s = t.Clock() ) if h == 0 && m == 0 && s == 0 { format = DateFormat } output[name] = t.Format(format) }, } MapBinder = Binder{ Bind: bindMap, Unbind: unbindMap, } )
var ( NilFilter = func(_ *Controller, _ []Filter) {} NilChain = []Filter{NilFilter} )
NilFilter and NilChain are helpful in writing filter tests.
var ( // App details AppName string // e.g. "sample" BasePath string // e.g. "/Users/robfig/gocode/src/corp/sample" AppPath string // e.g. "/Users/robfig/gocode/src/corp/sample/app" ViewsPath string // e.g. "/Users/robfig/gocode/src/corp/sample/app/views" ImportPath string // e.g. "corp/sample" SourcePath string // e.g. "/Users/robfig/gocode/src" Config *MergedConfig RunMode string // Application-defined (by default, "dev" or "prod") DevMode bool // if true, RunMode is a development mode. // Revel installation details RevelPath string // e.g. "/Users/robfig/gocode/src/revel" // Where to look for templates and configuration. // Ordered by priority. (Earlier paths take precedence over later paths.) CodePaths []string ConfPaths []string TemplatePaths []string Modules []Module // Server config. // // Alert: This is how the app is configured, which may be different from // the current process reality. For example, if the app is configured for // port 9000, HttpPort will always be 9000, even though in dev mode it is // run on a random port and proxied. HttpPort int // e.g. 9000 HttpAddr string // e.g. "", "127.0.0.1" HttpSsl bool // e.g. true if using ssl HttpSslCert string // e.g. "/path/to/cert.pem" HttpSslKey string // e.g. "/path/to/key.pem" // All cookies dropped by the framework begin with this prefix. CookiePrefix string // Cookie flags CookieHttpOnly bool CookieSecure bool // Delimiters to use when rendering templates TemplateDelims string // Loggers TRACE = log.New(ioutil.Discard, "TRACE ", log.Ldate|log.Ltime|log.Lshortfile) INFO = log.New(ioutil.Discard, "INFO ", log.Ldate|log.Ltime|log.Lshortfile) WARN = log.New(ioutil.Discard, "WARN ", log.Ldate|log.Ltime|log.Lshortfile) ERROR = log.New(&error_log, "ERROR ", log.Ldate|log.Ltime|log.Lshortfile) Initialized bool )
var ( MainRouter *Router MainTemplateLoader *TemplateLoader MainWatcher *Watcher Server *http.Server )
var DefaultValidationKeys map[string]map[int]string
Register default validation keys for all calls to Controller.Validation.Func(). Map from (package).func => (line => name of first arg to Validation func) E.g. "myapp/controllers.helper" or "myapp/controllers.(*Application).Action" This is set on initialization in the generated main.go file.
var ERROR_CLASS = "hasError"
var Filters = []Filter{ PanicFilter, RouterFilter, FilterConfiguringFilter, ParamsFilter, SessionFilter, FlashFilter, ValidationFilter, I18nFilter, InterceptorFilter, CompressFilter, ActionInvoker, }
Filters is the default set of global filters. It may be set by the application on initialization.
var ( // The functions available for use in the templates. TemplateFuncs = map[string]interface{}{ "url": ReverseUrl, "eq": Equal, "set": func(renderArgs map[string]interface{}, key string, value interface{}) template.HTML { renderArgs[key] = value return template.HTML("") }, "append": func(renderArgs map[string]interface{}, key string, value interface{}) template.HTML { if renderArgs[key] == nil { renderArgs[key] = []interface{}{value} } else { renderArgs[key] = append(renderArgs[key].([]interface{}), value) } return template.HTML("") }, "field": NewField, "option": func(f *Field, val, label string) template.HTML { selected := "" if f.Flash() == val { selected = " selected" } return template.HTML(fmt.Sprintf(`<option value="%s"%s>%s</option>`, html.EscapeString(val), selected, html.EscapeString(label))) }, "radio": func(f *Field, val string) template.HTML { checked := "" if f.Flash() == val { checked = " checked" } return template.HTML(fmt.Sprintf(`<input type="radio" name="%s" value="%s"%s>`, html.EscapeString(f.Name), html.EscapeString(val), checked)) }, "checkbox": func(f *Field, val string) template.HTML { checked := "" if f.Flash() == val { checked = " checked" } return template.HTML(fmt.Sprintf(`<input type="checkbox" name="%s" value="%s"%s>`, html.EscapeString(f.Name), html.EscapeString(val), checked)) }, "pad": func(str string, width int) template.HTML { if len(str) >= width { return template.HTML(html.EscapeString(str)) } return template.HTML(html.EscapeString(str) + strings.Repeat(" ", width-len(str))) }, "errorClass": func(name string, renderArgs map[string]interface{}) template.HTML { errorMap, ok := renderArgs["errors"].(map[string]*ValidationError) if !ok || errorMap == nil { WARN.Println("Called 'errorClass' without 'errors' in the render args.") return template.HTML("") } valError, ok := errorMap[name] if !ok || valError == nil { return template.HTML("") } return template.HTML(ERROR_CLASS) }, "msg": func(renderArgs map[string]interface{}, message string, args ...interface{}) template.HTML { str, ok := renderArgs[CurrentLocaleRenderArg].(string) if !ok { return "" } return template.HTML(Message(str, message, args...)) }, "nl2br": func(text string) template.HTML { return template.HTML(strings.Replace(template.HTMLEscapeString(text), "\n", "<br>", -1)) }, "raw": func(text string) template.HTML { return template.HTML(text) }, "pluralize": func(items interface{}, pluralOverrides ...string) string { singular, plural := "", "s" if len(pluralOverrides) >= 1 { singular = pluralOverrides[0] if len(pluralOverrides) == 2 { plural = pluralOverrides[1] } } switch v := reflect.ValueOf(items); v.Kind() { case reflect.Int: if items.(int) != 1 { return plural } case reflect.Slice: if v.Len() != 1 { return plural } default: ERROR.Println("pluralize: unexpected type: ", v) } return singular }, "date": func(date time.Time) string { return date.Format(DateFormat) }, "datetime": func(date time.Time) string { return date.Format(DateTimeFormat) }, "slug": Slug, } )
var TestSuites []interface{} // Array of structs that embed TestSuite
var WatchFilter = func(c *Controller, fc []Filter) { if MainWatcher != nil { err := MainWatcher.Notify() if err != nil { c.Result = c.RenderError(err) return } } fc[0](c, fc[1:]) }
Functions ¶
func ActionInvoker ¶
func ActionInvoker(c *Controller, _ []Filter)
func Bind ¶
Bind takes the name and type of the desired parameter and constructs it from one or more values from Params. Returns the zero value of the type upon any sort of failure.
func CompressFilter ¶
func CompressFilter(c *Controller, fc []Filter)
func ContainsString ¶
func ContentTypeByFilename ¶
Returns a MIME content type based on the filename's extension. If no appropriate one is found, returns "application/octet-stream" by default. Additionally, specifies the charset as UTF-8 for text/* types.
func Equal ¶
func Equal(a, b interface{}) bool
Equal is a helper for comparing value equality, following these rules:
- Values with equivalent types are compared with reflect.DeepEqual
- int, uint, and float values are compared without regard to the type width. for example, Equal(int32(5), int64(5)) == true
- strings and byte slices are converted to strings before comparison.
- else, return false.
func ExecuteTemplate ¶
func ExecuteTemplate(tmpl ExecutableTemplate, data interface{}) string
Execute a template and returns the result as a string.
func FilterConfiguringFilter ¶
func FilterConfiguringFilter(c *Controller, fc []Filter)
FilterConfiguringFilter is a filter stage that customizes the remaining filter chain for the action being invoked.
func FindMethod ¶
Return the reflect.Method, given a Receiver type and Func value.
func FirstNonEmpty ¶
func FlashFilter ¶
func FlashFilter(c *Controller, fc []Filter)
FlashFilter is a Revel Filter that retrieves and sets the flash cookie. Within Revel, it is available as a Flash attribute on Controller instances. The name of the Flash cookie is set as CookiePrefix + "_FLASH".
func I18nFilter ¶
func I18nFilter(c *Controller, fc []Filter)
func Init ¶
func Init(mode, importPath, srcPath string)
Init initializes Revel -- it provides paths for getting around the app.
Params:
mode - the run mode, which determines which app.conf settings are used. importPath - the Go import path of the application. srcPath - the path to the source directory, containing Revel and the app. If not specified (""), then a functioning Go installation is required.
func InterceptFunc ¶
func InterceptFunc(intc InterceptorFunc, when When, target interface{})
Install a general interceptor. This can be applied to any Controller. It must have the signature of:
func example(c *revel.Controller) revel.Result
func InterceptMethod ¶
func InterceptMethod(intc InterceptorMethod, when When)
Install an interceptor method that applies to its own Controller.
func (c AppController) example() revel.Result func (c *AppController) example() revel.Result
func InterceptorFilter ¶
func InterceptorFilter(c *Controller, fc []Filter)
func Message ¶
Perform a message look-up for the given locale and message using the given arguments.
When either an unknown locale or message is detected, a specially formatted string is returned.
func MessageLanguages ¶
func MessageLanguages() []string
Return all currently loaded message languages.
func MustReadLines ¶
Reads the lines of the given file. Panics in the case of error.
func OnAppStart ¶
func OnAppStart(f func())
Register a function to be run at app startup.
The order you register the functions will be the order they are run. You can think of it as a FIFO queue. This process will happen after the config file is read and before the server is listening for connections.
Ideally, your application should have only one call to init() in the file init.go. The reason being that the call order of multiple init() functions in the same package is undefined. Inside of init() call revel.OnAppStart() for each function you wish to register.
Example:
// from: yourapp/app/controllers/somefile.go func InitDB() { // do DB connection stuff here } func FillCache() { // fill a cache from DB // this depends on InitDB having been run } // from: yourapp/app/init.go func init() { // set up filters... // register startup functions revel.OnAppStart(InitDB) revel.OnAppStart(FillCache) }
This can be useful when you need to establish connections to databases or third-party services, setup app components, compile assets, or any thing you need to do between starting Revel and accepting connections.
func PanicFilter ¶
func PanicFilter(c *Controller, fc []Filter)
PanicFilter wraps the action invocation in a protective defer blanket that converts panics into 500 error pages.
func ParamsFilter ¶
func ParamsFilter(c *Controller, fc []Filter)
func ParseKeyValueCookie ¶
Takes the raw (escaped) cookie value and parses out key values.
func ParseParams ¶
func RegisterController ¶
func RegisterController(c interface{}, methods []*MethodType)
Register a Controller and its Methods with Revel.
func ResolveContentType ¶
Get the content type. e.g. From "multipart/form-data; boundary=--" to "multipart/form-data" If none is specified, returns "text/html" by default.
func ResolveFormat ¶
ResolveFormat maps the request's Accept MIME type declaration to a Request.Format attribute, specifically "html", "xml", "json", or "txt", returning a default of "html" when Accept header cannot be mapped to a value above.
func ResolveImportPath ¶
ResolveImportPath returns the filesystem path for the given import path. Returns an error if the import path could not be found.
func ReverseUrl ¶
Return a url capable of invoking a given controller method: "Application.ShowApp 123" => "/app/123"
func RouterFilter ¶
func RouterFilter(c *Controller, fc []Filter)
func Run ¶
func Run(port int)
Run the server. This is called from the generated main file. If port is non-zero, use that. Else, read the port from app.conf.
func SessionFilter ¶
func SessionFilter(c *Controller, fc []Filter)
SessionFilter is a Revel Filter that retrieves and sets the session cookie. Within Revel, it is available as a Session attribute on Controller instances. The name of the Session cookie is set as CookiePrefix + "_SESSION".
func Sign ¶
Sign a given string with the app-configured secret key. If no secret key is set, returns the empty string. Return the signature in base64 (URLEncoding).
func ValidationFilter ¶
func ValidationFilter(c *Controller, fc []Filter)
Revel Filter function to be hooked into the filter chain.
Types ¶
type AcceptLanguage ¶
AcceptLanguage is a single language from the Accept-Language HTTP header.
type AcceptLanguages ¶
type AcceptLanguages []AcceptLanguage
AcceptLanguages is collection of sortable AcceptLanguage instances.
func ResolveAcceptLanguage ¶
func ResolveAcceptLanguage(req *http.Request) AcceptLanguages
ResolveAcceptLanguage returns a sorted list of Accept-Language header values.
The results are sorted using the quality defined in the header for each language range with the most qualified language range as the first element in the slice.
See the HTTP header fields specification (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4) for more details.
func (AcceptLanguages) Len ¶
func (al AcceptLanguages) Len() int
func (AcceptLanguages) Less ¶
func (al AcceptLanguages) Less(i, j int) bool
func (AcceptLanguages) String ¶
func (al AcceptLanguages) String() string
func (AcceptLanguages) Swap ¶
func (al AcceptLanguages) Swap(i, j int)
type ActionDefinition ¶
func (*ActionDefinition) String ¶
func (a *ActionDefinition) String() string
type BinaryResult ¶
type BinaryResult struct { Reader io.Reader Name string Length int64 Delivery ContentDisposition ModTime time.Time }
func (*BinaryResult) Apply ¶
func (r *BinaryResult) Apply(req *Request, resp *Response)
type Binder ¶
type Binder struct { // Bind takes the name and type of the desired parameter and constructs it // from one or more values from Params. // // Example // // Request: // url?id=123&ol[0]=1&ol[1]=2&ul[]=str&ul[]=array&user.Name=rob // // Action: // Example.Action(id int, ol []int, ul []string, user User) // // Calls: // Bind(params, "id", int): 123 // Bind(params, "ol", []int): {1, 2} // Bind(params, "ul", []string): {"str", "array"} // Bind(params, "user", User): User{Name:"rob"} // // Note that only exported struct fields may be bound. Bind func(params *Params, name string, typ reflect.Type) reflect.Value // Unbind serializes a given value to one or more URL parameters of the given // name. Unbind func(output map[string]string, name string, val interface{}) }
A Binder translates between string parameters and Go data structures.
type CompressResponseWriter ¶
type CompressResponseWriter struct { http.ResponseWriter // contains filtered or unexported fields }
func (*CompressResponseWriter) DetectCompressionType ¶
func (c *CompressResponseWriter) DetectCompressionType(req *Request, resp *Response)
func (*CompressResponseWriter) Write ¶
func (c *CompressResponseWriter) Write(b []byte) (int, error)
func (*CompressResponseWriter) WriteHeader ¶
func (c *CompressResponseWriter) WriteHeader(status int)
type ContentDisposition ¶
type ContentDisposition string
var ( Attachment ContentDisposition = "attachment" Inline ContentDisposition = "inline" )
type Controller ¶
type Controller struct { Name string // The controller name, e.g. "Application" Type *ControllerType // A description of the controller type. MethodName string // The method name, e.g. "Index" MethodType *MethodType // A description of the invoked action type. AppController interface{} // The controller that was instantiated. Action string // The fully qualified action name, e.g. "App.Index" Request *Request Response *Response Result Result Flash Flash // User cookie, cleared after 1 request. Session Session // Session, stored in cookie, signed. Params *Params // Parameters from URL and form (including multipart). Args map[string]interface{} // Per-request scratch space. RenderArgs map[string]interface{} // Args passed to the template. Validation *Validation // Data validation helpers }
func NewController ¶
func NewController(req *Request, resp *Response) *Controller
func (*Controller) FlashParams ¶
func (c *Controller) FlashParams()
FlashParams serializes the contents of Controller.Params to the Flash cookie.
func (*Controller) Forbidden ¶
func (c *Controller) Forbidden(msg string, objs ...interface{}) Result
Forbidden returns an HTTP 403 Forbidden response whose body is the formatted string of msg and objs.
func (*Controller) Message ¶
func (c *Controller) Message(message string, args ...interface{}) (value string)
Perform a message lookup for the given message name using the given arguments using the current language defined for this controller.
The current language is set by the i18n plugin.
func (*Controller) NotFound ¶
func (c *Controller) NotFound(msg string, objs ...interface{}) Result
NotFound returns an HTTP 404 Not Found response whose body is the formatted string of msg and objs.
func (*Controller) Redirect ¶
func (c *Controller) Redirect(val interface{}, args ...interface{}) Result
Redirect to an action or to a URL.
c.Redirect(Controller.Action) c.Redirect("/controller/action") c.Redirect("/controller/%d/action", id)
func (*Controller) Render ¶
func (c *Controller) Render(extraRenderArgs ...interface{}) Result
Render a template corresponding to the calling Controller method. Arguments will be added to c.RenderArgs prior to rendering the template. They are keyed on their local identifier.
For example:
func (c Users) ShowUser(id int) revel.Result { user := loadUser(id) return c.Render(user) }
This action will render views/Users/ShowUser.html, passing in an extra key-value "user": (User).
func (*Controller) RenderBinary ¶
func (c *Controller) RenderBinary(memfile io.Reader, filename string, delivery ContentDisposition, modtime time.Time) Result
RenderBinary is like RenderFile() except that it instead of a file on disk, it renders data from memory (which could be a file that has not been written, the output from some function, or bytes streamed from somewhere else, as long it implements io.Reader). When called directly on something generated or streamed, modtime should mostly likely be time.Now().
func (*Controller) RenderError ¶
func (c *Controller) RenderError(err error) Result
func (*Controller) RenderFile ¶
func (c *Controller) RenderFile(file *os.File, delivery ContentDisposition) Result
RenderFile returns a file, either displayed inline or downloaded as an attachment. The name and size are taken from the file info.
func (*Controller) RenderHtml ¶
func (c *Controller) RenderHtml(html string) Result
Render html in response
func (*Controller) RenderJson ¶
func (c *Controller) RenderJson(o interface{}) Result
Uses encoding/json.Marshal to return JSON to the client.
func (*Controller) RenderJsonP ¶
func (c *Controller) RenderJsonP(callback string, o interface{}) Result
Renders a JSONP result using encoding/json.Marshal
func (*Controller) RenderTemplate ¶
func (c *Controller) RenderTemplate(templatePath string) Result
A less magical way to render a template. Renders the given template, using the current RenderArgs.
func (*Controller) RenderText ¶
func (c *Controller) RenderText(text string, objs ...interface{}) Result
Render plaintext in response, printf style.
func (*Controller) RenderXml ¶
func (c *Controller) RenderXml(o interface{}) Result
Uses encoding/xml.Marshal to return XML to the client.
func (*Controller) SetAction ¶
func (c *Controller) SetAction(controllerName, methodName string) error
SetAction sets the action that is being invoked in the current request. It sets the following properties: Name, Action, Type, MethodType
func (*Controller) SetCookie ¶
func (c *Controller) SetCookie(cookie *http.Cookie)
func (*Controller) Todo ¶
func (c *Controller) Todo() Result
Todo returns an HTTP 501 Not Implemented "todo" indicating that the action isn't done yet.
type ControllerType ¶
type ControllerType struct { Type reflect.Type Methods []*MethodType ControllerIndexes [][]int // FieldByIndex to all embedded *Controllers }
func (*ControllerType) Method ¶
func (ct *ControllerType) Method(name string) *MethodType
Method searches for a given exported method (case insensitive)
type DiscerningListener ¶
type DiscerningListener interface { Listener WatchDir(info os.FileInfo) bool WatchFile(basename string) bool }
DiscerningListener allows the receiver to selectively watch files.
type Email ¶
type Email struct {
Match
}
func VaildEmail ¶
func VaildEmail() Email
func (Email) DefaultMessage ¶
type Error ¶
type Error struct { SourceType string // The type of source that failed to build. Title, Path, Description string // Description of the error, as presented to the user. Line, Column int // Where the error was encountered. SourceLines []string // The entire source file, split into lines. Stack string // The raw stack trace string from debug.Stack(). MetaError string // Error that occurred producing the error page. }
An error description, used as an argument to the error template.
func NewErrorFromPanic ¶
func NewErrorFromPanic(err interface{}) *Error
Find the deepest stack from in user code and provide a code listing of that, on the line that eventually triggered the panic. Returns nil if no relevant stack frame can be found.
func (*Error) ContextSource ¶
func (e *Error) ContextSource() []sourceLine
Returns a snippet of the source around where the error occurred.
type ErrorResult ¶
This result handles all kinds of error codes (500, 404, ..). It renders the relevant error page (errors/CODE.format, e.g. errors/500.json). If RunMode is "dev", this results in a friendly error page.
func (ErrorResult) Apply ¶
func (r ErrorResult) Apply(req *Request, resp *Response)
type ExecutableTemplate ¶
Add some more methods to the default Template.
type Field ¶
type Field struct { Name string Error *ValidationError // contains filtered or unexported fields }
Field represents a data field that may be collected in a web form.
func (*Field) ErrorClass ¶
ErrorClass returns ERROR_CLASS if this field has a validation error, else empty string.
func (*Field) FlashArray ¶
FlashArray returns the flashed value of this Field as a list split on comma.
type Filter ¶
type Filter func(c *Controller, filterChain []Filter)
type FilterConfigurator ¶
type FilterConfigurator struct {
// contains filtered or unexported fields
}
FilterConfigurator allows the developer configure the filter chain on a per-controller or per-action basis. The filter configuration is applied by the FilterConfiguringFilter, which is itself a filter stage. For example,
Assuming:
Filters = []Filter{ RouterFilter, FilterConfiguringFilter, SessionFilter, ActionInvoker, }
Add:
FilterAction(App.Action). Add(OtherFilter) => RouterFilter, FilterConfiguringFilter, SessionFilter, OtherFilter, ActionInvoker
Remove:
FilterAction(App.Action). Remove(SessionFilter) => RouterFilter, FilterConfiguringFilter, OtherFilter, ActionInvoker
Insert:
FilterAction(App.Action). Insert(OtherFilter, revel.BEFORE, SessionFilter) => RouterFilter, FilterConfiguringFilter, OtherFilter, SessionFilter, ActionInvoker
Filter modifications may be combined between Controller and Action. For example:
FilterController(App{}). Add(Filter1) FilterAction(App.Action). Add(Filter2) .. would result in App.Action being filtered by both Filter1 and Filter2.
Note: the last filter stage is not subject to the configurator. In particular, Add() adds a filter to the second-to-last place.
func FilterAction ¶
func FilterAction(methodRef interface{}) FilterConfigurator
FilterAction returns a configurator for the filters applied to the given controller method. For example:
FilterAction(MyController.MyAction)
func FilterController ¶
func FilterController(controllerInstance interface{}) FilterConfigurator
FilterController returns a configurator for the filters applied to all actions on the given controller instance. For example:
FilterAction(MyController{})
func (FilterConfigurator) Add ¶
func (conf FilterConfigurator) Add(f Filter) FilterConfigurator
Add the given filter in the second-to-last position in the filter chain. (Second-to-last so that it is before ActionInvoker)
func (FilterConfigurator) Insert ¶
func (conf FilterConfigurator) Insert(insert Filter, where When, target Filter) FilterConfigurator
Insert a filter into the filter chain before or after another. This may be called with the BEFORE or AFTER constants, for example:
revel.FilterAction(App.Index). Insert(MyFilter, revel.BEFORE, revel.ActionInvoker). Insert(MyFilter2, revel.AFTER, revel.PanicFilter)
func (FilterConfigurator) Remove ¶
func (conf FilterConfigurator) Remove(target Filter) FilterConfigurator
Remove a filter from the filter chain.
type Flash ¶
Flash represents a cookie that is overwritten on each request. It allows data to be stored across one page at a time. This is commonly used to implement success or error messages. E.g. the Post/Redirect/Get pattern: http://en.wikipedia.org/wiki/Post/Redirect/Get
type GoTemplate ¶
Adapter for Go Templates.
func (GoTemplate) Content ¶
func (gotmpl GoTemplate) Content() []string
type Interception ¶
type Interception struct { When When // contains filtered or unexported fields }
type InterceptorFunc ¶
type InterceptorFunc func(*Controller) Result
An "interceptor" is functionality invoked by the framework BEFORE or AFTER an action.
An interceptor may optionally return a Result (instead of nil). Depending on when the interceptor was invoked, the response is different: 1. BEFORE: No further interceptors are invoked, and neither is the action. 2. AFTER: Further interceptors are still run. In all cases, any returned Result will take the place of any existing Result.
In the BEFORE case, that returned Result is guaranteed to be final, while in the AFTER case it is possible that a further interceptor could emit its own Result.
Interceptors are called in the order that they are added.
***
Two types of interceptors are provided: Funcs and Methods
Func Interceptors may apply to any / all Controllers.
func example(*revel.Controller) revel.Result
Method Interceptors are provided so that properties can be set on application controllers.
func (c AppController) example() revel.Result func (c *AppController) example() revel.Result
type InterceptorMethod ¶
type InterceptorMethod interface{}
type Length ¶
type Length struct {
N int
}
Requires an array or string to be exactly a given length.
func ValidLength ¶
func (Length) DefaultMessage ¶
func (Length) IsSatisfied ¶
type Listener ¶
type Listener interface { // Refresh is invoked by the watcher on relevant filesystem events. // If the listener returns an error, it is served to the user on the current request. Refresh() *Error }
Listener is an interface for receivers of filesystem events.
type Match ¶
Requires a string to match a given regex.
func ValidMatch ¶
func (Match) DefaultMessage ¶
func (Match) IsSatisfied ¶
type MaxSize ¶
type MaxSize struct {
Max int
}
Requires an array or string to be at most a given length.
func ValidMaxSize ¶
func (MaxSize) DefaultMessage ¶
func (MaxSize) IsSatisfied ¶
type MergedConfig ¶
type MergedConfig struct {
// contains filtered or unexported fields
}
This handles the parsing of app.conf It has a "preferred" section that is checked first for option queries. If the preferred section does not have the option, the DEFAULT section is checked fallback.
func LoadConfig ¶
func LoadConfig(confName string) (*MergedConfig, error)
func (*MergedConfig) Bool ¶
func (c *MergedConfig) Bool(option string) (result, found bool)
func (*MergedConfig) BoolDefault ¶
func (c *MergedConfig) BoolDefault(option string, dfault bool) bool
func (*MergedConfig) HasSection ¶
func (c *MergedConfig) HasSection(section string) bool
func (*MergedConfig) IntDefault ¶
func (c *MergedConfig) IntDefault(option string, dfault int) int
func (*MergedConfig) Options ¶
func (c *MergedConfig) Options(prefix string) []string
Options returns all configuration option keys. If a prefix is provided, then that is applied as a filter.
func (*MergedConfig) Raw ¶
func (c *MergedConfig) Raw() *config.Config
func (*MergedConfig) SetOption ¶
func (c *MergedConfig) SetOption(name, value string)
func (*MergedConfig) SetSection ¶
func (c *MergedConfig) SetSection(section string)
func (*MergedConfig) String ¶
func (c *MergedConfig) String(option string) (result string, found bool)
func (*MergedConfig) StringDefault ¶
func (c *MergedConfig) StringDefault(option, dfault string) string
type MethodType ¶
type MinSize ¶
type MinSize struct {
Min int
}
Requires an array or string to be at least a given length.
func ValidMinSize ¶
func (MinSize) DefaultMessage ¶
func (MinSize) IsSatisfied ¶
type Module ¶
type Module struct {
Name, ImportPath, Path string
}
func ModuleByName ¶
ModuleByName returns the module of the given name, if loaded.
type Params ¶
type Params struct { url.Values // A unified view of all the individual param maps below. // Set by the router Fixed url.Values // Fixed parameters from the route, e.g. App.Action("fixed param") Route url.Values // Parameters extracted from the route, e.g. /customers/{id} // Set by the ParamsFilter Query url.Values // Parameters from the query string, e.g. /index?limit=10 Form url.Values // Parameters from the request body. Files map[string][]*multipart.FileHeader // Files uploaded in a multipart form // contains filtered or unexported fields }
Params provides a unified view of the request params. Includes: - URL query string - Form values - File uploads
Warning: param maps other than Values may be nil if there were none.
type PlaintextErrorResult ¶
type PlaintextErrorResult struct {
Error error
}
func (PlaintextErrorResult) Apply ¶
func (r PlaintextErrorResult) Apply(req *Request, resp *Response)
This method is used when the template loader or error template is not available.
type Range ¶
Requires an integer to be within Min, Max inclusive.
func ValidRange ¶
func (Range) DefaultMessage ¶
func (Range) IsSatisfied ¶
type RedirectToActionResult ¶
type RedirectToActionResult struct {
// contains filtered or unexported fields
}
func (*RedirectToActionResult) Apply ¶
func (r *RedirectToActionResult) Apply(req *Request, resp *Response)
type RedirectToUrlResult ¶
type RedirectToUrlResult struct {
// contains filtered or unexported fields
}
func (*RedirectToUrlResult) Apply ¶
func (r *RedirectToUrlResult) Apply(req *Request, resp *Response)
type RenderHtmlResult ¶
type RenderHtmlResult struct {
// contains filtered or unexported fields
}
func (RenderHtmlResult) Apply ¶
func (r RenderHtmlResult) Apply(req *Request, resp *Response)
type RenderJsonResult ¶
type RenderJsonResult struct {
// contains filtered or unexported fields
}
func (RenderJsonResult) Apply ¶
func (r RenderJsonResult) Apply(req *Request, resp *Response)
type RenderTemplateResult ¶
Action methods return this result to request a template be rendered.
func (*RenderTemplateResult) Apply ¶
func (r *RenderTemplateResult) Apply(req *Request, resp *Response)
type RenderTextResult ¶
type RenderTextResult struct {
// contains filtered or unexported fields
}
func (RenderTextResult) Apply ¶
func (r RenderTextResult) Apply(req *Request, resp *Response)
type RenderXmlResult ¶
type RenderXmlResult struct {
// contains filtered or unexported fields
}
func (RenderXmlResult) Apply ¶
func (r RenderXmlResult) Apply(req *Request, resp *Response)
type Request ¶
type Request struct { *http.Request ContentType string Format string // "html", "xml", "json", or "txt" AcceptLanguages AcceptLanguages Locale string Websocket *websocket.Conn }
func NewRequest ¶
type Required ¶
type Required struct{}
func ValidRequired ¶
func ValidRequired() Required
func (Required) DefaultMessage ¶
func (Required) IsSatisfied ¶
type Response ¶
type Response struct { Status int ContentType string Out http.ResponseWriter }
func NewResponse ¶
func NewResponse(w http.ResponseWriter) *Response
func (*Response) WriteHeader ¶
Write the header (for now, just the status code). The status may be set directly by the application (c.Response.Status = 501). if it isn't, then fall back to the provided status code.
type Route ¶
type Route struct { Method string // e.g. GET Path string // e.g. /app/:id Action string // e.g. "Application.ShowApp", "404" ControllerName string // e.g. "Application", "" MethodName string // e.g. "ShowApp", "" FixedParams []string // e.g. "arg1","arg2","arg3" (CSV formatting) TreePath string // e.g. "/GET/app/:id" // contains filtered or unexported fields }
type RouteMatch ¶
type Router ¶
type Router struct { Routes []*Route Tree *pathtree.Node // contains filtered or unexported fields }
func (*Router) Refresh ¶
Refresh re-reads the routes file and re-calculates the routing table. Returns an error if a specified action could not be found.
type Session ¶
A signed cookie (and thus limited to 4kb in size). Restriction: Keys may not have a colon in them.
func (Session) Id ¶
Id retrieves from the cookie or creates a time-based UUID identifying this session.
func (Session) SetDefaultExpiration ¶
func (s Session) SetDefaultExpiration()
SetDefaultExpiration sets session to expire after default duration
func (Session) SetNoExpiration ¶
func (s Session) SetNoExpiration()
SetNoExpiration sets session to expire when browser session ends
type TemplateLoader ¶
type TemplateLoader struct {
// contains filtered or unexported fields
}
This object handles loading and parsing of templates. Everything below the application's views directory is treated as a template.
func NewTemplateLoader ¶
func NewTemplateLoader(paths []string) *TemplateLoader
func (*TemplateLoader) Refresh ¶
func (loader *TemplateLoader) Refresh() *Error
This scans the views directory and parses all templates as Go Templates. If a template fails to parse, the error is set on the loader. (It's awkward to refresh a single Go Template)
func (*TemplateLoader) Template ¶
func (loader *TemplateLoader) Template(name string) (Template, error)
Return the Template with the given name. The name is the template's path relative to a template loader root.
An Error is returned if there was any problem with any of the templates. (In this case, if a template is returned, it may still be usable.)
func (*TemplateLoader) WatchFile ¶
func (loader *TemplateLoader) WatchFile(basename string) bool
type TestSuite ¶
type TestSuite struct { Client *http.Client Response *http.Response ResponseBody []byte Session Session }
func NewTestSuite ¶
func NewTestSuite() TestSuite
NewTestSuite returns an initialized TestSuite ready for use. It is invoked by the test harness to initialize the embedded field in application tests.
func (*TestSuite) AssertContains ¶
Assert that the response contains the given string.
func (*TestSuite) AssertContainsRegex ¶
Assert that the response matches the given regular expression.BUG
func (*TestSuite) AssertContentType ¶
func (*TestSuite) AssertEqual ¶
func (t *TestSuite) AssertEqual(expected, actual interface{})
func (*TestSuite) AssertHeader ¶
func (*TestSuite) AssertNotFound ¶
func (t *TestSuite) AssertNotFound()
func (*TestSuite) AssertStatus ¶
func (*TestSuite) BaseUrl ¶
Return the base http/https URL of the server, e.g. "http://127.0.0.1:8557". The scheme is set to https if http.ssl is set to true in the configuration file.
func (*TestSuite) Delete ¶
Issue a DELETE request to the given path and store the result in Request and RequestBody.
func (*TestSuite) Get ¶
Issue a GET request to the given path and store the result in Request and RequestBody.
func (*TestSuite) MakeRequest ¶
Issue any request and read the response. If successful, the caller may examine the Response and ResponseBody properties. You will need to manage session / cookie data manually
func (*TestSuite) MakeRequestSession ¶
Issue any request and read the response. If successful, the caller may examine the Response and ResponseBody properties. Session data will be added to the request cookies for you.
func (*TestSuite) Post ¶
Issue a POST request to the given path, sending the given Content-Type and data, and store the result in Request and RequestBody. "data" may be nil.
func (*TestSuite) PostForm ¶
Issue a POST request to the given path as a form post of the given key and values, and store the result in Request and RequestBody.
func (*TestSuite) WebSocket ¶
Create a websocket connection to the given path and return the connection
func (*TestSuite) WebSocketUrl ¶
Return the base websocket URL of the server, e.g. "ws://127.0.0.1:8557"
type Validation ¶
type Validation struct { Errors []*ValidationError // contains filtered or unexported fields }
A Validation context manages data validation and error messages.
func (*Validation) Check ¶
func (v *Validation) Check(obj interface{}, checks ...Validator) *ValidationResult
Apply a group of validators to a field, in order, and return the ValidationResult from the first one that fails, or the last one that succeeds.
func (*Validation) Email ¶
func (v *Validation) Email(str string) *ValidationResult
func (*Validation) Error ¶
func (v *Validation) Error(message string, args ...interface{}) *ValidationResult
Error adds an error to the validation context.
func (*Validation) ErrorMap ¶
func (v *Validation) ErrorMap() map[string]*ValidationError
ErrorMap returns the errors mapped by key. If there are multiple validation errors associated with a single key, the first one "wins". (Typically the first validation will be the more basic).
func (*Validation) HasErrors ¶
func (v *Validation) HasErrors() bool
HasErrors returns true if there are any (ie > 0) errors. False otherwise.
func (*Validation) Keep ¶
func (v *Validation) Keep()
Keep tells revel to set a flash cookie on the client to make the validation errors available for the next request. This is helpful when redirecting the client after the validation failed. It is good practice to always redirect upon a HTTP POST request. Thus one should use this method when HTTP POST validation failed and redirect the user back to the form.
func (*Validation) Length ¶
func (v *Validation) Length(obj interface{}, n int) *ValidationResult
func (*Validation) Match ¶
func (v *Validation) Match(str string, regex *regexp.Regexp) *ValidationResult
func (*Validation) Max ¶
func (v *Validation) Max(n int, max int) *ValidationResult
func (*Validation) MaxSize ¶
func (v *Validation) MaxSize(obj interface{}, max int) *ValidationResult
func (*Validation) Min ¶
func (v *Validation) Min(n int, min int) *ValidationResult
func (*Validation) MinSize ¶
func (v *Validation) MinSize(obj interface{}, min int) *ValidationResult
func (*Validation) Range ¶
func (v *Validation) Range(n, min, max int) *ValidationResult
func (*Validation) Required ¶
func (v *Validation) Required(obj interface{}) *ValidationResult
Required tests that the argument is non-nil and non-empty (if string or list)
type ValidationError ¶
type ValidationError struct {
Message, Key string
}
Simple struct to store the Message & Key of a validation error
func (*ValidationError) String ¶
func (e *ValidationError) String() string
String returns the Message field of the ValidationError struct.
type ValidationResult ¶
type ValidationResult struct { Error *ValidationError Ok bool }
A ValidationResult is returned from every validation method. It provides an indication of success, and a pointer to the Error (if any).
func (*ValidationResult) Key ¶
func (r *ValidationResult) Key(key string) *ValidationResult
Key sets the ValidationResult's Error "key" and returns itself for chaining
func (*ValidationResult) Message ¶
func (r *ValidationResult) Message(message string, args ...interface{}) *ValidationResult
Message sets the error message for a ValidationResult. Returns itself to allow chaining. Allows Sprintf() type calling with multiple parameters
type Watcher ¶
type Watcher struct {
// contains filtered or unexported fields
}
Watcher allows listeners to register to be notified of changes under a given directory.
func NewWatcher ¶
func NewWatcher() *Watcher
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
modules
|
|
db/app
This module configures a database connection for the application.
|
This module configures a database connection for the application. |
jobs/app/jobs
A job runner for executing scheduled or ad-hoc tasks asynchronously from HTTP requests.
|
A job runner for executing scheduled or ad-hoc tasks asynchronously from HTTP requests. |
The command line tool for running Revel apps.
|
The command line tool for running Revel apps. |
samples
|
|
skeleton
|
|