nitweb: introduce ModelAction
[nit.git] / src / web / web_base.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Base classes used by `nitweb`.
16 module web_base
17
18 import model::model_views
19 import nitcorn
20 import json
21
22 # Nitcorn server runned by `nitweb`.
23 #
24 # Usage:
25 #
26 # ~~~nitish
27 # var srv = new NitServer("localhost", 3000)
28 # srv.routes.add new Route("/", new MyAction)
29 # src.listen
30 # ~~~
31 class NitServer
32
33 # Host to bind.
34 var host: String
35
36 # Port to use.
37 var port: Int
38
39 # Routes knwon by the server.
40 var routes = new Array[Route]
41
42 # Start listen on `host:port`.
43 fun listen do
44 var iface = "{host}:{port}"
45 print "Launching server on http://{iface}/"
46
47 var vh = new VirtualHost(iface)
48 for route in routes do vh.routes.add route
49
50 var fac = new HttpFactory.and_libevent
51 fac.config.virtual_hosts.add vh
52 fac.run
53 end
54 end
55
56 # Specific nitcorn Action for nitweb.
57 class NitAction
58 super Action
59
60 # Link to the NitServer that runs this action.
61 var srv: NitServer
62
63 # Build a custom http response for errors.
64 fun render_error(code: Int, message: String): HttpResponse do
65 var response = new HttpResponse(code)
66 var tpl = new Template
67 tpl.add "<h1>Error {code}</h1>"
68 tpl.add "<pre><code>{message.html_escape}</code></pre>"
69 response.body = tpl.write_to_string
70 return response
71 end
72
73 # Render a view as a HttpResponse 200.
74 fun render_view(view: NitView): HttpResponse do
75 var response = new HttpResponse(200)
76 response.body = view.render(srv).write_to_string
77 return response
78 end
79
80 # Return a HttpResponse containing `json`.
81 fun render_json(json: Jsonable): HttpResponse do
82 var response = new HttpResponse(200)
83 response.body = json.to_json
84 return response
85 end
86 end
87
88 # Specific nitcorn Action that uses a Model
89 class ModelAction
90 super NitAction
91
92 # Model to use.
93 var model: Model
94
95 # Init the model view from the `req` uri parameters.
96 fun init_model_view(req: HttpRequest): ModelView do
97 var view = new ModelView(model)
98
99 var show_private = req.bool_arg("private") or else false
100 if not show_private then view.min_visibility = protected_visibility
101
102 view.include_fictive = req.bool_arg("fictive") or else false
103 view.include_empty_doc = req.bool_arg("empty-doc") or else true
104 view.include_test_suite = req.bool_arg("test-suite") or else false
105 view.include_attribute = req.bool_arg("attributes") or else true
106
107 return view
108 end
109 end
110
111 # A NitView is rendered by an action.
112 interface NitView
113 # Renders this view and returns something that can be written to a HTTP response.
114 fun render(srv: NitServer): Writable is abstract
115 end
116
117 redef class HttpRequest
118 # Does the client asked for a json formatted response?
119 #
120 # Checks the URL get parameter `?json=true`.
121 fun is_json_asked: Bool do return bool_arg("json") or else false
122 end