Created
December 18, 2008 14:14
-
-
Save reddavis/37506 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/ruby | |
require 'rubygems' | |
require 'mongrel' | |
# Add the request handler directory to the load path. | |
# Files in the 'app/controllers' dir will be mapped against the first segment | |
# of a URL | |
$LOAD_PATH.unshift( File.join( File.dirname( __FILE__ ) , 'app/controllers' ) ) | |
PORT = 4000 | |
# If true, controller source files are 'load'ed rather than 'require'd | |
# so you can tweak code and reload a page. | |
ALLOW_RELOADING = true | |
class String | |
def import | |
ALLOW_RELOADING ? load( self + '.rb' ) : require( self ) | |
end | |
def controller_class_name | |
self.capitalize | |
end | |
end | |
class MerberHandler < Mongrel::HttpHandler | |
def instantiate_controller(controller_name) | |
controller_name.import | |
begin | |
return Object.const_get( controller_name.controller_class_name ).new | |
rescue Exception | |
# If life is sad, then print the error and re-raise the exception: | |
warn "Error getting instance of '#{controller_name.controller_class_name}': #{$!}" | |
raise $! | |
end | |
end | |
# Grab the request URL and break it up to get the parts that map to the | |
# code request. There's a simple assumption that the first part defines a | |
# class holding the desired code. | |
def handle(request) | |
path = request.params["PATH_INFO"] | |
puts request.inspect | |
puts '='*50 | |
# Might want to consider returning a default object if we have a bare URL. | |
return [nil, nil, nil ] if path =~ /^\/$/ | |
c, m, args = path.to_s.gsub( /^\//, '' ).split( '/' , 3) | |
args = args.to_s.strip.empty? ? nil : args.split( '/' ) | |
# STDERR.puts( "handler_details returning #{h}, #{m}, #{args.inspect} ") | |
# Return an array with our object instance, the method name, and any args. | |
[ instantiate_controller(c), m, args ] | |
end | |
def process(request, response) | |
response.start(200) do |head,out| | |
head["Content-Type"] = "text/html" | |
begin | |
# Looks at the URL and breaks it up into | |
# chunks that map to a class, a method call, | |
# and arguments. | |
# Basically, | |
# /foo/bar/baz/baz | |
# ends up becoming | |
# Foo.new.bar( baz, baz ) | |
controller, method, args = handle(request) | |
if controller | |
# No allowance for default methods. | |
# Worth considering, maybe default to 'index' or 'to_s' | |
out << ( args ? controller.send( method, *args ) : | |
controller.send( method ) ) | |
else | |
out << "<html><body>Error: no merb controller found for this url.</body></html>" | |
end | |
rescue Exception | |
out << "<html>Error! #{$!}</html>" | |
end | |
end | |
end | |
end | |
h = Mongrel::HttpServer.new("0.0.0.0", PORT) | |
h.register("/", MerberHandler.new) | |
h.register("/", Mongrel::DirHandler.new("assets")) | |
h.run.join | |
--merb.rb--- | |
require 'erb' | |
class Merb | |
# Define a class variable to track the default location of the template | |
# files. | |
@@template_dir = File.expand_path( ( File.dirname( __FILE__ ) + "/../views/merb" ) ) | |
def hello(*names) | |
# Assign the parameter to an instance variable | |
@name = names.join(', ') | |
template = ERB.new( IO.read( @@template_dir + '/hello.rhtml' ) ) | |
template.result( binding ) | |
end | |
end | |
--hello.rhtml-- | |
<html> | |
<head> | |
<title>Hello, <%= @name %></title> | |
</head> | |
<body> | |
<h1>Hello, <%= @name %>!</h1> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment