In this tutorial we will show you how to create a basic wiki engine and look into how one can map a URL or the path component of a URL to a database entry. This tutorial builds on what we learned in the Lua SQLite Database Tutorial.
The purpose with this tutorial is to show you how to do URL to database mapping, and the wiki engine we design in this tutorial will be fairly basic. You can use what you learn in this tutorial as a base if you want to build a full-fledged wiki engine. The SQL table that will be used in the wiki engine for storing wiki pages will be created as follows:
The 'relpath' is the URL's relative path element. The relpath is used as a key and allows us to search for pages by using the URL's relative path element. We will get more into relative paths soon. The 'data' is the text displayed on the wiki page.
The Mako Server is a spin-off from the Barracuda Embedded Web Server Library and this server supports the concept of a virtual file system, where the path component of a URL is mapped to directory nodes installed in this file system. Each installed directory node can optionally have a callback function called the directory service function. A directory service function allows us to map the URL to SQL queries.
The following code snippet shows the directory service function in the wiki engine's .preload script.
1 local function wikifunc(_ENV,relpath) 2 local sql=string.format("data FROM wiki WHERE relpath=%s", 3 luasql.quotestr(relpath)) 4 local data=su.find(function() return su.open"wiki" end, sql) 5 if data then 6 if request:data"edit" then 7 _ENV.relpath=relpath 8 _ENV.wikidata = data 9 response:forward(wikidir:baseuri()..".edit/modify.lsp") 10 else 11 response:write("<html><body>", 12 text2html(data), 13 "<p><a href='?edit='>edit</a> <a href='", 14 wikidir:baseuri(), 15 "'>index</a></p>", 16 "</body></html>") 17 end 18 else 19 _ENV.relpath=relpath 20 response:forward(wikidir:baseuri()..".edit/create.lsp") 21 end 22 end
The server provides a number of directory object types that can be installed in the virtual file system. When you load the wiki engine using the Mako Server, the server creates one directory node of type resource reader for the wiki application and inserts this directory node into the virtual file system. The resource reader is your LSP application and the resource reader's directory node is made available as 'dir' in the preload script. The following example inserts the above directory service function ' wikifunc' into this directory node.
The directory service function takes precedence over LSP pages in your application, and the 'wikifunc' as we have designed it above will make it impossible to run any of our LSP pages in the application since all pages will be assumed to be part of the wiki. What we want to do is to be able to access the LSP pages in our example such as 'index.lsp' and the two pages we use for editing 'create.lsp' and 'modify.lsp'. Any resource not found in our LSP application will be assumed to be part of the wiki. One way to solve this is to create a new directory object and then insert this as a child object of the application's directory object. The following code snippet from the .preload script illustrates how this is done.
1 local wikidir=ba.create.dir() -- No 'name' makes dir a sibling when inserted 2 wikidir:setfunc(wikifunc) 3 dir:insert(wikidir,true)
Child objects with no name behave as if it is a sibling to the parent directory. This is a feature that works great with our wiki engine since it allows resources to be initially searched for in the application's directory and if not found, searched for in the wiki directory. The 'wikifunc' directory service function is called as soon as the virtual file system delegates the response to the wiki directory object.
The wiki engine in the .preload script includes a few supporting LSP pages: