lua MVC框架 Orbit初探


介紹

http://keplerproject.github.io/orbit/

Orbit是lua語言版本的MVC框架。

此框架完全拋棄CGILUA的腳本模型, 支持的應用, 每個應用可以卸載一個單獨的文件中,當然你也可以將它拆為一個文件, 當你需要時候。

此框架運行在WSAPI協議的服務器上,所以可以工作在 Xavante和一些CGI和fastcgi程序上。

Orbit is an MVC web framework for Lua. The design is inspired by lightweight Ruby frameworks such as Camping. It completely abandons the CGILua model of "scripts" in favor of applications, where each Orbit application can fit in a single file, but you can split it into multiple files if you want. All Orbit applications follow the WSAPI protocol, so they currently work with Xavante, CGI and Fastcgi. It includes a launcher that makes it easy to launch a Xavante instance for development.

 

安裝運行

http://keplerproject.github.io/orbit/example.html

此程序依賴 sqlite。

Depending on your configuration, you might need to install the luasql-sqlite3 and markdown rocks before running the application. Now just start Xavante, and point your browser to blog.ws, and you should see the index page of the blog. If you created a blog.db from scratch you are not going to see any posts, though. The blog application in `samples/blog' includes a blog.db filled with random posts and comments.

 

安裝:

luarocks search sql

apt-get install sqlite3

luarocks install luasql-sqlite3 SQLITE_DIR=/usr/local

 

運行

root@fqs:/usr/local/lib/luarocks/rocks/orbit/2.2.4-1/samples/blog# orbit -p 8181 blog.lua
Starting Orbit server at port 8181

image

 

 

使用firefox sqlite插件, 查看db

image

 

APP接口

 

使用orbit.new則構造了一個APP環境, 此環境可以引用全局變量,

同時還定義了 blog應用繼承了 orbit項目的接口, 例如路由的get接口  dispatch_get

local blog = setmetatable(orbit.new(), { __index = _G })
if _VERSION == "Lua 5.2" then
  _ENV = blog
else
  setfenv(1, blog)
end

orbit.new injects quite a lot of stuff in the blog module's namespace. The most important of these are the dispatch_get, dispatch_post, and model methods that let you define the main functionality of the application.

 

Creating Models

模型角色負責從數據庫中查詢數據, 后者新建和修改數據。

Our blog application has three kinds of objects: posts, comments, and "static" pages (things like an "About" page for the blog, for example). It's no coincidence that we also have three tables in the database, each table maps to a kind of object our application handles, and for each kind we will create a model. We first create a model object for posts:

posts = blog:model "post"
function posts:find_recent()
   return self:find_all("published_at is not null",
            { order = "published_at desc",
               count = recent_count })
end

 

Defining Controllers

對於請求的URL,執行訪問什么數據, 怎么響應。 訪問數據調用model對象, 響應內容可以是html, 也可以是 xml json等。

Controllers are the interface between the web and your application. With Orbit you can map the path part of your application's URLs (in http://myserver.com/myapp.ws/foo/bar the path is /foo/bar, for example) to controllers. In Lua terms, an Orbit controller is a function that receives a request/response object (usually called web) plus parameters extracted from the path, and returns text that is sent to the client (usually HTML, but can be XML, or even an image).

 

GET請求一個URL,調用模型獲取數據

function index(web)
   local ps = posts:find_recent()
   local ms = posts:find_months()
   local pgs = pgs or pages:find_all()
   return render_index(web, { posts = ps, months = ms,
              recent = ps, pages = pgs })
end

blog:dispatch_get(cache(index), "/", "/index") 

POST修改數據, 調用模型,保存數據 。

function add_comment(web, post_id)
   local input = web.input
   if string.find(input.comment, "^%s*$") then
      return view_post(web, post_id, true)
   else
      local comment = comments:new()
      comment.post_id = tonumber(post_id)
      comment.body = markdown(input.comment)
      if not string.find(input.author, "^%s*$") then
     comment.author = input.author
      end
      if not string.find(input.email, "^%s*$") then
     comment.email = input.email
      end
      if not string.find(input.url, "^%s*$") then
     comment.url = input.url
      end
      comment:save()
      local post = posts:find(tonumber(post_id))
      post.n_comments = (post.n_comments or 0) + 1
      post:save()
      cache:invalidate("/")
      cache:invalidate("/post/" .. post_id)
      cache:invalidate("/archive/" .. os.date("%Y/%m", post.published_at))
      return web:redirect(web:link("/post/" .. post_id))
   end
end

blog:dispatch_post(add_comment, "/post/(%d+)/addcomment")

 

Views: Generating HTML

視圖定義的一個簡單函數, 在函數中生成視圖內容,例如HTML。

可以直接從控制器中返回,渲染的內容, 但是這里還是建議分離控制器和視圖,這是一個好的編程實踐。

Views are the last component of the MVC triad. For Orbit views are just simple functions that generate content (usually HTML), and are strictly optional, meaning you can return content directly from the controller. But it's still good programming practice to separate controllers and views.

 

你可使用concat將字符串拼接為視圖結果, 也可以使用一個第三方的模板庫, 將從model中獲取的數據, 使用模板引擎渲染到模板中。

orbit提供了使用的 HTML和XML生成器 orbit.htmlify, 但是你也可以自由選擇其它的你想用的方法。

How you generate content is up to you: concatenate Lua strings, use table.concat, use a third-party template library... Orbit provides programmatic HTML/XML generation through orbit.htmlify, but you are free to use any method you want. In this tutorial we will stick with programmatic generation, though, as the other methods (straight strings, Cosmo, etc.) are thoroughly documented elsewhere.

orbit.htmlify

function layout(web, args, inner_html)
   return html{
      head{
     title(blog_title),
     meta{ ["http-equiv"] = "Content-Type",
        content = "text/html; charset=utf-8" },
     link{ rel = 'stylesheet', type = 'text/css', 
        href = web:static_link('/style.css'), media = 'screen' }
      },
      body{
     div{ id = "container",
        div{ id = "header", title = "sitename" },
        div{ id = "mainnav",
           _menu(web, args)
        }, 
            div{ id = "menu",
           _sidebar(web, args)
        },  
        div{ id = "contents", inner_html },
        div{ id = "footer", copyright_notice }
     }
      }
   } 
end
 
 

cosmo后台模板引擎

MVC架構中一直提到數據和視圖分離,

如果使用orbit.htmlify模式, 則只能寫出符合DOM結構化的lua代碼, 對於前端代碼如果能用HTML方式書寫,類似JSP格式, 也比orbit提供的這種方式好維護, 前端更加方便定制。

 

看看lua的后台模板引擎

http://cosmo.luaforge.net/

Overview

Cosmo is a “safe templates” engine. It allows you to fill nested templates, providing many of the advantages of Turing-complete template engines, without without the downside of allowing arbitrary code in the templates.

 

Simple Form Filling

Let’s start with a simple example of filling a set of scalar values into a template: Here are a few examples of Cosmo in use:

> values = { rank="Ace", suit="Spades" } 
> template = "$rank of $suit"
> require("cosmo")
> = cosmo.fill(template, values)
Ace of Spades

Note that the template is a string that marks where values should go. The table provides the values. $rank will get replaced by value.rank (“Ace”) and $suit will get replaced by value.suit (“Spades”).

cosmo.fill() takes two parameters at once. Cosmo also provides a “shortcut” method f() which takes only one parameter – the template – and returns a function that then takes the second parameter. This allows for a more compact notation:

> = cosmo.f(template){ rank="Ace", suit="Spades" } 
Ace of Spades


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM