### Initialize Model Definitions Source: https://leafo.net/lapis/reference/models.html Setup models for use in subsequent class method examples. ```Lua local Model = require("lapis.db.model").Model local Users = Model:extend("users") local Tags = Model:extend("tags", { primary_key = {"user_id", "tag"} }) ``` ```MoonScript import Model from require "lapis.db.model" class Users extends Model class Tags extends Model @primary_key: {"user_id", "tag"} ``` -------------------------------- ### Start Lapis Server Source: https://leafo.net/lapis/reference/getting_started.html Command to initialize the server process in the current directory. ```bash $ lapis server ``` -------------------------------- ### Example Migration Module Source: https://leafo.net/lapis/reference/database.html A sample migration file structure that creates a new table. ```lua -- migrations.lua local schema = require("lapis.db.schema") local types = schema.types return { [1] = function() schema.create_table("articles", { { "id", types.serial }, { "title", types.text }, { "content", types.text }, "PRIMARY KEY (id)" }) end } ``` ```moonscript -- migrations.moon import create_table, types from require "lapis.db.schema" { [1]: => create_table "articles", { { "id", types.serial } { "title", types.text } { "content", types.text } "PRIMARY KEY (id)" } } ``` -------------------------------- ### Start the Lapis server Source: https://leafo.net/lapis/reference/lua_getting_started.html Command to launch the OpenResty server for the current project. ```bash lapis server ``` -------------------------------- ### Initialize app dependencies Source: https://leafo.net/lapis/reference/command_line.html Example command to generate a rockspec configured for MoonScript and SQLite. ```bash $ lapis generate rockspec --moonscript --sqlite ``` -------------------------------- ### Defining Basic Routes Source: https://leafo.net/lapis/reference/actions.html Examples of defining static routes that match paths verbatim. ```lua local lapis = require("lapis") local app = lapis.Application() app:match("/", function(self) end) app:match("/hello", function(self) end) app:match("/users/all", function(self) end) ``` ```moonscript lapis = require "lapis" class App extends lapis.Application "/": => "/hello": => "/users/all": => ``` -------------------------------- ### Examples of simulating requests Source: https://leafo.net/lapis/reference/command_line.html Common usage patterns for the simulate command. ```bash # Request the root page with a GET request lapis simulate / # Request the login page with form data in a POST request, output response as JSON lapis simulate /login --csrf --print-json -F username=bart -F password=cool ``` -------------------------------- ### Install Lapis Console via LuaRocks Source: https://leafo.net/lapis/reference/lapis_console.html Command to install the lapis-console package. ```bash $ luarocks install lapis-console ``` -------------------------------- ### Start Lapis Server with Environment Source: https://leafo.net/lapis/reference/configuration.html Specify the target environment when launching the Lapis server via the command line. ```bash $ lapis server [environment] ``` -------------------------------- ### Install Tableshape Source: https://leafo.net/lapis/reference/input_validation.html Command to install the Tableshape dependency via LuaRocks. ```bash $ luarocks install tableshape ``` -------------------------------- ### Install Lapis via LuaRocks Source: https://leafo.net/lapis/reference/getting_started.html Use this command to install the Lapis framework package into your Lua environment. ```bash $ luarocks install lapis ``` -------------------------------- ### Create a basic Lapis application Source: https://leafo.net/lapis Defines a simple route that returns a Hello World message. Requires the lapis module to be installed and loaded. ```lua local lapis = require "lapis" local app = lapis.Application() app:match("/", function(self) return "Hello world!" end) return app ``` ```moonscript lapis = require "lapis" class extends lapis.Application "/": => "Hello world!" ``` -------------------------------- ### Define a Lapis Application with Routes Source: https://leafo.net/lapis/reference/moon_getting_started.html A comprehensive example showing how to define routes and render HTML using a class that extends lapis.Application. ```MoonScript lapis = require "lapis" favorite_foods = { "pizza": "Wow pizza is the best! Definitely my favorite" "egg": "A classic breakfast, never leave home without" "ice cream": "Can't have a food list without a dessert" } class App extends lapis.Application [index: "/"]: => -- Render HTML inline for simplicity @html -> h1 "My homepage" a href: @url_for("list_foods"), "Check out my favorite foods" [list_foods: "/foods"]: => @html -> ul -> for food in pairs favorite_foods li -> a href: @url_for("food", name: food), food [food: "/food/:name"]: => food_description = favorite_foods[@params.name] unless food_description return "Not found", status: 404 @html -> h1 @params.name h2 "My thoughts on this food" p food_description ``` -------------------------------- ### Simple etlua template example Source: https://leafo.net/lapis/reference/etlua_templates.html A basic .etlua file demonstrating how to embed a Lua expression to generate dynamic content. ```html
Here is a random number: <%= math.random() %>
``` -------------------------------- ### SQL Query for Preloading Source: https://leafo.net/lapis/reference/models.html Example of the underlying SQL query generated during relation preloading. ```sql SELECT * from "users" where "id" in (3,4,5,6,7); ``` -------------------------------- ### Paginator SQL Output Source: https://leafo.net/lapis/reference/models.html Example SQL queries generated by the paginator. ```SQL SELECT * from "users" where group_id = 123 order by name asc limit 10 offset 0 SELECT * from "users" where group_id = 123 order by name asc limit 10 offset 50 ``` -------------------------------- ### Internal server start command Source: https://leafo.net/lapis/reference/command_line.html The command executed by Lapis to launch the Nginx process. ```bash $ nginx -p "$(pwd)"/ -c "nginx.conf.compiled" ``` -------------------------------- ### Install dependencies with LuaRocks Source: https://leafo.net/lapis/reference/command_line.html Command to install project dependencies locally using LuaRocks. ```bash $ luarocks --local --lua-version=5.1 build --only-deps ``` -------------------------------- ### Define a Simple Route and Action Source: https://leafo.net/lapis/reference/moon_getting_started.html A basic example of mapping a route pattern to a handler function in a Lapis application. ```MoonScript lapis = require "lapis" class App extends lapis.Application "/hello": => "Hello World!" ``` -------------------------------- ### Define an etlua template Source: https://leafo.net/lapis/reference/etlua_templates.html An example of an etlua template file structure. ```html
Welcome to my site!
``` -------------------------------- ### Defining Lapis Actions Source: https://leafo.net/lapis/reference/actions.html Examples of defining routes and actions using both Lua and MoonScript syntax. ```Lua local lapis = require("lapis") local app = lapis.Application() -- an unnamed action app:match("/", function(self) return "hello" end) -- an action with a name app:match("logout", "/logout", function(self) return {status = 404} end) -- a named action with a path parameter that loads the action function by -- module name app:match("profile", "/profile/:username", "user_profile") ``` ```MoonScript lapis = require "lapis" class App extends lapis.Application -- an unnamed action "/": => "hello" -- an action with a name [logout: "/logout"]: => status: 404 -- a named action with a path parameter that loads the action function by -- module name [profile: "/profile/:username"]: "user_profile" ``` -------------------------------- ### Installing lua-resty-http Dependencies Source: https://leafo.net/lapis/reference/utilities.html Required LuaRocks packages for using the lua-resty-http client. ```bash luarocks install lua-resty-http luarocks install lua-resty-openssl ``` -------------------------------- ### Defining Lapis Models Source: https://leafo.net/lapis/reference/models.html Basic setup for defining models with table associations. ```lua local Model = require("lapis.db.model").Model -- table with columns: id, name local Users = Model:extend("users") -- table with columns: id, user_id, text_content local Posts = Model:extend("posts") ``` ```moonscript import Model from require "lapis.db.model" -- table with columns: id, name class Users extends Model -- table with columns: id, user_id, text_content class Posts extends Model ``` -------------------------------- ### Template Rendering Source: https://leafo.net/lapis Examples of using etlua templates or the Widget class for structured HTML generation. ```etlua

<%= "Hello" %>

<% if current_user then %>
Welcome back <%= current_user.name %>
<% end %>
Welcome to my site
``` ```MoonScript import Widget from require "lapis.html" class Index extends Widget content: => h1 class: "header", "Hello" @user_panel! div class: "body", -> text "Welcome to my site!" user_panel: => return unless @current_user div class: "user_panel", "Welcome back " .. @current_user.name ``` -------------------------------- ### Perform HTTP Requests with lapis.http Source: https://leafo.net/lapis/reference/utilities.html Demonstrates basic GET and POST requests using the lapis.http module and LTN12 for data handling. ```lua local http = require("lapis.http") local ltn12 = require("ltn12") -- a simple GET request local body, status_code, headers = http.request("http://leafo.net") -- a simple POST request local out = {} local _, status_code, headers = http.request({ url = "http://leafo.net", method = "POST", headers = { ["Content-type"] = "application/x-www-form-urlencoded" }, source = ltn12.source.string("param1=value1¶m2=value2"), sink = ltn12.sink.table(out) }) local body = table.concat(out) ``` ```moonscript http = require "lapis.http" ltn12 = require "ltn12" -- a simple GET request body, status_code, headers = http.request "http://leafo.net" out = {} _, status_code, headers = http.request { url: "http://leafo.net", method: "POST", headers: { ["Content-type"] = "application/x-www-form-urlencoded" } source: ltn12.source.string "param1=value1¶m2=value2" sink ltn12.sink.table(out) } body = table.concat out ``` -------------------------------- ### Test Application with Busted Source: https://leafo.net/lapis/reference/testing.html Example of testing a Lapis application route using the Busted framework. ```Lua local lapis = require("lapis.application") local simulate_request = require("lapis.spec.request").simulate_request local app = lapis.Application() app:match("/hello", function(self) return "welcome to my page" end) describe("my application", function() it("should make a request", function() local status, body = simulate_request(app, "/hello") assert.same(200, status) assert.truthy(body:match("welcome")) end) end) ``` ```MoonScript lapis = require "lapis" import simulate_request from require "lapis.spec.request" class App extends lapis.Application "/hello": => "welcome to my page" describe "my application", -> it "should make a request", -> status, body = simulate_request App, "/hello" assert.same 200, status assert.truthy body\match "welcome" ``` -------------------------------- ### HTTP Verb Wrappers Source: https://leafo.net/lapis/reference/actions.html Use convenience methods like get and delete as wrappers around respond_to for common HTTP verbs. ```lua app:get("/test", function(self) return "I only render for GET requests" end) app:delete("/delete-account", function(self) -- do something destructive end) ``` -------------------------------- ### Generate HTML tags with Lua and MoonScript Source: https://leafo.net/lapis/reference/html_generation.html Basic examples of tag generation, attributes, and nested content using the HTML builder environment. ```lua div() --
b("Hello World") -- Hello World div("hi
") --
hi<br/>
text("Hi!") -- Hi! raw("
") --
br() --
element("table", { width = "100%" }) --
div({ class = "footer" }, "The Foot") -- input({ required = true }) -- div(function() text("Hey") end) --
Hey
div({ class = "header" }, function() h2("My Site") p("Welcome!") end) --

My Site

--

Welcome!

``` ```moonscript div! --
b "Hello World" -- Hello World div "hi
" --
hi<br/>
text "Hi!" -- Hi! raw "
" --
element "table", width: "100%", -> --
div class: "footer", "The Foot" -- input required: true -- div -> --
Hey
text "Hey" div class: "header", -> --

My Site

h2 "My Site" --

Welcome!

p "Welcome!" ``` -------------------------------- ### Setting up a User Session with Before Filters Source: https://leafo.net/lapis/reference/actions.html Demonstrates initializing a current user from the session before an action executes. ```Lua local app = lapis.Application() app:before_filter(function(self) if self.session.user then self.current_user = load_user(self.session.user) end end) app:match("/", function(self) return "current user is: " .. tostring(self.current_user) end) ``` ```MoonScript lapis = require "lapis" class App extends lapis.Application @before_filter => if @session.user @current_user = load_user @session.user "/": => "current user is: #{@current_user}" ``` -------------------------------- ### Initialize a new Lapis project Source: https://leafo.net/lapis/reference/getting_started.html Generates the default project structure including nginx.conf, mime.types, app.lua, and config.lua. ```bash $ lapis new wrote nginx.conf wrote mime.types wrote app.lua wrote config.lua ``` ```bash $ lapis new --cqueues ``` -------------------------------- ### Define an Events Model Source: https://leafo.net/lapis/reference/models.html Example model definition for an events table. ```Lua create_table("events", { { "id", types.serial }, { "user_id", types.foreign_key }, { "data", types.text }, "PRIMARY KEY(id)" }) local Events = Model:extend("events") ``` ```MoonScript create_table "events", { { "id", types.serial } { "user_id", types.foreign_key } { "data", types.text } "PRIMARY KEY(id)" } class Events extends Model ``` -------------------------------- ### Initialize a new Lapis project Source: https://leafo.net/lapis/reference/command_line.html Displays the usage and available options for the 'lapis new' command to scaffold a new project. ```text Usage: lapis new ([--nginx] | [--cqueues]) ([--lua] | [--moonscript]) [-h] [--etlua-config] [--git] [--tup] [--rockspec] [--force] Create a new Lapis project in the current directory Options: -h, --help Show this help message and exit. --nginx Generate config for nginx server (default) --cqueues Generate config for cqueues server --lua Generate app template file in Lua (default) --moonscript, --moon Generate app template file in MoonScript --etlua-config Use etlua for templated configuration files (eg. nginx.conf) --git Generate default .gitignore file --tup Generate default Tupfile --rockspec Generate a rockspec file for managing dependencies --force Bypass errors when detecting functional server environment ``` -------------------------------- ### Initialize a new Lapis project with MoonScript Source: https://leafo.net/lapis/reference/moon_getting_started.html Run this command in your terminal to generate the default project structure including nginx.conf and app.moon. ```bash $ lapis new --moonscript ``` -------------------------------- ### Generated HTML output Source: https://leafo.net/lapis/reference/html_generation.html The resulting HTML output from the class attribute example. ```html
Hello world!
``` -------------------------------- ### MoonScript Configuration DSL and Resulting Table Source: https://leafo.net/lapis/reference/moon_creating_configurations.html Demonstrates the configuration DSL syntax using function calls and logic, alongside the resulting table structure. ```moonscript some_function = -> steak "medium_well" config "development", -> hello "world" if 20 > 4 color "blue" else color "green" custom_settings -> age 10 enabled true -- tables are merged extra -> name "leaf" mood "happy" extra -> name "beef" shoe_size 12 include some_function include some_function -- a normal table can be passed instead of a function some_list { 1,2,3,4 } -- use set to assign names that are unavailable set "include", "hello" ``` ```moonscript { hello: "world" color: "blue" custom_settings: { age: 10 enabled: true } extra: { name: "beef" mood: "happy" shoe_size: 12 steak: "medium_well" } steak: "medium_well" some_list: { 1,2,3,4 } include: "hello" } ``` -------------------------------- ### Initialize Database Module Source: https://leafo.net/lapis/reference/database.html Load the Lapis database module to access query functions. ```Lua local db = require("lapis.db") ``` ```MoonScript db = require "lapis.db" ``` -------------------------------- ### Reading a cookie value Source: https://leafo.net/lapis/reference/actions.html A simple example of reading a specific cookie value by name. ```Lua app:match("/reads-cookie", function(self) print(self.cookies.foo) end) ``` -------------------------------- ### Registering routes with application:match (Instance approach) Source: https://leafo.net/lapis/reference/actions.html Defines routes by creating an instance of the Lapis Application class. ```lua local app = lapis.Application() app:match("index", "/index", function(self) return "Hello world!" end) app:match("/about", function(self) return "My site is cool" end) ``` ```moonscript app = lapis.Application! app\match "index", "/index", => "Hello world!" app\match "/about", => "My site is cool" ``` -------------------------------- ### Run migrations via CLI Source: https://leafo.net/lapis/reference/command_line.html Displays the help and usage information for the lapis migrate command. ```text Usage: lapis migrate [-h] [--migrations-module ] [] [--transaction [{global,individual}]] Run any outstanding migrations Arguments: environment Options: -h, --help Show this help message and exit. --migrations-module Module to load for migrations (default: migrations) --transaction [{global,individual}] ``` -------------------------------- ### Initialize HTML Module Source: https://leafo.net/lapis/reference/html_generation.html Basic requirement of the Lapis HTML module. ```MoonScript html = require "lapis.html" ``` -------------------------------- ### Generate SQL Clause Source: https://leafo.net/lapis/reference/database.html Example of the SQL output generated by the database clause builder. ```sql SELECT * FROM profiles WHERE (username like '%admin') AND (views_count > 100) AND ("active" OR "promoted") AND "status" IN (3, 4) AND "id" = 12 AND not "deleted", ``` -------------------------------- ### Generate a new Lapis project Source: https://leafo.net/lapis/reference/lua_getting_started.html Initializes a new Lapis project skeleton in the current directory. ```bash $ lapis new ``` -------------------------------- ### Migrating from flip and local_key with custom keys Source: https://leafo.net/lapis/reference/models.html Shows how to map custom local keys without using the deprecated flip option. ```lua UserData:include_in(users, "user_id", { flip = true, local_key = "internal_id" }) UserData:include_in(users, { user_id = "internal_id" }) ``` ```moonscript UserData\include_in users, "user_id", flip: true, local_key: "internal_id" UserData\include_in users, user_id: "internal_id" ``` -------------------------------- ### Initialize Test Server Source: https://leafo.net/lapis/reference/testing.html Use use_test_server to manage the lifecycle of the test server within your spec blocks. ```lua local use_test_server = require("lapis.spec").use_test_server describe("my site", function() use_test_server() -- write some tests that use the server here end) ``` ```moonscript import use_test_server from require "lapis.spec" describe "my_site", -> use_test_server! -- write some tests that use the server here ``` -------------------------------- ### Migrating from flip and local_key Source: https://leafo.net/lapis/reference/models.html Demonstrates replacing deprecated flip and local_key options with column mapping tables. ```lua UserData:include_in(users, "user_id", { flip = true }) UserData:include_in(users, { user_id = "id" }) ``` ```moonscript UserData\include_in users, "user_id", flip: true UserData\include_in users, user_id: "id" ``` -------------------------------- ### Define Model Table Schema Source: https://leafo.net/lapis/reference/models.html Example schema definition for a users table using Lapis types. ```Lua create_table("users", { { "id", types.serial }, { "name", types.varchar }, { "group_id", types.foreign_key }, "PRIMARY KEY(id)" }) local Users = Model:extend("users") ``` ```MoonScript create_table "users", { { "id", types.serial } { "name", types.varchar } { "group_id", types.foreign_key } "PRIMARY KEY(id)" } class Users extends Model ``` -------------------------------- ### Initializing widgets with options Source: https://leafo.net/lapis/reference/html_generation.html Passing parameters to the widget constructor to override fields or set render-time data. ```Lua local Widget = require("lapis.html").Widget local SomeWidget = Widget:extend({ content = function(self) div("Hello ", self.name) end }) local w = SomeWidget({ name = "Garf" }) print(widget:render_to_string()) -->
Hello Garf
``` ```MoonScript class SomeWidget extends html.Widget content: => div "Hello ", @name widget = SomeWidget name: "Garf" print widget\render_to_string! -->
Hello Garf
``` -------------------------------- ### Defining Named Routes Source: https://leafo.net/lapis/reference/actions.html Examples of defining named routes in both Lua and MoonScript for use with URL generation. ```Lua app:match("index", "/", function() -- ... end) app:match("user_data", "/data/:user_id/:data_field", function() -- ... end) ``` ```MoonScript class App extends lapis.Application [index: "/"]: => -- .. [user_data: "/data/:user_id/:data_field"]: => -- ... ``` -------------------------------- ### Define Application Routes Source: https://leafo.net/lapis Demonstrates defining routes and using HTML builder syntax for rendering responses. ```Lua local lapis = require "lapis" local app = lapis.Application() -- Define a basic pattern that matches / app:match("/", function(self) local profile_url = self:url_for("profile", {name = "leafo"}) -- Use HTML builder syntax helper to quickly and safely write markup return self:html(function() h2("Welcome!") text("Go to my ") a({href = profile_url}, "profile") end) end) -- Define a named route pattern with a variable called name app:match("profile", "/:name", function(self) return self:html(function() div({class = "profile"}, "Welcome to the profile of " .. self.params.name) end) end) return app ``` ```MoonScript lapis = require "lapis" class extends lapis.Application -- Define a basic pattern that matches / "/": => profile_url = @url_for "profile", name: "leafo" -- Use HTML builder syntax helper to quickly and safely write markup @html -> h2 "Welcome!" text "Go to my " a href: profile_url, "profile" -- Define a named route pattern with a variable called name [profile: "/:name"]: => @html -> div class: "profile", -> text "Welcome to the profile of ", @params.name ``` -------------------------------- ### Specify OpenResty binary location Source: https://leafo.net/lapis/reference/command_line.html Example of overriding the OpenResty binary path using an environment variable. ```bash LAPIS_OPENRESTY=/home/leafo/bin/openresty lapis server ``` -------------------------------- ### Manually Create Migrations Table Source: https://leafo.net/lapis/reference/database.html Initialize the migrations tracking table in the database. ```lua local migrations = require("lapis.db.migrations") migrations.create_migrations_table() ``` ```moonscript migrations = require "lapis.db.migrations" migrations.create_migrations_table! ``` -------------------------------- ### Define Nginx worker connections Source: https://leafo.net/lapis/reference/configuration.html Example of using interpolated variables within an Nginx configuration block. ```nginx events { worker_connections ${{WORKER_CONNECTIONS}}; } ``` -------------------------------- ### Define Environment Configurations Source: https://leafo.net/lapis/reference/configuration.html Sets up environment-specific variables for development and production environments. ```lua local config = require("lapis.config") config("development", { port = 8080 }) config("production", { port = 80, num_workers = 4, code_cache = "on" }) ``` ```moonscript -- config.moon config = require "lapis.config" config "development", -> port 8080 config "production", -> port 80 num_workers 4 code_cache "on" ``` -------------------------------- ### Iterate through pages with OrderedPaginator Source: https://leafo.net/lapis/reference/models.html Use OrderedPaginator to iterate through database results. The iterator supports optional starting cursors. ```Lua local OrderedPaginator = require("lapis.db.pagination").OrderedPaginator local pager = OrderedPaginator(Events, "id", "where user_id = ?", 123) -- iterate through all pages from the beginning for page_results in pager:each_page() do process(page_results) end -- iterate starting from id > 500 for page_results in pager:each_page(500) do process(page_results) end ``` ```MoonScript import OrderedPaginator from require "lapis.db.pagination" pager = OrderedPaginator Events, "id", "where user_id = ?", 123 -- iterate through all pages from the beginning for page_results in pager\each_page! process page_results -- iterate starting from id > 500 for page_results in pager\each_page 500 process page_results ``` -------------------------------- ### Registering routes with application:match (Class approach) Source: https://leafo.net/lapis/reference/actions.html Defines routes by extending the Lapis Application class. ```lua local app = lapis.Application:extend() app:match("index", "/index", function(self) return "Hello world!" end) app:match("/about", function(self) return "My site is cool" end) ``` ```moonscript class extends lapis.Application @match "index", "/index", => "Hello world!" @match "/about", => "My site is cool" ``` -------------------------------- ### Display Lapis help information Source: https://leafo.net/lapis/reference/getting_started.html Use this command to view available Lapis CLI commands and options. ```bash $ lapis help ``` -------------------------------- ### Overriding Default Route for Logging Source: https://leafo.net/lapis/reference/actions.html Example of extending the default route to add custom logging while preserving original functionality. ```lua function app:default_route() ngx.log(ngx.NOTICE, "User hit unknown path " .. self.req.parsed_url.path) -- call the original implementation to preserve the functionality it provides return lapis.Application.default_route(self) end ``` ```moonscript class App extends lapis.Application default_route: => ngx.log ngx.NOTICE, "User hit unknown path #{@req.parsed_url.path}" super! ``` -------------------------------- ### Define and Merge Configurations Source: https://leafo.net/lapis/reference/lua_creating_configurations.html Use the config function to define base settings and override them for specific environments like development or production. ```lua -- config.lua local config = require("lapis.config") config({"development", "production"}, { host = "example.com", email_enabled = false, postgres = { host = "localhost", port = "5432", database = "my_app" } }) config("production", { email_enabled = true, postgres = { database = "my_app_prod" } }) ``` -------------------------------- ### Running HTTPS Requests via resty CLI Source: https://leafo.net/lapis/reference/utilities.html Example of passing SSL configuration directives to the resty CLI tool. ```bash resty --http-conf "lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt; lua_ssl_verify_depth 2;" -e 'print(require("lapis.nginx.resty_http").request("https://example.com"))' ``` -------------------------------- ### Configure Lapis application to render views Source: https://leafo.net/lapis/reference/lua_getting_started.html Enable etlua support and define a route that renders the index view. ```lua -- app.lua local lapis = require("lapis") local app = lapis.Application() app:enable("etlua") app:get("/", function(self) return { render = "index" } end) return app ``` -------------------------------- ### Create with custom returning options Source: https://leafo.net/lapis/reference/models.html Specify custom columns to return after insertion using the create_opts table. ```Lua Users:create({ profile_color = "blue" }, { returning = "*" }) ``` ```MoonScript Users\create { profile_color: "blue" }, returning: "*" ``` -------------------------------- ### console.make([opts]) Source: https://leafo.net/lapis/reference/lapis_console.html Creates an action to be used in a Lapis application route to enable the interactive console. ```APIDOC ## console.make([opts]) ### Description Creates a Lapis action that serves the interactive console. This should be mapped to a route in your application. ### Parameters - **opts** (table) - Optional - Configuration options for the console. - **env** (string) - Optional - The environment in which the console is enabled. Defaults to "development". Set to "all" to enable in all environments. ``` -------------------------------- ### Instantiating and Using a Flow Source: https://leafo.net/lapis/reference/flows.html Initialize a flow with an object and invoke its methods, which will proxy calls to the underlying object. ```Lua local obj = { name = "Pizza Zone", age = "2000 Years", get_greeting = function(self) -- self will always be obj, not a flow instance, even if called through a -- flow return "Hello from " .. self.name end } local flow = FormatterFlow(obj) print(flow:format_name()) --> "Pizza Zone (age: 2000 Years)" flow:print_greeting() --> "Hello from Pizza Zone" ``` ```MoonScript obj = { name: "Pizza Zone" age: "2000 Years" get_greeting: => -- @ will always be obj, not a flow instance, even if called through a -- flow "Hello from #{@name}" } flow = FormatterFlow(obj) print flow\format_name! --> "Pizza Zone (age: 2000 Years)" flow\print_greeting! --> "Hello from Pizza Zone" ``` -------------------------------- ### Handle HTTP verbs with respond_to Source: https://leafo.net/lapis/reference/quick_reference.html Use the respond_to decorator to define logic for different HTTP methods and shared setup via the before hook. ```lua local lapis = require("lapis") local app = lapis.Application() local respond_to = require("lapis.application").respond_to app:match("/", respond_to({ -- do common setup before = function(self) if self.session.current_user then self:write({ redirect_to = "/" }) end end, -- render the view GET = function(self) return { render = true } end, -- handle the form submission POST = function(self) self.session.current_user = try_to_login(self.params.username, self.params.password) return { redirect_to = "/" } end })) ``` ```moonscript lapis = require "lapis" import respond_to from require "lapis.application" class App extends lapis.Application "/login": respond_to { before: => -- do common setup if @session.current_user @write redirect_to: "/" GET: => -- render the view render: true POST: => -- handle the form submission @session.current_user = try_to_login(@params.username, @params.password) redirect_to: "/" } ``` -------------------------------- ### Test helper functions with stub_request Source: https://leafo.net/lapis/reference/testing.html Example usage of stub_request within a test suite to verify URL generation, parameter handling, and session access. ```Lua local lapis = require("lapis") local stub_request = require("lapis.spec.request").stub_request local app = lapis.Application() app:match("user_profile", "/user/:id", function(self) end) describe("my helper", function() it("generates correct URLs", function() local req = stub_request(app, "/") assert.same("/user/123", req:url_for("user_profile", {id = 123})) end) it("has access to params", function() local req = stub_request(app, "/test", { post = {name = "hello"}, params = {id = "5"} }) assert.same("hello", req.params.name) assert.same("5", req.params.id) end) it("has access to session", function() local req = stub_request(app, "/", { session = {user_id = 101} }) assert.same(101, req.session.user_id) end) end) ``` ```MoonScript lapis = require "lapis" import stub_request from require "lapis.spec.request" class App extends lapis.Application [user_profile: "/user/:id"]: => describe "my helper", -> it "generates correct URLs", -> req = stub_request App, "/" assert.same "/user/123", req\url_for "user_profile", id: 123 it "has access to params", -> req = stub_request App, "/test", { post: {name: "hello"} params: {id: "5"} } assert.same "hello", req.params.name assert.same "5", req.params.id it "has access to session", -> req = stub_request App, "/", { session: {user_id: 101} } assert.same 101, req.session.user_id ``` -------------------------------- ### Configure Multiple Environments Source: https://leafo.net/lapis/reference/configuration.html Applies the same configuration settings to multiple environments simultaneously by passing an array of names. ```lua config({"development", "production"}, { session_name = "my_app_session" }) ``` ```moonscript config {"development", "production"}, -> session_name "my_app_session" ``` -------------------------------- ### cache.cached(fn_or_tbl) Source: https://leafo.net/lapis/reference/utilities.html Wraps an action to use the memory cache. The cache stores the output, content type, and status code, keyed by the request path and GET parameters. ```APIDOC ## cache.cached(fn_or_tbl) ### Description Wraps an action to use the cache. The first request runs the action and stores the result; subsequent requests return the cached result. The cache key includes the request path and sorted GET parameters. ### Parameters - **fn_or_tbl** (function or table) - Required - The action function to wrap, or a table containing the function and configuration options (dict_name, exptime, cache_key, when). ``` -------------------------------- ### Create with raw SQL values Source: https://leafo.net/lapis/reference/models.html Use db.raw to insert computed values, which are then fetched back via the RETURNING clause. ```Lua local user = Users:create({ position = db.raw("(select coalesce(max(position) + 1, 0) from users)") }) ``` ```MoonScript user = Users\create { position: db.raw "(select coalesce(max(position) + 1, 0) from users)" } ``` ```SQL INSERT INTO "users" (position) VALUES ((select coalesce(max(position) + 1, 0) from users)) RETURNING "id", "position" ``` -------------------------------- ### http.request(url_or_table) Source: https://leafo.net/lapis/reference/utilities.html Performs an HTTP request. Can accept a URL string for a simple GET request or a table containing request configuration (url, method, headers, source, sink) for more complex operations. ```APIDOC ## http.request(url_or_table) ### Description Performs an HTTP request. When a string is provided, it performs a GET request. When a table is provided, it allows for custom methods, headers, and data streaming using LTN12. ### Parameters - **url_or_table** (string|table) - Required - The target URL string or a configuration table containing 'url', 'method', 'headers', 'source', and 'sink'. ### Returns - **body** (string|nil) - The response body. - **status_code** (number) - The HTTP status code. - **headers** (table) - The response headers. ``` -------------------------------- ### Display Lapis CLI Help Source: https://leafo.net/lapis/reference/command_line.html Run the lapis command without arguments to view the usage summary, available commands, and environment details. ```bash Usage: lapis [-h] [--environment ] [--config-module ] [--trace] ... Control & create web applications written with Lapis Lapis: 1.14.0 Default environment: development OpenResty: /usr/local/openresty/nginx/sbin/nginx cqueues: 20200726 lua-http: 0.4 Options: -h, --help Show this help message and exit. --environment Override the environment name --config-module Override module name to require configuration from (default: config) --trace Show full error trace if lapis command fails Commands: help Show help for commands. new Create a new Lapis project in the current directory server, serve Start the server from the current directory build Rebuild configuration and send a reload signal to running server (server: nginx) term Sends TERM signal to shut down a running server (server: nginx) exec, execute Execute Lua on the server (server: nginx) migrate Run any outstanding migrations generate Generates a new file in the current directory from template simulate Execute a mock HTTP request to your application code without any server involved ``` -------------------------------- ### Define a basic Lapis application Source: https://leafo.net/lapis/reference/lua_getting_started.html A standard app.lua file structure for a Lapis application. ```lua -- app.lua local lapis = require("lapis") local app = lapis.Application() app:get("/", function() return "Welcome to Lapis " .. require("lapis.version") end) return app ``` -------------------------------- ### Manually Run Migrations Source: https://leafo.net/lapis/reference/database.html Execute pending migrations from a specified module. ```lua local migrations = require("lapis.db.migrations") migrations.run_migrations(require("migrations")) ``` ```moonscript import run_migrations from require "lapis.db.migrations" run_migrations require "migrations" ``` -------------------------------- ### Simulate HTTP requests Source: https://leafo.net/lapis/reference/command_line.html Displays the help and usage information for the lapis simulate command. ```text Usage: lapis simulate [-h] [--app-class ] [--helper ] [--method {GET,POST,PUT,DELETE,OPTIONS,HEAD,PATCH}] [--body ] [--form
] [--header
] [--host ] [--scheme ] [--json] [--csrf] [--print-headers] [--print-json] Execute a mock HTTP request to your application code without any server involved Arguments: path Path to request, may include query parameters (eg. /) Request control: --method {GET,POST,PUT,DELETE,OPTIONS,HEAD,PATCH} HTTP method (default: GET) --body Body of request, - for stdin --form , Set method to POST if unset, content type to application/x-www-form-urlencoded, and body to value of this option -F --header
, Append an input header, can be used multiple times (can overwrite set headers from other options -H
--host Set the host header of request --scheme Override default scheme (eg. https, http) --json Set accept header to application/json --csrf Set generated CSRF header and parameter for form requests Display options: --print-headers Print only the headers as JSON --print-json Print the entire response as JSON Other options: -h, --help Show this help message and exit. --app-class Override default app class module name --helper Module name to require before loading app ``` -------------------------------- ### application:include(other_app, opts={}) Source: https://leafo.net/lapis/reference/actions.html Copies all routes from another application into the current application, optionally applying path or name prefixes. ```APIDOC ## application:include(other_app, opts={}) ### Description Copies all the routes from other_app into the current app. If there are any before filters in other_app, every action of other_app will be wrapped in a new function that calls those before filters. ### Parameters - **other_app** (table) - Required - The application class or instance to include. - **opts** (table) - Optional - Configuration options including 'path' (prefix for paths) and 'name' (prefix for route names). ``` -------------------------------- ### Perform HTTP Requests to Test Server Source: https://leafo.net/lapis/reference/testing.html Use the request helper to send HTTP requests to the running test server and inspect the response. ```lua local request = require("lapis.spec.server").request local use_test_server = require("lapis.spec").use_test_server describe("my site", function() use_test_server() it("should load /", function() local status, body, headers = request("/") assert.same(200, status) end) end) ``` ```moonscript import use_test_server from require "lapis.spec" import request from require "lapis.spec.server" describe "my_site", -> use_test_server! it "should load /", -> status, body, headers = request "/" assert.same 200, status ``` -------------------------------- ### Render a widget from an action Source: https://leafo.net/lapis/reference/html_generation.html Return a table with the render key to specify which widget to display. ```Lua app:match("/", function() return {render = "index"} end) ``` ```MoonScript "/": => render: "index" ``` -------------------------------- ### Create a Paginator Source: https://leafo.net/lapis/reference/models.html Initialize an OffsetPaginator for a model query. ```Lua local paginated = Users:paginated([[where group_id = ? order by name asc]], 123) ``` ```MoonScript paginated = Users\paginated [[where group_id = ? order by name asc]], 123 ``` -------------------------------- ### Require Application Helpers Source: https://leafo.net/lapis/reference/utilities.html Import the application module using Lua or MoonScript syntax. ```lua local app_helpers = require("lapis.application") ``` ```moonscript application = require "lapis.application" ``` -------------------------------- ### Simulate Sequential Requests Source: https://leafo.net/lapis/reference/testing.html Use the prev option to pass headers from a previous request to maintain state like cookies or sessions. ```Lua local r1_status, r1_res, r1_headers = simulate_request(my_app, "/first_url") local r2_status, r2_res = simulate_request(my_app, "/second_url", { prev = r1_headers }) ``` ```MoonScript r1_status, r1_res, r1_headers = simulate_request MyApp!, "/first_url" r2_status, r2_res = simulate_request MyApp!, "/second_url", prev: r1_headers ``` -------------------------------- ### Define fetch with preload Source: https://leafo.net/lapis/reference/models.html Using fetch = true with a custom preload function for bulk loading. ```Lua local Model = require("lapis.db.model").Model local Users = Model:extend("users", { relations = { {"recent_posts", -- we can use true here to have the singular getter automatically -- generated based on the preload function fetch = true, preload = function(objs) for object in pairs(objs) do -- provide your own preload code and store the result on the object object.recent_posts = some_preloading_code(object) end end, } } }) ``` ```MoonScript import Model from require "lapis.db.model" class Users extends Model @relations: { {"recent_posts" -- we can use true here to have the singular getter automatically -- generated based on the preload function fetch: true preload: (objs) -> for object in *objs -- provide your own preload code and store the result on the object object.recent_posts = some_preloading_code object } } ``` -------------------------------- ### Create a database table Source: https://leafo.net/lapis/reference/database.html Defines a new table structure using column definitions and constraints. ```lua local schema = require("lapis.db.schema") local types = schema.types schema.create_table("users", { {"id", types.serial}, {"username", types.varchar}, "PRIMARY KEY (id)" }) ``` ```moonscript schema = require "lapis.db.schema" import create_table, types from schema create_table "users", { {"id", types.serial} {"username", types.varchar} "PRIMARY KEY (id)" } ``` -------------------------------- ### Generate migration files Source: https://leafo.net/lapis/reference/command_line.html Syntax for generating or updating database migration files. ```bash Usage: lapis generate migration ([--lua] | [--moonscript]) [-h] [--counter {timestamp,increment}] [--migrations-module ] Generate a migrations file if necessary, and append a new migration to the file Options: -h, --help Show this help message and exit. --counter {timestamp,increment} Naming convention for new migration (default: timestamp) --migrations-module , --module The module name of the migrations file (default: migrations) --lua Force editing/creating Lua file --moonscript, --moon Force editing/creating MoonScript file ``` -------------------------------- ### Generate Migration Stub Source: https://leafo.net/lapis/reference/database.html Use the CLI to scaffold a new migration entry in the migrations module. ```bash $ lapis generate migration --moonscript Created migration: 1694285420 ```