Open starius opened 9 years ago
+1 on this. Moonscript is cool, but learning (yet another) language in order to use lapis adds a hurdle to lapis adoption
+1 Man you did a great great job with lapis, but Moonscript is not cool. I don't like CofeeScript, I guess JavaScript and Lua are amazing languages so we don't need replace then.
I really like moonscript. It was easy to learn and understand the benefits of it, however, I still prefer to work in Lua as I'd much rather use etlua templates than pure script. This way it's pretty much web development as usual but with a much better framework.
I'm a bit confused what you guys think needs added. Is there some benefit to sub-apps (as classes) that I'm not aware of? From what I can tell, you can get the same functionality by including an external function and passing the app to it.
applications/foo.lua:
function foo(app)
app:get("/test", function(self)
return "bar"
end)
return app
end
return foo
app.lua:
require("applications.foo")(app)
-- or
subapp = require("applications.foo")
subapp(app)
Just an example. In this way you can add additional functionality or just keep things separate and clean.
Is there some benefit to sub-apps (as classes) that I'm not aware of?
You can add a path prefix to a sub-application. It is good for isolation between sub-applications and prevention of path collisions.
Examples like vain474's this are very helpful to me- thanks
Here's another alternative to sub-apps which may be useful. I like to keep all of my routes in the app.lua
file and call the actions from separate files:
app.lua:
--[[ ACTIONS ]]--
local function action(f)
local script = loadfile("actions/"..f..".lua")
if not script then
-- replace with your own error solution
return function(self)
self.title = "Woops..."
self.errormsg = "Action script not found for this page"
return { layout = nil, render = "error" }
end
end
return script(self)
end
--[[ ROUTES ]]--
-- INDEX --
app:get("index","/", action("index_get"))
...
then all you need is a Lua file that returns a function:
_actions/indexget.lua:
return function(self)
return "Welcome to Lapis " .. require("lapis.version")
end
This allows you to use the same function for multiple routes and possibly reduce code. With most of the routes being a single line it makes it very easy to see them all, and keep track of your path structure. This also comes in handy for splats, as you can add additional checks to determine which action to call, while still keeping routes separate from the logic.
The use of loadfile() for every route may impact performance (would this effect code cache?), so you might want to do your own testing to find what works best for your project. If anyone else has other examples for alternatives, I'd really like to see some. There's many different ways to do things, so a class solution might not be the best for everyone.
The use of loadfile() for every route may impact performance
So you can use require
instead of loadfile
.
That technique looks useful. I tried using require, didn't manage to get it to work. I had to change the script lookup to
local script = require("actions."..f)
but hitting the index page of the server resulted in the error
"...ce1/openresty/luajit/share/lua/5.1/lapis/application.lua:621: attempt to call local 'fn' (a string value)"
any hints? maybe it's just a lua thing that I'm missing, I'm pretty new to lua.
Check for typos. The example uses f
and your error says you're calling fn
. You would also need to change return script(self)
to just return script
. Or just call require
directly within the route:
app:get("index","/", require("actions.index_get"))
Using require
doesn't need the action
function. It was just used with the loadfile
example to keep things a little cleaner.
Thanks much for your suggestion. I didn't find any reference to 'fn', but I did get it going with with the require syntax that you suggested. In your original index_get.lua, you wrote return function(self)
- is there some way to add an argument besides self to that?
I tried a few different methods and kept running into the same fn
error you had. This is the only way I've had success:
local index_get = require("actions.index_get")
app:get("index","/", function(self)
return index_get(self,"foo")
end)
one-liner:
app:get("index","/", function(self) return require("actions.index_get")(self,"foo") end)
This is because self
can't be passed when using require
directly, as it doesn't exist yet. Routes seem to require the function to be anonymous.
oh well. thanks for the tips!
Thanks.. it works...
Currently, a sub-application is a class (Moonscript). Lua applications are instances, not classes. I want to use sub-applications written in Lua.