Permalink
Browse files

Make the readme nice and put in an ignore.

  • Loading branch information...
1 parent 8c0e491 commit cfd26b5b76d56106b84fdb38103de8cff8f6c13d @zedshaw zedshaw committed May 21, 2011
Showing with 260 additions and 1 deletion.
  1. +30 −0 .gitignore
  2. +0 −1 README
  3. +230 −0 README.md
View
@@ -0,0 +1,30 @@
+
+bin/
+# Compiled Object files
+*.slo
+*.lo
+*.o
+
+# Compiled Dynamic libraries
+*.so
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+.*.sw*
+tests/*_tests
+tests/*_tests.*/*
+tests/config.sqlite
+tests/empty.sqlite
+*.log
+tests/request_payloads.txt
+tests/test.pid
+tests/tests.log
+tools/lemon/lemon
+tools/m2sh/build/
+tools/m2sh/tests/*_tests
+tools/m2sh/tests/tests.log
+run/*
+logs/*
+tmp/*
View
@@ -1 +0,0 @@
-This is the Tir project. A better readme on the way.
View
@@ -0,0 +1,230 @@
+Tir Web Framework: The State Agnostic Lua Micro-Framework
+=========================================================
+
+Tir is an experimental web framework for the [Mongrel2 webserver](http://mongrel2.org/) and Lua
+programming language. The purpose of Tir is to play with the idea of a State
+Agnostic web framework. Tir lets you create handlers that work in various
+configurations as needed by your application requirements. You create your
+application using a natural_coroutine_style of handler, then make another part
+stateless, and still have other parts using an evented/callback_style.
+
+Getting Started
+---------------
+
+Tir is very alpha, but it is being used on a few projects. Feel free to grab
+the code and if you want to help, then contact zedshaw@zedshaw.com for more
+information. You can read the Install, GettingStarted and the
+ContributorInstructions for information on how to get up and running with Tir.
+The source to Tir is available at http://tir.mongrel2.org/downloads/tir-0.9-1.tar.gz.
+
+
+Tir's Philosophy
+----------------
+
+Tir's philosophy is that the framework creator shouldn't be shoving stateful/
+stateless dogma in your face, and that it's possible to support various state
+management styles. Tir allows you to use different state management strategies
+for different interfaces you need to design.
+
+* If a part of your application is a complex process, then Natural Style is the
+ way to go.
+* If there's a single URL service then Stateless Style is the easiest.
+* If you have a URL+action for say a REST API then Evented Style works great.
+
+The point though is that different problems are best solved with different
+state management.
+
+Natural Style
+-------------
+
+I'm calling the coroutine based handlers "Natural Style" because you write the
+code for them in a more natural way, as if you don't need to worry about
+routing and state management. You can code up entire complex processes and
+interactions using the natural style very easily. For example, pagination is
+difficult in stateless servers, but it's just a repeat/until loop in natural
+style.
+By default, handlers are natural style and maintain a coroutine for each user
+and let you write your code using phrases like "prompt", "recv", "page", and
+"send".
+
+<pre>
+ local login_page = Tir.view("login.html")
+ local login_form = Tir.form { 'login_name', 'password'}
+
+ local function login(web, req)
+ local params = login_form:parse(req)
+
+ repeat
+ params = web:prompt(login_page {form=params, logged_in=false})
+ until login_form:valid(params)
+
+ return web:redirect('/')
+ end
+
+ Tir.start {route='/Login', main=login}
+</pre>
+
+
+Stateless Style
+---------------
+
+Handlers can be made "stateless" and they'll work like coroutine handlers, but
+not retain any state. These are good for one-shot operations and simpler
+actions that don't need much routing.
+
+<pre>
+ local search_page = Tir.view("search.html")
+ local search_form = Tir.form {"q"}
+
+ local function search(web, req)
+ local params = search_form:parse(req)
+ local q = params.q
+ local results = {}
+
+ if search_form:valid(params) then
+ local pattern = ".*" .. q:upper() .. ".*";
+
+ for i, cat in ipairs(categories) do
+ if cat:upper():match(pattern) then
+ results[#results + 1] = cat
+ end
+ end
+ end
+
+ web:page(search_page {results=results, q=q})
+ end
+
+ Tir.stateless {route='/Search', main=search}
+</pre>
+
+Evented Style
+-------------
+
+Tir also supports the alternative "evented" style, which means that URLs are
+mapped to callback functions in your handler. A simple URL pattern is used to
+transform your /Route/action style URLs into a function to call. Best of all,
+evented operation can be combined with stateless (the default) or coroutines,
+so you can easily refactor complex URL schemes if you need:
+
+<pre>
+ local Manage = {
+ form = Tir.form {"id", "action"}
+ }
+
+ function Manage.people(web, req, params)
+ -- Do whatever managing people does.
+ end
+
+ function Manage.cats(web, req, params)
+ -- Whatever managing cats means, if that's possible.
+ end
+
+ function Manage.dogs(web, req, params)
+ -- Ah way easier to manage dogs.
+ end
+
+ Manage.config = {
+ route='/Manage',
+ }
+
+ Tir.evented(Manage)
+</pre>
+
+In this style, Manage.form is run and then your handlers receive the results to
+work with right away. You can even change the routing pattern if you don't like
+what I've chosen, or need even more complexity in your life.
+
+Simple Templating Language
+--------------------------
+
+Tir uses embedded Lua as it's templating language, which means you get a real
+language and not some crippled one someone smarter than you think you should be
+using. And Lua already looks like most of the nice template languages out
+there:
+
+<pre>
+ {% if #results > 0 then %}
+ <ul>
+ {% for _,result in ipairs(results) do %}
+ <li>{{ result }}</li>
+ {% end %}
+ </ul>
+ {% else %}
+ <p>We'll add "{{ q }}" as a new one.</p>
+ {% end %}
+</pre>
+
+Multiple Little Processes
+-------------------------
+
+Tir also uses ZeroMQ and Mongrel2 to run the application as a set of small
+processes for each major routing, rather than one monolithic process. In the
+above two examples, each Tir.start line is a single process.
+You can also build on this to flex and warp the size of your processes as you
+need, and locate them or cluster them however you like. By default it shoots
+for small little processes, but nothing prevents you from doing others.
+
+Builtin Background Tasks
+------------------------
+
+Tir.Task lets you create and connect to ready to run 0MQ background task
+processes so you can offload long running tasks and avoid holding up web
+requests. They're designed to be very easy to use, but still flexible enough to
+let you do what you need. By default they use PUB/SUB sockets, but you can
+change that with a setting. You can also put the background tasks on clusters
+of machines and nearly anything else you need to do. Messages are simply just
+JSON encoded Lua structures.
+Here's a Task that just dumps it's args.
+
+<pre>
+ require 'tir/engine'
+
+ function test(args)
+ Tir.dump(args)
+ end
+
+ Tir.Task.start { main = test, spec = 'ipc://run/photos' }
+</pre>
+
+And here's a sample Handler that can talk to it:
+
+<pre>
+ require 'tir/engine'
+
+ local conn = Tir.Task.connect { spec = 'ipc://run/photos' }
+
+ function main(web, req)
+ conn:send('photo', req.headers)
+ web:ok()
+ end
+
+ Tir.stateless {route='/Task', main=main}
+</pre>
+
+Unit Test Support
+-----------------
+
+New in 0.9, Tir now has decent unit testing in the tir/testing library and
+there's a sample test in the GettingStarted guide that shows how it's done.
+
+Async Ready
+-----------
+
+Because Tir uses Mongrel2 it already support async operation, streaming,
+regular HTTP, HTTP long poll, and flash/jssockets.
+
+No ORM
+------
+
+Tir comes without an ORM by default. People would probably hate any ORM I wrote
+and there's plenty of options you can add.
+
+No Core
+-------
+
+This isn't really a Tir feature, but do you hate when there's bugs in your core
+libraries and that guy who "owns" the broken library refuses to fix it? Me too,
+that's why Lua and LuaRocks are awesome. You get a tight core language that's
+completely described in_a_few_HTML_pages and then install all the platform
+libraries you need with LuaRocks.
+No more gatekeepers with Lua.

0 comments on commit cfd26b5

Please sign in to comment.