view doc/autodoc-header.htmlpart @ 520:ec1cca939315

Improved documentation of WebMCP's initialization procedure
author jbe
date Mon Aug 21 19:52:27 2017 +0200 (2017-08-21)
parents 55a43a67e9ad
children c5bf8d6963c4
line source
1 <HTML>
2 <head>
3 <script type="text/javascript">
4 var expandedSections = {};
5 function toggleSection(ident) {
6 var element = document.getElementById('autodoc_details_' + ident);
7 if (element) {
8 if (expandedSections[ident]) {
9 element.style.display = 'none';
10 delete expandedSections[ident];
11 } else {
12 element.style.display = '';
13 expandedSections[ident] = true;
14 }
15 }
16 }
17 var inProgress = false;
18 window.onload = window.onhashchange = function() {
19 if (inProgress) return;
20 for (var ident in expandedSections) toggleSection(ident);
21 var hash = window.location.hash;
22 if (hash) {
23 toggleSection(hash.replace(/^#/, ''));
24 inProgress = true;
25 window.location.hash = hash; // required after collapsing/expanding
26 inProgress = false;
27 }
28 };
29 </script>
30 <style>
31 body {
32 font-family: "Liberation Sans", sans-serif;
33 font-size: 11pt;
34 padding-bottom: 5ex;
35 }
36 .warning {
37 color: #ff0000;
38 }
39 h1, h2 {
40 font-family: "Liberation Serif", Georgia, serif;
41 }
42 h2 {
43 margin-bottom: 0.3ex;
44 }
45 p {
46 margin-bottom: 1ex;
47 line-height: 130%;
48 }
49 tt, pre {
50 font-size: 10pt;
51 }
52 tt {
53 font-weight: bold;
54 white-space: nowrap;
55 }
56 .autodoc_entry {
57 margin-top: 1ex;
58 margin-bottom: 1ex;
59 }
60 .autodoc_comment_tail {
61 font-style: italic;
62 }
63 .autodoc_entry .short_synopsis {
64 cursor: pointer;
65 }
66 .AUTODOC_details {
67 padding-left: 1em;
68 padding-right: 1em;
69 border: 1px solid #777;
70 }
71 .autodoc_synopsis {
72 font-weight: bold;
73 }
74 .autodoc_synopsis .autodoc_comment_tail {
75 font-weight: normal;
76 color: #008000;
77 }
78 .autodoc_entry .autodoc_comment {
79 color: #400080;
80 }
81 .autodoc_source {
82 color: #505050;
83 }
84 </style>
85 <title>WebMCP 2.1.0 Documentation</title>
86 </head>
87 <body>
88 <h1>WebMCP 2.1.0 Documentation</h1>
89 <p>
90 WebMCP is a web development framework based on the Lua programming language (read more about Lua <a href="http://www.lua.org/about.html">here</a>).
91 </p>
92 <h2>Requirements</h2>
93 <p>
94 WebMCP has been developed on Linux and FreeBSD. Using it with Mac&nbsp;OS&nbsp;X is untested as of yet; Microsoft Windows is not supported. Beside the operating system, the only mandatory dependencies for WebMCP are the <a href="http://www.lua.org/">programming language Lua</a> version 5.2 or 5.3, the <a href="http://www.public-software-group.org/moonbridge">Moonbridge Network Server for Lua Applications</a> version 1.0.1 or higher, <a href="http://www.postgresql.org/">PostgreSQL</a> version 8.2 or higher, and a C compiler.
95 </p>
96 <h2>Installation</h2>
97 <p>
98 After downloading the tar.gz package, unpack it, enter the unpacked directory and type <tt>make</tt>. If you use Mac OS X or if you experience problems during compilation, you need to edit the <tt>Makefile.options</tt> file prior to compilation. The framework itself will be available in the <tt>framework/</tt> directory, while a demo application is available in the <tt>demo-app/</tt> directory. The <tt>framework.precompiled/</tt> and <tt>demo-app.precompiled/</tt> directories will contain a version with all Lua files being byte-code pre-compiled, which can be used instead. You may copy these directories (with <tt>cp -L</tt> to follow links) to any other place you like. Don't forget to setup a database, and make the <tt>tmp/</tt> directory of the application writable for the user who executes WebMCP. Good luck and have fun!
99 </p>
100 <h2>Configuration, initializers, and request handling</h2>
101 <p>
102 WebMCP uses the <a href="http://www.public-software-group.org/moonbridge">Moonbridge Network Server</a> to handle HTTP requests. The Moonbridge Network Server listens to a TCP port and passes control to WebMCP by calling <a href="#request.handler"><tt>request.handler(...)</tt></a> for each request. However, before each request is processed, WebMCP will initialize the environment. This initialization includes tasks such as
103 </p>
104 <ul>
105 <li>loading libraries,</li>
106 <li>configuring the database connection or the application,</li>
107 <li>connecting to the database,</li>
108 <li>etc.</li>
109 </ul>
110 <p>
111 For each request, it is also possible to execute filters. Filters can be used to
112 </p>
113 <ul>
114 <li>
115 restrict access for certain requests, e.g. by performing redirects or raising errors
116 </li>
117 <li>
118 perform tasks that are common for different requests, e.g.
119 <ul>
120 <li>execution certain database requests,</li>
121 <li>prepare a menu on the website,</li>
122 <li>&hellip;</li>
123 </ul>
124 </li>
125 </ul>
126 <p>
127 Filters and initializers are created by adding files in the application's directory structure. The filename determins the execution order of otherwise equally ranked initializers and/or filters. It is a common idiom to start the filename of a filter or initializer with a two digit number to be easily able to change the execution order when desired. Filters and initializers are executed both before and after a request. Each file must contain an <a href="#execute.inner"><tt>execute.inner()</tt></a> command. The part before that command is executed before the request, and the part after that command is executed after the request.
128 </p>
129 <p>
130 The Moonbridge server creates forks (i.e. clones) of the application server process (i.e. the whole Lua engine including all libraries and variables) in order to handle concurrent requests. Certain initializations may be performed before forking, other initializations must be performed after forking. For this purpose, WebMCP allows an application to provide so-called "pre-fork" and "post-fork" initializers. The application's configuration files as well as its pre-fork initializers are executed before forking. The application's post-fork initializers are executed after forking. In particular, any libraries that open file or network handles during initialization must not be loaded before the server process is forked. Opening database connections must be performed after forking as well. WebMCP follows the following execution order (directory structure is explained further down):
131 </p>
132 <ol>
133 <li>
134 Initialization code of <tt>mcp.lua</tt> in the <tt>bin/</tt> directory of the framework, including:
135 <ul>
136 <li>Initialization of WebMCP's autoloader in <tt>mcp.lua</tt> (in the <tt>bin/</tt> directory of the framework),</li>
137 <li>Execution of <tt>env/__init.lua</tt> (both relative to the framework and, if existent, relative to the application base directory)</li>
138 <li>Loading of most of WebMCP's libraries (excluding "multirand" library, which must not be loaded prior to forking);</li>
139 </ul>
140 </li>
141 <li>
142 Executing the selected configuration file: <tt>config/</tt><i>configuration_name</i><tt>.lua</tt>;
143 </li>
144 <li>
145 Executing all pre-fork initializers (both those in the <tt>app/_prefork/</tt> and those in the <tt>app/</tt><i>application_name</i><tt>/_prefork/</tt> directory) until call of <tt>execute.inner()</tt> within each initializer;
146 </li>
147 <li>
148 The Moonbridge Network Server forks the process (i.e. cloning the whole Lua machine);<br />
149 <span style="color: red">Note: no file handles or network connections must be opened prior to this point!</span>
150 </li>
151 <li>
152 Loading WebMCP's "multirand" library;
153 </li>
154 <li>
155 Executing all post-fork initializers (both those in the <tt>app/_postfork/</tt> and those in the <tt>app/</tt><i>application_name</i><tt>/_postfork/</tt> directory) until call of <tt>execute.inner()</tt> within each initializer;
156 </li>
157 <li>
158 For each request:
159 <ul>
160 <li>
161 Execution of all applicable filters until call of <tt>execute.inner()</tt> within each filter,
162 </li>
163 <li>
164 Handling of the request by calling the appropriate view or action,
165 </li>
166 <li>
167 Resuming execution of all filters in reverse order from that position where <tt>execute.inner()</tt> had been called;
168 </li>
169 </ul>
170 </li>
171 <li>
172 Resuming execution of all post-fork initializers in reverse order from that position where <tt>execute.inner()</tt> had been called;
173 </li>
174 <li>
175 Resuming execution of all pre-fork initializers in reverse order from that position where <tt>execute.inner()</tt> had been called.
176 </li>
177 </ol>
178 </p>
179 <p>
180 As a minimum configuration, the used configuration file or pre-fork initializer should at least contain a <a href="#listen"><tt>listen{...}</tt></a> call, e.g.:
181 </p>
182 <pre>
183 listen{
184 { proto = "tcp", host = "::", port = 8080 },
185 { proto = "tcp", host = "", port = 8080 }
186 }
187 execute.inner() -- only use this line if done in pre-fork initializer</pre>
188 <h2>Using the atom library</h2>
189 <p>
190 Lua itself has only very few built-in data types. The atom library gives support for extra data types. Currently the following extra data types are provided:
191 </p>
192 <ul>
193 <li><a href="#atom.fraction:new">atom.fraction</a></li>
194 <li><a href="#atom.date:new">atom.date</a></li>
195 <li><a href="#atom.time:new">atom.time</a></li>
196 <li><a href="#atom.timestamp:new">atom.timestamp (date and time combined in one data type)</a></li>
197 </ul>
198 <p>
199 In addition the following pseudo-types are existent, corresponding to Lua's base types:
200 </p>
201 <ul>
202 <li>atom.boolean</li>
203 <li>atom.string</li>
204 <li>atom.integer</li>
205 <li>atom.number</li>
206 </ul>
207 <p>
208 Both atom.integer and atom.number refer to Lua's base type &ldquo;number&rdquo;.
209 </p>
210 <p>
211 New values of atom data types are created by either calling <tt>atom.</tt><i>type</i><tt>:load(string_representation)</tt> or by calling <tt>atom.</tt><i>type</i><tt>{...}</tt>, e.g. <tt>atom.date{year=1970, month=1, day=1}</tt>. Note that <tt>atom.date{...}</tt> is a shortcut for <tt><a href="#atom.date:new">atom.date:new</a>{...}</tt>. You can dump any atom value as a string by calling <a href="#atom.dump"><tt>atom.dump(value)</tt></a> and later reload it with <tt>atom.</tt><i>type</i><tt>:load(string)</tt>.
212 </p>
213 <h2>Using the Object-Relational Mapper &ldquo;mondelefant&rdquo;</h2>
214 <p>
215 The library &ldquo;mondelefant&rdquo; shipping with WebMCP can be used to access PostgreSQL databases. It also serves as an Object-Relational Mapper (ORM). The database connection is usually configured in the config file (e.g. in <tt>config/devel.lua</tt>):
216 </p>
217 <pre>
218 config.db = { engine="postgresql", dbname="webmcp_demo" }</pre>
219 <p>
220 In addition to configuring the database, it must be opened within a post-fork initializer (e.g. in <tt>app/_postfork/01_database.lua</tt>):
221 </p>
222 <pre>
223 _G.db = assert(<a href="#mondelefant.connect">mondelefant.connect</a>(config.db))
224 function mondelefant.class_prototype:<a href="#db_class:get_db_conn">get_db_conn</a>() return db end
225 execute.inner()</pre>
226 <p>
227 The parameters for <tt>mondelefant.connect</tt> are directly passed to PostgreSQL's client library libpq. See PostgreSQL's documentation for information about <a href="https://www.postgresql.org/docs/9.6/static/libpq-connect.html#LIBPQ-PARAMKEYWORDS">supported parameters</a>.
228 </p>
229 <p>
230 To define a model to be used within a WebMCP application, create a file named with the name of the model and <tt>.lua</tt> as extension in the <tt>model/</tt> directory of your application. The most basic definition of a model (named &ldquo;movie&rdquo; in this example) is:
231 </p>
232 <pre>
233 Movie = <a href="#mondelefant.new_class">mondelefant.new_class</a>()
234 Movie.table = 'movie'</pre>
235 <p>
236 Note: Model classes are always written CamelCase, while the name of the file in <tt>model/</tt> is written lower_case.
237 </p>
238 <p>
239 To select objects from the database, the mondelefant library provides a selector framework:
240 </p>
241 <pre>
242 local s = Movie:<a href="#db_class:new_selector">new_selector</a>()
243 s:<a href="#db_selector:add_where">add_where</a>{ 'id = ?', param.get_id() }
244 s:<a href="#db_selector:single_object_mode">single_object_mode</a>() -- return single object instead of list
245 local movie = s:<a href="#db_selector:exec">exec</a>()</pre>
246 <p>
247 A short form of the above query would be:
248 </p>
249 <pre>
250 local movie = Movie:new_selector():add_where{ 'id = ?', param.get_id() }:single_object_mode():exec()</pre>
251 <p>
252 For more examples about how to use the model system, please take a look at the demo application.
253 </p>
254 <h2>The Model-View-Action (MVA) concept</h2>
255 <p>
256 As opposed to other web application frameworks, WebMCP does not use a Model-View-Controller (MVC) concept, but a Model-View-Action (MVA) concept.
257 </p>
258 <h3>Models</h3>
259 <p>
260 The models in MVA are like the models in MVC; they are used to access data, which is stored in a relational database (PostgreSQL), in an object oriented way. Methods provided by the corresponding classes can be used to alter stored objects or execute any other associated program code. Models are usually defined in a file with a lowercase filename ending with "<tt>.lua</tt>" in the <tt>models/</tt> directory of the application. The corresponding model name (i.e. class name) must be written in CamelCase, e.g. "<tt>models/my_model.lua</tt>" should define a model class named "<tt>MyModel</tt>". The simplest model is created by calling <a href="#mondelefant.new_class"><tt>mondelefant.new_class()</tt></a> and subsequently setting the <a href="#db_class.table"><tt>table</tt></a> attribute of the returned class.
261 </p>
262 <pre>
263 -- filename: model/customer_receipt.lua
264 CustomerReceipt = mondelefant.new_class()
265 CustomerReceipt.table = "custreceipt"</pre>
266 <p>
267 Methods such as <a href="#db_class:add_reference"><tt>:add_reference(...)</tt></a> can be used to further modify or extend the class.
268 </p>
269 <h3>Views</h3>
270 <p>
271 The views in the MVA concept are different from the views in the MVC concept. As WebMCP has no controllers, the views are responsible for processing the GET/POST parameters from the webbrowser, fetching the data to be displayed, and creating the output by directly writing HTML to slots of a layout (see <a href="#slot.select"><tt>slot.select(...)</tt></a>, <a href="#slot.put"><tt>slot.put(...)</tt></a>, and <a href="#slot.put_into"><tt>slot.put_into(...)</tt></a> or by calling helper functions for the user interface (those functions beginning with "<tt>ui.</tt>"). Views are stored in files with the file path "<tt>app/</tt><i>application_name</i><tt>/</tt><i>module_name</i><tt>/</tt><i>view_name</i><tt>.lua</tt>". When their corresponding URL, e.g. "<tt>http://</tt><i>hostname</i><tt>:</tt><i>port</i><tt>/</tt><i>module_name</i><tt>/</tt><i>view_name</i><tt>.html</tt>", is requested, the code in that file gets executed (after calling appropriate filters). After the execution of the view has finished (and after all filters have finished their execution too), the slot data will be inserted into placeholder sections in the selected layout file. The layout file defaults to "<tt>app/</tt><i>application_name</i><tt>/_layout/default.html</tt>" but may be changed using the <a href="#slot.set_layout"><tt>slot.set_layout(...)</tt></a> function.
272 </p>
273 <h3>Actions</h3>
274 <p>
275 Actions are similar to views, but supposed to change data in the database, hence only callable by HTTP POST requests. They are also responsible for processing the POST parameters from the webbrowser. They can modify the database, but instead of rendering a page to be displayed, they just return a status code string (via Lua's <tt>return</tt> statement, where <tt>true</tt> can also be used instead of "<tt>ok</tt>", and <tt>false</tt> instead of "<tt>error</tt>"). Depending on the status string there will be an internal forward or an HTTP 303 redirect to a view. When calling an action via a POST request, additional POST parameters, which are usually added by hidden form fields, determine the view to be displayed for each status string returned by the action. See the <tt>routing</tt> parameter to the <a href="#ui.form"><tt>ui.form{...}</tt></a> function for further details.
276 </p>
277 <h2>Layouts</h2>
278 <p>
279 Templates for HTML documents to be returned by views are stored at the path "<tt>app/</tt><i>application_name</i><tt>/_layout/</tt><i>layout_name</i><tt>.html</tt>", relative to the application base path. The default layout name is "<tt>default</tt>". For system errors, the layout name "<tt>system_error</tt>" is used. A sample layout is given as follows:
280 </p>
281 <pre>
282 &lt;!DOCTYPE HTML&gt;
283 &lt;html&gt;
284 &lt;head&gt;
285 &lt;title&gt;&lt!-- WEBMCP SLOTNODIV title --&gt;&lt;/title&gt;
286 &lt;link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/style.css"/&gt;
287 &lt;/head&gt;
288 &lt;body&gt;
289 &lt;!-- WEBMCP SLOT content --&gt;
290 &lt;/body&gt;
291 &lt;/html&gt;</pre>
292 <p>
293 The following elements in a layout file get replaced automatically:
294 </p>
295 <ul>
296 <li><tt>__BASEURL__</tt> gets replaced with the application's base web address.</li>
297 <li><tt>&lt;!-- WEBMCP SLOT </tt><i>slot_name</i><tt> --&gt;</tt> gets, if the slot is not empty, replaced with a <tt>&lt;div&gt;</tt> element (with the <tt>id</tt> attribute set to "<tt>slot_</tt><i>slotname</i>") that contains the slot's content.</li>
298 <li><tt>&lt;!-- WEBMCP SLOTNODIV </tt><i>slot_name</i><tt> --&gt;</tt> gets replaced with the slot's content (without wrapping it in an additional <tt>&lt;div&gt;</tt> element).</li>
299 </ul>
300 <h2>Internationalization/Localization</h2>
301 <p>
302 To translate certain strings in your application, simply use the <a href="#_">underscore function</a>. A language can be selected with <tt><a href="#locale.set">locale.set</a>{lang = "code"}</tt> where <tt>code</tt> is a language code. The translations for strings are expected to be contained in files "<tt>locale/translations.</tt><i>language_code</i><tt>.lua</tt>". These files should return a table that maps strings to their corresponding translation:
303 </p>
304 <pre>
305 return{
306 ["Are you sure?"] = "Bist Du sicher?";
307 ["User '#{name}' created"] = "Benutzer '#{name}' created";
308 }</pre>
309 <p>
310 Such translation files can be automatically created with the <tt>langtool.lua</tt> program, found in the framework's <tt>bin/</tt> directory.
311 </p>
312 <h2>Global variables and the environment</h2>
313 <p>
314 To avoid accidental programming errors, WebMCP forbids setting of global variables by default. This is overridden by using the prefix "<tt>_G.</tt>" (<a href="#_G">see reference</a>) when setting the variable, e.g. <tt>_G.myvar = 7</tt>, or by setting the variable in a file with the same name of the global varaible (but suffixed with "<tt>.lua</tt>") in the <tt>env/</tt> directory of the framework or application. Note, however, that the lifetime of global variables is not predictable as it depends on process recycling of the Moonbridge webserver (one fork will handle more than one request) and because there may be multiple forks of the Lua machine which all have their own global variable space (there is usually more than one fork).
315 </p>
316 <p>
317 If an application needs to store request related data, the global table <a href="#app"><tt>app</tt></a> should be used (e.g. <tt>app.myvar = true</tt> instead of <tt>_G.myvar = true</tt>). The <tt>app</tt> table gets automatically initialized (i.e. emptied) for each request.
318 </p>
319 <p>
320 Global variables are still useful when providing access to libraries, for example. WebMCP automatically loads certain libraries and functions though an autoloader mechanism. On read-accessing any unknown variable, WebMCP will search the framework's and application's <tt>env/</tt> directories for an appropriate file (e.g. "<tt>my_func.lua</tt> if you invoke "<tt>my_func()</tt>") or a matching directory (e.g. "<tt>my_module/</tt> if you access "<tt>my_module.my_func()</tt>). In case of an existing directory in <tt>env/</tt>, an empty table with autoloading capabilities is automatically created as global variable with the name of the directory. The autoloading mechanism allows directories to contain further files which can be used to initialize variables within that table when accessed. Directories can also contain a special file called "<tt>__init.lua</tt>" that always gets executed when the table is accessed for the first time. The <tt>env/</tt> root directory can also contain a file ("<tt>env/__init__.lua</tt>") which gets executed before any configuration is loaded.
321 </p>
322 <p>
323 A good place to store utility functions is a global table called <tt>util</tt>. This table will be automatically accessible if you create a <tt>env/util/</tt> directory in your WebMCP application. To provide a function <tt>util.myfunc(...)</tt> simply create a file <tt>env/util/myfunc.lua</tt>, with the following function definition:
324 </p>
325 <pre>
326 -- filename: env/util/myfunc.lua
327 function util.myfunc()
328 slot.put_into("hello", "Hello World!")
329 end</pre>
330 <h2>Directory structure of a WebMCP application</h2>
331 <p>
332 Summarizing information from the previous section, we get the following directory structure for a WebMCP application:
333 </p>
334 <ul>
335 <li>
336 Base Directory
337 <ul>
338 <li>
339 <tt>app/</tt>
340 <ul>
341 <li><tt>_prefork/</tt></li>
342 <li><tt>_postfork/</tt></li>
343 <li>
344 <tt>main/</tt> (typically "main" is the only application)
345 <ul>
346 <li><tt>_prefork/</tt></li>
347 <li><tt>_postfork/</tt></li>
348 <li><tt>_filter/</tt></li>
349 <li><tt>_filter_action/</tt></li>
350 <li><tt>_filter_view/</tt></li>
351 <li><tt>_layout/</tt></li>
352 <li>
353 <tt>index/</tt> (module "index" is the default module)
354 <ul>
355 <li>
356 <tt>_action/</tt>
357 <ul>
358 <li><i>action_name</i><tt>.lua</tt></li>
359 <li><i>another_action_name</i><tt>.lua</tt></li>
360 <li>&hellip;</li>
361 </ul>
362 </li>
363 <li><tt>index.lua</tt> (view "index" of module "index" is the default view)</li>
364 <li><i>other_view_name</i><tt>.lua</tt></li>
365 <li>&hellip;</li>
366 </ul>
367 </li>
368 <li>
369 <i>other_module_name</i><tt>/</tt>
370 <ul><li>&hellip;</li></ul>
371 </li>
372 </ul>
373 </li>
374 <li>
375 <i>other_application_name</i><tt>/</tt>
376 <ul>
377 <li>&hellip;</li>
378 </ul>
379 </li>
380 </ul>
381 </li>
382 <li>
383 <tt>config/</tt>
384 <ul>
385 <li><tt>development.lua</tt> (e.g. to be used for development purposes)</li>
386 <li><tt>production.lua</tt> (e.g. to be used for production)</li>
387 <li><i>other_config_name</i><tt>.lua</tt></li>
388 <li>&hellip;</li>
389 </ul>
390 </li>
391 <li>
392 <tt>db/</tt>
393 <ul>
394 <li><tt>schema.sql</tt> (not used by WebMCP, but may be used to initialize a database)</li>
395 </ul>
396 </li>
397 <li>
398 <tt>env/</tt>
399 <ul>
400 <li><tt>__init.lua</tt></li>
401 <li><i>some_global_variable_name</i><tt>.lua</tt></li>
402 <li>
403 <i>another_global_variable_name</i><tt>/</tt>
404 <ul>
405 <li><tt>__init.lua</tt></li>
406 <li><i>attribute_name</i><tt>.lua</tt></li>
407 <li>
408 <i>another_attibute_name</i><tt>/</tt>
409 <ul><li>&hellip;</li></ul>
410 </li>
411 </ul>
412 </li>
413 </ul>
414 <li>
415 <tt>locale/</tt> (translation files used by the <a href="#_">underscore function</a>")
416 <ul>
417 <li>
418 <tt>translations.de.lua</tt>
419 </li>
420 <li>
421 <tt>translations.en.lua</tt>
422 </li>
423 <li>
424 <tt>translations.</tt><i>languagecode</i><tt>.lua</tt>
425 </li>
426 <li>&hellip;</li>
427 </ul>
428 </li>
429 <li>
430 <tt>model/</tt>
431 <ul>
432 <li>
433 <i>model_name</i><tt>.lua</tt> (code must create a model class in camel case, e.g. "<tt>ModelName</tt>" if the file name is "<tt>model_name.lua</tt>")
434 </li>
435 <li>
436 <i>another_model_name</i><tt>.lua</tt>
437 </li>
438 <li>&hellip;</li>
439 </ul>
440 </li>
441 <li>
442 <tt>static/</tt>
443 <ul>
444 <li>&hellip; (images, javascript, ...)</li>
445 </ul>
446 </li>
447 <li>
448 <tt>tmp/</tt> (needs to be writable by the user executing WebMCP)
449 </li>
450 </ul>
451 </li>
452 </ul>
453 <h2>Starting your application</h2>
454 <p>
455 Ensure that the <tt>moonbridge</tt> binary is within your system's search path and that the <tt>moonbridge_http.lua</tt> file is included in the LUA_PATH or linked into the framework's <tt>lib/</tt> directory (alternatively the MOONBR_LUA_PATH option might be set accordingly at compile-time of the Moonbridge Network Server). To start an application, call the <tt>mcp.lua</tt> executable (found in <tt>framework/bin/mcp.lua</tt>) with the following four arguments:
456 </p>
457 <ol>
458 <li>Path of the WebMCP framework directory, e.g. <tt>./framework</tt></li>
459 <li>Path of your application's directory, e.g. <tt>./demo-app</tt></li>
460 <li>Name of your applicaiton (usually <tt>main</tt>)</li>
461 <li>Name of configuration (e.g. <tt>devel</tt> to use config/devel.lua)</li>
462 </ol>
463 <p>
464 Alternatively, the <tt>moonbridge</tt> binary may be called directly with the following five arguments:
465 </p>
466 <ol>
467 <li>Path to <tt>mcp.lua</tt>, e.g. <tt>./framework/bin/mcp.lua</tt></li>
468 <li>Path of the WebMCP framework directory, e.g. <tt>./framework</tt></li>
469 <li>Path of your application's directory, e.g. <tt>./demo-app</tt></li>
470 <li>Name of your applicaiton (usually <tt>main</tt>)</li>
471 <li>Name of configuration (e.g. <tt>devel</tt> to use config/devel.lua)</li>
472 </ol>
473 <p>
474 Note that the demo application will require a database to be set up prior to starting. Execute the following shell commands first:
475 </p>
476 <pre>
477 createdb webmcp_demo
478 psql -v ON_ERROR_STOP=1 -f demo-app/db/schema.sql webmcp_demo</pre>
479 <h2>Automatically generated reference for the WebMCP environment</h2>
480 <ul>

Impressum / About Us