Skip to content

Commit 41d929f

Browse files
committed
Quickstart start
Signed-off-by: NotZippy <[email protected]>
1 parent 17240b5 commit 41d929f

File tree

15 files changed

+1107
-0
lines changed

15 files changed

+1107
-0
lines changed

_data/quickstart.yml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
- text: Home
2+
url: /quickstart/
3+
- text: Introduction
4+
url: /quickstart/introduction/
5+
subitems:
6+
- text: Concepts
7+
url: /quickstart/introduction/concepts/
8+
- text: Organization
9+
url: /quickstart/introduction/organization/
10+
- text: Controller
11+
url: /quickstart/controller/
12+
subitems:
13+
- text: Overview
14+
url: /quickstart/controller/overview
15+
- text: Input
16+
url: /quickstart/controller/input
17+
subitems:
18+
- text: Routing
19+
url: /quickstart/controller/input/routing
20+
- text: Parameters
21+
url: /quickstart/controller/input/parameters
22+
- text: Returns
23+
url: /quickstart/controller/returns
24+

_includes/nav.html

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{% assign navurl = page.url | remove: 'index.html' %}
2+
<ul>
3+
{% for item in include.nav %}
4+
<li>
5+
<a href="{{ item.url }}">
6+
{% if item.url == navurl %}
7+
<b>{{ item.text }}</b>
8+
{% else %}
9+
{{ item.text }}
10+
{% endif %}
11+
</a>
12+
</li>
13+
{% if item.subitems and navurl contains item.url %}
14+
{% include nav.html nav=item.subitems %}
15+
{% endif %}
16+
{% endfor %}
17+
</ul>

_layouts/quickstart.html

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
{% include head.html %}
5+
<link href="{{ page.root }}/css/manual.css" type="text/css" rel="stylesheet" />
6+
<link href="{{ page.root }}/css/prettify.css" type="text/css" rel="stylesheet" />
7+
<script src="{{ page.root }}/js/prettify.js" type="text/javascript"></script>
8+
<script src="{{ page.root }}/js/lang-go-rich.js" type="text/javascript"></script>
9+
{% include analytics.html %}
10+
</head>
11+
12+
<body onload="prettyPrint()">
13+
14+
{% include topnav.html %}
15+
16+
<div class="container">
17+
<div class="row">
18+
<div class="span2">
19+
{% include nav.html nav=site.data.quickstart %}
20+
</div>
21+
22+
<div class="span10">
23+
<div class="page-header">
24+
<h1>{{ page.title }}</h1>
25+
<a href="https://github.com/revel/revel.github.io/edit/master/{{ page.path }}" class="improve-page btn btn-info" target="_blank">Improve this page</a>
26+
</div>
27+
{{ content }}
28+
</div>
29+
</div>
30+
</div>
31+
</body>
32+
</html>

quickstart/controller/index.md

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
layout: quickstart
3+
title: Controllers
4+
---
5+
6+
A controller is a container for the request actions. You could have every request tied to an action (function) in one controller
7+
but a better practice would be to divide the work up amongst controllers in a logical manner,
8+
refer to the hotel application for an example.
9+
10+
11+
##Coding Rules
12+
Two important rules, the **Controller** must be the first type when defined in a file, the following example the Foo
13+
controller will not be found
14+
15+
type (
16+
Bar struct {
17+
*revel.Controller
18+
}
19+
Foo struct {
20+
*revel.Controller
21+
}
22+
)
23+
24+
Coded properly it would be like this
25+
26+
type (
27+
Bar struct {
28+
*revel.Controller
29+
}
30+
)
31+
type (
32+
Foo struct {
33+
*revel.Controller
34+
}
35+
)
36+
37+
or this
38+
39+
type Bar struct {
40+
*revel.Controller
41+
}
42+
type Foo struct {
43+
*revel.Controller
44+
}
45+
46+
The second rule is that a controller can only exist in a folder called controllers, if you intend to extend all your controllers
47+
from a common one make sure that the common one exists in a folder called controllers as well, or none of your controllers
48+
will be found
49+
50+
##Extending the Controller
51+
A **Controller** is any type that embeds `*revel.Controller` (directly or indirectly).
52+
This means controllers may extend other classes, here is an example on how to do that. Note in the *MyController* the
53+
*BaseController* reference is NOT a pointer
54+
55+
type (
56+
BaseController struct {
57+
*revel.Controller
58+
}
59+
)
60+
type (
61+
MyController struct {
62+
BaseController
63+
}
64+
)

quickstart/controller/input/index.md

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
layout: quickstart
3+
title: Quickstart
4+
---
5+
For a controller there are two components to map a request to an action and to determine how the data is processed
6+
7+
The **[route]({{site.url}}/quickstart/controller/input/routing/index.html)** maps the request to the action, it also
8+
provides url paramater mapping, templates also make use of this file to map a controller action and paramater to
9+
a linkable request.
10+
11+
The **[parameter]({{site.url}}/quickstart/controller/input/parameters/index.html)** or end function point also are
12+
intelligently designed. ie if paramaters are passed in which match the variables name in the function then those objects
13+
will be populated via the paramater(s). This goes beyond simple string and ints, you can also populate structures so
14+
a fully populated form object is achievable with only one input.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
---
2+
layout: quickstart
3+
title: Quickstart
4+
---
5+
Revel tries to make the conversion of parameters into their desired Go types as
6+
easy as possible. This conversion from string to another type is referred to as
7+
"data binding".
8+
9+
## Params
10+
11+
All request parameters are collected into a single `Params` object. That includes:
12+
13+
* URL Path parameters
14+
* URL Query parameters
15+
* Form values (Multipart or not)
16+
* File uploads
17+
18+
This is the definition ([godoc](../docs/godoc/params.html)):
19+
20+
<pre class="prettyprint lang-go">
21+
type Params struct {
22+
url.Values
23+
Files map[string][]*multipart.FileHeader
24+
}
25+
</pre>
26+
27+
The embedded `url.Values` ([godoc](http://www.golang.org/pkg/net/url/#Values))
28+
does provide accessors for simple values, but developers will find it easier to
29+
use Revel's data-binding mechanisms for any non-string values.
30+
31+
## Action arguments
32+
33+
Parameters may be accepted directly as method arguments by the action. For
34+
example:
35+
36+
<pre class="prettyprint lang-go">
37+
func (c AppController) Action(name string, ids []int, user User, img []byte) revel.Result {
38+
...
39+
}
40+
</pre>
41+
42+
Before invoking the action, Revel asks its Binder to convert parameters of those
43+
names to the requested data type. If the binding is unsuccessful for any
44+
reason, the parameter will have the zero value for its type.
45+
46+
## Binder
47+
48+
To bind a parameter to a data type, use Revel's Binder
49+
([godoc](../docs/godoc/binder.html)). It is integrated with the Params object
50+
as the following example shows:
51+
52+
{% raw %}
53+
<pre class="prettyprint lang-go">
54+
func (c SomeController) Action() revel.Result {
55+
var ids []int
56+
c.Params.Bind(&amp;ids, "ids")
57+
...
58+
}
59+
</pre>
60+
{% endraw %}
61+
62+
The following data types are supported out of the box:
63+
64+
* Ints of all widths
65+
* Bools
66+
* Pointers to any supported type
67+
* Slices of any supported type
68+
* Structs
69+
* time.Time for dates and times
70+
* \*os.File, \[\]byte, io.Reader, io.ReadSeeker for file uploads
71+
72+
The following sections describe the syntax for these types. It is also useful
73+
to refer to [the source code](../docs/src/binder.html) if more detail is required.
74+
75+
### Booleans
76+
77+
The string values "true", "on", and "1" are all treated as **true**. Else, the
78+
bound value will be **false**.
79+
80+
### Slices
81+
82+
There are two supported syntaxes for binding slices: ordered or unordered.
83+
84+
Ordered:
85+
86+
?ids[0]=1
87+
&ids[1]=2
88+
&ids[3]=4
89+
90+
Results in the slice `[]int{1, 2, 0, 4}`
91+
92+
Unordered:
93+
94+
?ids[]=1
95+
&ids[]=2
96+
&ids[]=3
97+
98+
results in the slice `[]int{1, 2, 3}`
99+
100+
**Note:** Only ordered slices should be used when binding a slice of structs:
101+
102+
?user[0].Id=1
103+
&user[0].Name=rob
104+
&user[1].Id=2
105+
&user[1].Name=jenny
106+
107+
### Structs
108+
109+
Structs are bound using a simple dot notation:
110+
111+
?user.Id=1
112+
&user.Name=rob
113+
&user.Friends[]=2
114+
&user.Friends[]=3
115+
&user.Father.Id=5
116+
&user.Father.Name=Hermes
117+
118+
would bind a structure defined as:
119+
120+
<pre class="prettyprint lang-go">
121+
type User struct {
122+
Id int
123+
Name string
124+
Friends []int
125+
Father User
126+
}
127+
</pre>
128+
129+
**Note:** Properties must be exported in order to be bound.
130+
131+
### Date / Time
132+
133+
The SQL standard time formats \["2006-01-02", "2006-01-02 15:04"\] are built in.
134+
135+
More may be added by the application, using
136+
[the official pattern](http://golang.org/pkg/time/#pkg-constants). Simply add
137+
the pattern to recognize to the `TimeFormats` variable, like this:
138+
139+
<pre class="prettyprint lang-go">
140+
func init() {
141+
revel.TimeFormats = append(revel.TimeFormats, "01/02/2006")
142+
}
143+
</pre>
144+
145+
### File Uploads
146+
147+
File uploads may be bound to any of the following types:
148+
149+
* \*os.File
150+
* \[\]byte
151+
* io.Reader
152+
* io.ReadSeeker
153+
154+
This is a wrapper around the upload handling provided by
155+
[Go's multipart package](http://golang.org/pkg/mime/multipart/). The bytes
156+
stay in memory unless they exceed a threshold (10MB by default), in which case
157+
they are written to a temp file.
158+
159+
**Note:** Binding a file upload to `os.File` requires Revel to write it to a
160+
temp file (if it wasn't already), making it less efficient than the other types.
161+
162+
### Custom Binders
163+
164+
The application may define its own binders to take advantage of this framework.
165+
166+
It need only implement the [binder interface](../docs/godoc/binder.html#Binder) and register the type for which it
167+
should be called:
168+
169+
<pre class="prettyprint lang-go">
170+
var myBinder = revel.Binder{
171+
Bind: func(params *revel.Params, name string, typ reflect.Type) reflect.Value {...},
172+
Unbind: func(output map[string]string, name string, val interface{}) {...},
173+
}
174+
175+
func init() {
176+
revel.TypeBinders[reflect.TypeOf(MyType{})] = myBinder
177+
}
178+
</pre>

0 commit comments

Comments
 (0)