Skip to content

Instantly share code, notes, and snippets.

@RyanScottLewis
Created May 27, 2011 05:22
Show Gist options
  • Select an option

  • Save RyanScottLewis/994683 to your computer and use it in GitHub Desktop.

Select an option

Save RyanScottLewis/994683 to your computer and use it in GitHub Desktop.
Ironing out details on a new web application library
require 'pp'
# The only thing you're really doing when defining a web aplication is setting
# attributes on your application class.
# For example, the following can be written many ways:
# in ./lib/app.rb
class MyApp < WebApplication
# This method just runs the given files within the scope of your
# application class in the order specified. This also loads the file into
# the same scope as the directory your file is in.
# For example, `load_files "configure/development"` will be the same
# as:
# configure do
# development do
# middleware { use Rack::Lint }
# end
# end
#
# Assuming the contents of configure/development.rb is:
# middleware { use Rack::Lint }
load_files "init", "**/*"
end
# in ./lib/init.rb
configure do
foo :bar
middleware do
use Rack::Lobster
end
end
configure.foo = "foo" # => "foo"
configure.foo("baz") # => "baz"
configure.foo do
"q" + "u" + "x"
end
routes.get("/") { render("index.haml") }
# in ./lib/configure.rb
foo "zap!"
# in ./lib/routes.rb
get("/foo") {
configure.foo
}
match("/bar", Bar)
# back in ./lib/app.rb
class MyApp < WebApplication
module Bar
def self.get
"Bar!"
end
end
end
# Now open a terminal and run `web_application console`:
# > p MyApp.configure.foo
# "zap!"
# > p MyApp.routes.get("/foo").call
# "zap!"
# The reason to setup this way is so that we can load your application's
# configurations as fast as possible when a handler is spawned.
# When caching is enabled, we don't even load these files,
# we marshal your application and load that.
# App showing off ALL features of WebApplication
class MyApp < WebApplication
configure do
dirs do
root File.expand_path(File.dirname(__FILE__)) # default
views File.join(root, 'views') # default
static File.join(root, 'public') # default
# Define custom dirs as well
images File.join(static, 'img')
end
middleware do
use Rack::Lint
end
# Set custom settings
foo :bar
# Settings for development, production, and test environments..
development do
middleware do
use Rack::CommonLogger, Logger.new(STDOUT)
end
foo :baz
end
production do
foo :qux
end
# Confusing but possible. Your whole application is nothing but a set of
# Arrays and Hashes which get utilized when your application is called.
test :foo => :tux, :middleware => [ [ Rack::Static, { :urls => ["/media"] } ] ]
# Set the default environment
environment :development # This is the default value
end
# We use Sequel for databases. Deal with it.
# Just kidding. There are wrappers for your favorite ORM.
models do
user do
schema do
primary_key :id
String :name
end
plugin :validation_helpers
validate do
validates_presence :name
validates_unique :name
validates_format /^\w+ \w+$/, :name, :message=>'is not a valid name'
end
end
end
# http://rubydoc.info/gems/sequel/3.23.0/Sequel/Migration
# Easily add migration tasks to Rake, Thor, etc..
# Let's emulate Rails, shall we?
# Rakefile:
# require 'my_app'
# task :migrate do
# MyApp.migrations.migrate(ENV['VERSION'])
# end
# task :rollback do
# ENV['STEP'].time do
# MyApp.models.rollback
# end
# end
views do
some_inline_template { "*#{action}s* YARG!" }
end
controller do
# before_all {}
# before("/", /^(yell|scream)$/) {}
# after_all {}
# after("/", /^(yell|scream)$/) {}
get "/" do
# p MyApp.configure.environment # => 'development' # or whatever.
render 'index.haml'
end
get /^(yell|scream)$/ do |action|
# request # => #<Rack::Request:0x000>
# params
render :some_inline_template, :locals => { :action => action }
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment