Class: Invisible

Inherits:
Object
  • Object
show all
Includes:
ERB::Util
Defined in:
lib/invisible.rb,
lib/invisible/erb.rb,
lib/invisible/haml.rb,
lib/invisible/mock.rb,
lib/invisible/erubis.rb,
lib/invisible/helpers.rb,
lib/invisible/reloader.rb

Overview

run app

Defined Under Namespace

Modules: MockMethods Classes: Reloader

Constant Summary collapse

HTTP_METHODS =
[:get, :post, :head, :put, :delete]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(&block) ⇒ Invisible

Creates a new Invisible Rack application. You can build your app in the yielded block or using the app instance.



26
27
28
29
30
# File 'lib/invisible.rb', line 26

def initialize(&block)
  @actions, @with, @loaded, @layouts, @views, @helpers, @app = [], [], [], {}, {}, self, method(:_call)
  @root = File.dirname(eval("__FILE__", block.binding))
  instance_eval(&block)
end

Instance Attribute Details

#actionsObject (readonly)

Returns the value of attribute actions.



22
23
24
# File 'lib/invisible.rb', line 22

def actions
  @actions
end

#paramsObject (readonly)

Returns the value of attribute params.



22
23
24
# File 'lib/invisible.rb', line 22

def params
  @params
end

#requestObject (readonly)

Returns the value of attribute request.



22
23
24
# File 'lib/invisible.rb', line 22

def request
  @request
end

#responseObject (readonly)

Returns the value of attribute response.



22
23
24
# File 'lib/invisible.rb', line 22

def response
  @response
end

Class Method Details

.run(*args, &block) ⇒ Object

Shortcut to Rack builder run method. Equivalent to:

app = Invisible.new do

...

end run app



176
177
178
# File 'lib/invisible.rb', line 176

def self.run(*args, &block)
  eval("self", block.binding).run new(&block)
end

Instance Method Details

#action(method, route, &block) ⇒ Object

Register an action for a specified route.

get "/" do
  # ...
end


44
45
46
# File 'lib/invisible.rb', line 44

def action(method, route, &block)
  @actions << [method.to_s, build_route(@with * "/" + route), block]
end

#call(env) ⇒ Object

Called by the Rack handler to process a request.



150
151
152
# File 'lib/invisible.rb', line 150

def call(env)
  @app.call(env)
end

#erb(file) ⇒ Object

Evaluate the Erubis template in file and returns the result as a string. Use with render:

render erb(:muffin)


12
13
14
15
# File 'lib/invisible/erb.rb', line 12

def erb(file)
  path = File.join(@root, "views", file.to_s)
  ERB.new(File.read("#{path}.erb")).result(binding)
end

#haml(file) ⇒ Object

Evaluate the Haml template in file and returns the result as a string. Use with render:

render haml(:muffin)


10
11
12
13
# File 'lib/invisible/haml.rb', line 10

def haml(file)
  path = File.join(@root, "views", file.to_s)
  Haml::Engine.new(File.read("#{path}.haml")).render(self)
end

#layout(name = :default, &block) ⇒ Object

Register a layout to be used around rendered text. Use markaby inside your block.



122
123
124
# File 'lib/invisible.rb', line 122

def layout(name=:default, &block)
  @layouts[name] = block
end


2
3
4
# File 'lib/invisible/helpers.rb', line 2

def link_to(title, url, options={})
  mab { a title, options.merge(:href => url) }
end

#load(file, options = {}) ⇒ Object

Load an external file inside the context of Invisible, which means you can use the get,post,with methods. The files loaded with this method will be reloaded in You’re using the Invisible Reloader middleware. Options: reload: false to not reload the file when Reloader middleware is in use.

(default: true)


161
162
163
164
165
166
# File 'lib/invisible.rb', line 161

def load(file, options={})
  return if @loaded.include?(file)
  @loaded << file unless FalseClass === options[:reload]
  path = File.join(@root, file) + ".rb"
  eval(File.read(path), binding, path)
end

#mab(&block) ⇒ Object

Return HTML rendered by evaluating the block using Markaby.



133
134
135
# File 'lib/invisible.rb', line 133

def mab(&block)
  Markaby::Builder.new({}, self, &block).to_s
end

#mockObject

Return a mocked request for the app. See: rack.rubyforge.org/doc/classes/Rack/MockRequest.html



4
5
6
# File 'lib/invisible/mock.rb', line 4

def mock
  @mock ||= Rack::MockRequest.new(@app)
end

#redirect_to(path, status = 302) ⇒ Object

Redirect to a path.

redirect_to "/login"

To do a permanent redirect, specify the status code as the last argument.

redirect_to "/", 301


116
117
118
# File 'lib/invisible.rb', line 116

def redirect_to(path, status=302)
  render(:status => status, "Location" => path) { p { text("You are redirected to "); a(path, :href => path) } }
end

#reload!Object

Reloader all the code loaded using the Invisible#load method. Use with the Reloader middleware.



4
5
6
7
8
9
# File 'lib/invisible/reloader.rb', line 4

def reload!
  loaded = @loaded.uniq
  @loaded = []
  [@actions, @with, @layouts, @views].each { |c| c.clear }
  loaded.each { |f| load(f) }
end

#render(*args, &block) ⇒ Object

Render the response inside an action. Render markaby by passing a block:

render do
  h1 "Poop"
  p "Smells!"
end

or simple text as the first argument:

render "crap"

or render a markaby view, created using the view method:

view :lolcat do
  p "i can has?"
end
render :lolcat

You can also pass some options or headers:

render "heck", :status => 201, :layout => :none, 'X-Crap-Level' => 'ubersome'

Supported options are: status: Status code of the response. layout: Name of the layout to use. All other options will be sent as a response header.



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/invisible.rb', line 90

def render(*args, &block)
  options  = args.last.is_a?(Hash) ? args.pop : {}
  
  # Extract options
  layout   = @layouts[options.delete(:layout) || :default]
  @response.status = options.delete(:status) || 200
  
  # Render inside the layout
  @content = args.last.is_a?(String) ? args.last : mab(&(block || @views[args.last]))
  @content = mab(&layout).to_s if layout
  
  # Set headers
  @response.headers.merge!(options)
  @response.headers["Content-Length"] ||= @content.size.to_s
  @response.headers["Last-Modified"]  ||= Time.now.httpdate
  @response.body = @content
end

#root(value = @root) ⇒ Object

Set the root of the app. Defaults to the file the Invisible class is instancianted in.



34
35
36
# File 'lib/invisible.rb', line 34

def root(value=@root)
  @root = value
end

#sessionObject

Return the current session. Add ‘use Rack::Session::Cookie` to use.



139
140
141
# File 'lib/invisible.rb', line 139

def session
  @request.env["rack.session"]
end

#use(middleware, *args) ⇒ Object

Register a Rack middleware wrapping the current application.



145
146
147
# File 'lib/invisible.rb', line 145

def use(middleware, *args)
  @app = middleware.new(@app, *args)
end

#view(name, &block) ⇒ Object

Register a named view to be used from render :name. Use markaby inside your block.



128
129
130
# File 'lib/invisible.rb', line 128

def view(name, &block)
  @views[name] = block
end

#with(route) ⇒ Object

Wrap actions sharing a common base route.

with "/lol" do
  get "/cat" # ...
end

Will register an action on GET /lol/cat. You can nested as many level as you want.



57
58
59
60
61
# File 'lib/invisible.rb', line 57

def with(route)
  @with.push(route)
  yield
  @with.pop
end