Class: Utopia::Controller

Inherits:
Object
  • Object
show all
Defined in:
lib/utopia/controller.rb,
lib/utopia/controller/base.rb,
lib/utopia/controller/action.rb,
lib/utopia/controller/rewrite.rb,
lib/utopia/controller/variables.rb

Defined Under Namespace

Modules: Rewrite Classes: Action, Base, RewriteError, Variables

Constant Summary collapse

CONTROLLER_RB =
'controller.rb'.freeze
PATH_INFO_KEY =
'PATH_INFO'.freeze
EMPTY_BODY =
[].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, **options) ⇒ Controller

Returns a new instance of Controller.



48
49
50
51
52
53
54
55
# File 'lib/utopia/controller.rb', line 48

def initialize(app, **options)
	@app = app
	@root = options[:root] || Utopia::default_root

	@controllers = {}
	
	@cache_controllers = options[:cache_controllers] || false
end

Instance Attribute Details

#appObject (readonly)

Returns the value of attribute app.



57
58
59
# File 'lib/utopia/controller.rb', line 57

def app
  @app
end

Instance Method Details

#call(env) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
# File 'lib/utopia/controller.rb', line 126

def call(env)
	variables = (env[VARIABLES_KEY] ||= Variables.new)
	
	request = Rack::Request.new(env)
	
	if result = invoke_controllers(request)
		return result
	end
	
	return @app.call(env)
end

#invoke_controllers(request) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/utopia/controller.rb', line 98

def invoke_controllers(request)
	relative_path = Path[request.path_info]
	controller_path = Path.new
	variables = request.env[VARIABLES_KEY]
	
	while relative_path.components.any?
		controller_path.components << relative_path.components.shift
		
		if controller = lookup_controller(controller_path)
			# Don't modify the original controller:
			controller = controller.clone
			
			# Append the controller to the set of controller variables, updates the controller with all current instance variables.
			variables << controller
			
			if result = controller.process!(request, relative_path)
				return result
			end
		end
	end
	
	# The controllers may have rewriten the path so we update the path info:
	request.env[PATH_INFO_KEY] = controller_path.to_s
	
	# No controller gave a useful result:
	return nil
end

#load_controller_file(path) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/utopia/controller.rb', line 69

def load_controller_file(path)
	uri_path = path
	base_path = File.join(@root, uri_path.components)
	
	controller_path = File.join(base_path, CONTROLLER_RB)
	# puts "load_controller_file(#{path.inspect}) => #{controller_path}"
	
	if File.exist?(controller_path)
		klass = Class.new(Base)
		
		# base_path is expected to be a string representing a filesystem path:
		klass.const_set(:BASE_PATH, base_path)
		
		# uri_path is expected to be an instance of Path:
		klass.const_set(:URI_PATH, uri_path)
		
		klass.const_set(:CONTROLLER, self)
		
		klass.class_eval(File.read(controller_path), controller_path)
		
		# Give the controller a useful name:
		# Controllers.define(klass)
		
		return klass.new
	else
		return nil
	end
end

#lookup_controller(path) ⇒ Object



59
60
61
62
63
64
65
66
67
# File 'lib/utopia/controller.rb', line 59

def lookup_controller(path)
	if @cache_controllers
		return @controllers.fetch(path.to_s) do |key|
			@controllers[key] = load_controller_file(path)
		end
	else
		return load_controller_file(path)
	end
end