mirror of
https://github.com/labstack/echo.git
synced 2025-04-21 12:17:04 +02:00
parent
c020919cb4
commit
5a71f202f5
58
context.go
58
context.go
@ -11,6 +11,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"golang.org/x/net/websocket"
|
"golang.org/x/net/websocket"
|
||||||
|
"bytes"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -110,68 +111,99 @@ func (c *Context) Bind(i interface{}) error {
|
|||||||
|
|
||||||
// Render renders a template with data and sends a text/html response with status
|
// Render renders a template with data and sends a text/html response with status
|
||||||
// code. Templates can be registered using `Echo.SetRenderer()`.
|
// code. Templates can be registered using `Echo.SetRenderer()`.
|
||||||
func (c *Context) Render(code int, name string, data interface{}) error {
|
func (c *Context) Render(code int, name string, data interface{}) (err error) {
|
||||||
if c.echo.renderer == nil {
|
if c.echo.renderer == nil {
|
||||||
return RendererNotRegistered
|
return RendererNotRegistered
|
||||||
}
|
}
|
||||||
|
buf := new (bytes.Buffer)
|
||||||
|
if err = c.echo.renderer.Render(buf, name, data); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
c.response.Header().Set(ContentType, TextHTMLCharsetUTF8)
|
c.response.Header().Set(ContentType, TextHTMLCharsetUTF8)
|
||||||
c.response.WriteHeader(code)
|
c.response.WriteHeader(code)
|
||||||
return c.echo.renderer.Render(c.response, name, data)
|
c.response.Write(buf.Bytes())
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTML formats according to a format specifier and sends HTML response with
|
// HTML formats according to a format specifier and sends HTML response with
|
||||||
// status code.
|
// status code.
|
||||||
func (c *Context) HTML(code int, format string, a ...interface{}) (err error) {
|
func (c *Context) HTML(code int, format string, a ...interface{}) (err error) {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
_, err = fmt.Fprintf(buf, format, a...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
c.response.Header().Set(ContentType, TextHTMLCharsetUTF8)
|
c.response.Header().Set(ContentType, TextHTMLCharsetUTF8)
|
||||||
c.response.WriteHeader(code)
|
c.response.WriteHeader(code)
|
||||||
_, err = fmt.Fprintf(c.response, format, a...)
|
c.response.Write(buf.Bytes())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// String formats according to a format specifier and sends text response with status
|
// String formats according to a format specifier and sends text response with status
|
||||||
// code.
|
// code.
|
||||||
func (c *Context) String(code int, format string, a ...interface{}) (err error) {
|
func (c *Context) String(code int, format string, a ...interface{}) (err error) {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
_, err = fmt.Fprintf(buf, format, a...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
c.response.Header().Set(ContentType, TextPlain)
|
c.response.Header().Set(ContentType, TextPlain)
|
||||||
c.response.WriteHeader(code)
|
c.response.WriteHeader(code)
|
||||||
_, err = fmt.Fprintf(c.response, format, a...)
|
c.response.Write(buf.Bytes())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON sends a JSON response with status code.
|
// JSON sends a JSON response with status code.
|
||||||
func (c *Context) JSON(code int, i interface{}) error {
|
func (c *Context) JSON(code int, i interface{}) (err error) {
|
||||||
|
b, err := json.Marshal(i)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
c.response.Header().Set(ContentType, ApplicationJSONCharsetUTF8)
|
c.response.Header().Set(ContentType, ApplicationJSONCharsetUTF8)
|
||||||
c.response.WriteHeader(code)
|
c.response.WriteHeader(code)
|
||||||
return json.NewEncoder(c.response).Encode(i)
|
c.response.Write(b)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONP sends a JSONP response with status code. It uses `callback` to construct
|
// JSONP sends a JSONP response with status code. It uses `callback` to construct
|
||||||
// the JSONP payload.
|
// the JSONP payload.
|
||||||
func (c *Context) JSONP(code int, callback string, i interface{}) (err error) {
|
func (c *Context) JSONP(code int, callback string, i interface{}) (err error) {
|
||||||
|
b, err := json.Marshal(i)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
c.response.Header().Set(ContentType, ApplicationJavaScriptCharsetUTF8)
|
c.response.Header().Set(ContentType, ApplicationJavaScriptCharsetUTF8)
|
||||||
c.response.WriteHeader(code)
|
c.response.WriteHeader(code)
|
||||||
c.response.Write([]byte(callback + "("))
|
c.response.Write([]byte(callback + "("))
|
||||||
if err = json.NewEncoder(c.response).Encode(i); err == nil {
|
c.response.Write(b)
|
||||||
c.response.Write([]byte(");"))
|
c.response.Write([]byte(");"))
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// XML sends an XML response with status code.
|
// XML sends an XML response with status code.
|
||||||
func (c *Context) XML(code int, i interface{}) error {
|
func (c *Context) XML(code int, i interface{}) (err error) {
|
||||||
|
b, err := xml.Marshal(i)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
c.response.Header().Set(ContentType, ApplicationXMLCharsetUTF8)
|
c.response.Header().Set(ContentType, ApplicationXMLCharsetUTF8)
|
||||||
c.response.WriteHeader(code)
|
c.response.WriteHeader(code)
|
||||||
c.response.Write([]byte(xml.Header))
|
c.response.Write([]byte(xml.Header))
|
||||||
return xml.NewEncoder(c.response).Encode(i)
|
c.response.Write(b)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// File sends a response with the content of the file. If attachment is true, the
|
// File sends a response with the content of the file. If attachment is true, the
|
||||||
// client is prompted to save the file.
|
// client is prompted to save the file.
|
||||||
func (c *Context) File(name string, attachment bool) error {
|
func (c *Context) File(name string, attachment bool) (err error) {
|
||||||
dir, file := path.Split(name)
|
dir, file := path.Split(name)
|
||||||
if attachment {
|
if attachment {
|
||||||
c.response.Header().Set(ContentDisposition, "attachment; filename="+file)
|
c.response.Header().Set(ContentDisposition, "attachment; filename="+file)
|
||||||
}
|
}
|
||||||
return serveFile(dir, file, c)
|
if err = serveFile(dir, file, c); err != nil {
|
||||||
|
c.response.Header().Del(ContentDisposition)
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoContent sends a response with no body and a status code.
|
// NoContent sends a response with no body and a status code.
|
||||||
|
@ -94,7 +94,7 @@ func TestContext(t *testing.T) {
|
|||||||
if assert.NoError(t, err) {
|
if assert.NoError(t, err) {
|
||||||
assert.Equal(t, http.StatusOK, rec.Code)
|
assert.Equal(t, http.StatusOK, rec.Code)
|
||||||
assert.Equal(t, ApplicationJSONCharsetUTF8, rec.Header().Get(ContentType))
|
assert.Equal(t, ApplicationJSONCharsetUTF8, rec.Header().Get(ContentType))
|
||||||
assert.Equal(t, userJSON+"\n", rec.Body.String())
|
assert.Equal(t, userJSON, rec.Body.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONP
|
// JSONP
|
||||||
@ -105,7 +105,7 @@ func TestContext(t *testing.T) {
|
|||||||
if assert.NoError(t, err) {
|
if assert.NoError(t, err) {
|
||||||
assert.Equal(t, http.StatusOK, rec.Code)
|
assert.Equal(t, http.StatusOK, rec.Code)
|
||||||
assert.Equal(t, ApplicationJavaScriptCharsetUTF8, rec.Header().Get(ContentType))
|
assert.Equal(t, ApplicationJavaScriptCharsetUTF8, rec.Header().Get(ContentType))
|
||||||
assert.Equal(t, callback+"("+userJSON+"\n);", rec.Body.String())
|
assert.Equal(t, callback+"("+userJSON+");", rec.Body.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// XML
|
// XML
|
||||||
|
@ -6,13 +6,13 @@
|
|||||||
"menu": {
|
"menu": {
|
||||||
"main": [{
|
"main": [{
|
||||||
"Name": "Guide",
|
"Name": "Guide",
|
||||||
"Pre": "<i class='fa fa-heart'></i>",
|
"Pre": "<i class='fa fa-book'></i>",
|
||||||
"Weight": -110,
|
"Weight": -110,
|
||||||
"Identifier": "guide",
|
"Identifier": "guide",
|
||||||
"URL": "guide"
|
"URL": "guide"
|
||||||
}, {
|
}, {
|
||||||
"Name": "Recipes",
|
"Name": "Recipes",
|
||||||
"Pre": "<i class='fa fa-road'></i>",
|
"Pre": "<i class='fa fa-code'></i>",
|
||||||
"Weight": -100,
|
"Weight": -100,
|
||||||
"Identifier": "recipes",
|
"Identifier": "recipes",
|
||||||
"URL": "recipes"
|
"URL": "recipes"
|
||||||
|
@ -3,6 +3,7 @@ title: Customization
|
|||||||
menu:
|
menu:
|
||||||
main:
|
main:
|
||||||
parent: guide
|
parent: guide
|
||||||
|
weight: 20
|
||||||
---
|
---
|
||||||
|
|
||||||
### HTTP error handler
|
### HTTP error handler
|
||||||
|
@ -3,6 +3,7 @@ title: Error Handling
|
|||||||
menu:
|
menu:
|
||||||
main:
|
main:
|
||||||
parent: guide
|
parent: guide
|
||||||
|
weight: 70
|
||||||
---
|
---
|
||||||
|
|
||||||
Echo advocates centralized HTTP error handling by returning `error` from middleware
|
Echo advocates centralized HTTP error handling by returning `error` from middleware
|
||||||
|
@ -3,6 +3,7 @@ title: Installation
|
|||||||
menu:
|
menu:
|
||||||
main:
|
main:
|
||||||
parent: guide
|
parent: guide
|
||||||
|
weight: 10
|
||||||
---
|
---
|
||||||
|
|
||||||
Echo has been developed and tested using Go `1.4.x`
|
Echo has been developed and tested using Go `1.4.x`
|
||||||
|
@ -3,6 +3,7 @@ title: Middleware
|
|||||||
menu:
|
menu:
|
||||||
main:
|
main:
|
||||||
parent: guide
|
parent: guide
|
||||||
|
weight: 40
|
||||||
---
|
---
|
||||||
|
|
||||||
Middleware is a function which is chained in the HTTP request-response cycle. Middleware
|
Middleware is a function which is chained in the HTTP request-response cycle. Middleware
|
||||||
|
@ -3,6 +3,7 @@ title: Request
|
|||||||
menu:
|
menu:
|
||||||
main:
|
main:
|
||||||
parent: guide
|
parent: guide
|
||||||
|
weight: 50
|
||||||
---
|
---
|
||||||
|
|
||||||
### Path parameter
|
### Path parameter
|
||||||
|
@ -3,6 +3,7 @@ title: Response
|
|||||||
menu:
|
menu:
|
||||||
main:
|
main:
|
||||||
parent: guide
|
parent: guide
|
||||||
|
weight: 60
|
||||||
---
|
---
|
||||||
|
|
||||||
### Template
|
### Template
|
||||||
|
@ -3,6 +3,7 @@ title: Routing
|
|||||||
menu:
|
menu:
|
||||||
main:
|
main:
|
||||||
parent: guide
|
parent: guide
|
||||||
|
weight: 30
|
||||||
---
|
---
|
||||||
|
|
||||||
Echo's router is [fast, optimized](https://github.com/labstack/echo#benchmark) and
|
Echo's router is [fast, optimized](https://github.com/labstack/echo#benchmark) and
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Google App Engine
|
title: Google App Engine
|
||||||
|
draft: true
|
||||||
menu:
|
menu:
|
||||||
main:
|
main:
|
||||||
parent: recipes
|
parent: recipes
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
<!-- Place favicon.ico in the root directory -->
|
<!-- Place favicon.ico in the root directory -->
|
||||||
<link rel="stylesheet" href="//storage.googleapis.com/code.getmdl.io/1.0.5/material.blue-pink.min.css">
|
<link rel="stylesheet" href="//storage.googleapis.com/code.getmdl.io/1.0.5/material.blue-pink.min.css">
|
||||||
<link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons">
|
<link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons">
|
||||||
|
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700">
|
||||||
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
|
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
|
||||||
<link rel="stylesheet" href="{{ .Site.BaseURL }}/styles/monokai.css">
|
<link rel="stylesheet" href="{{ .Site.BaseURL }}/styles/monokai.css">
|
||||||
<link rel="stylesheet" href="{{ .Site.BaseURL }}/styles/echo.css">
|
<link rel="stylesheet" href="{{ .Site.BaseURL }}/styles/echo.css">
|
||||||
|
@ -2,9 +2,14 @@
|
|||||||
<div>
|
<div>
|
||||||
{{ range .Site.Menus.main }}
|
{{ range .Site.Menus.main }}
|
||||||
{{ if .HasChildren }}
|
{{ if .HasChildren }}
|
||||||
<h4>{{ .Name }}</h4>
|
<h4>
|
||||||
|
{{ .Pre }}
|
||||||
|
{{ .Name }}
|
||||||
|
</h4>
|
||||||
{{ range .Children }}
|
{{ range .Children }}
|
||||||
<a href="{{ .URL }}">{{ .Name }}</a>
|
<a href="{{ .URL }}">
|
||||||
|
{{ .Name }}
|
||||||
|
</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"gulp": "^3.8.11",
|
"gulp": "^3.8.11",
|
||||||
"gulp-gh-pages": "^0.5.1",
|
"gulp-gh-pages": "^0.5.1",
|
||||||
"gulp-shell": "^0.4.1"
|
"gulp-shell": "^0.4.1"
|
||||||
}
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"prismjs": "0.0.1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,24 @@
|
|||||||
body {
|
|
||||||
background-color: #efefef;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
padding: 40px 80px !important;
|
padding: 40px 80px !important;
|
||||||
}
|
}
|
||||||
|
code {
|
||||||
|
font-size: .95em;
|
||||||
|
padding: 2px 4px;
|
||||||
|
background: #eee;
|
||||||
|
color: #4d4d4c;
|
||||||
|
font-family: Source Code Pro, Monaco, Menlo, Consolas, monospace;
|
||||||
|
}
|
||||||
a:link {
|
a:link {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-content {
|
.page-content {
|
||||||
padding: 20px 0;
|
padding: 20px 0;
|
||||||
max-width: 960px;
|
max-width: 960px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-content header {
|
.page-content header {
|
||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu a {
|
.menu a {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 2px 0
|
padding: 2px 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user