Class: Bijou::Context
- Inherits:
-
Object
- Object
- Bijou::Context
- Defined in:
- lib/bijou/context.rb
Overview
When a Bijou file is loaded by the processor, each component that is encountered causes a Bijou::Component class to be instantiated in the context. This context can then be executed with a set of input arguments, causing each component to be evaluated and the output to be rendered. A context may be used to invoke the same arrangement of components any number of times with different arguments.
Instance Attribute Summary collapse
-
#cgi ⇒ Object
Returns the value of attribute cgi.
-
#component_callback ⇒ Object
Returns the value of attribute component_callback.
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#container_callback ⇒ Object
Returns the value of attribute container_callback.
-
#environment ⇒ Object
readonly
Returns the value of attribute environment.
-
#request ⇒ Object
Returns the value of attribute request.
-
#response ⇒ Object
Returns the value of attribute response.
-
#stack ⇒ Object
readonly
Returns the value of attribute stack.
Instance Method Summary collapse
- #add_component(component) ⇒ Object
- #argument_exception(method, name) ⇒ Object
-
#cache_filename ⇒ Object
Used to retrieve the last active frame in the event of an exception.
-
#call_next(extra = {}) ⇒ Object
Container modules render their callers by calling the content method once at the location where the caller’s output should be rendered.
- #clear ⇒ Object
- #fetch_next ⇒ Object
- #fetch_remainder ⇒ Object
- #get_log ⇒ Object
- #get_trace ⇒ Object
-
#initialize(config, environment = nil) ⇒ Context
constructor
A new instance of Context.
-
#invoke(name, args) ⇒ Object
Used to invoke a method or a component.
-
#log(level, str) ⇒ Object
Logs with carriage return.
-
#log_(level, str) ⇒ Object
Logs without carriage return.
- #output ⇒ Object
- #render(args) ⇒ Object
-
#render_component(args) ⇒ Object
The render method renders the component chain.
-
#reset ⇒ Object
Called after clone.
-
#sinvoke(name, args) ⇒ Object
Used to invoke a method or a component.
-
#source_filename ⇒ Object
Used to retrieve the last active frame in the event of an exception.
-
#trace(level, str) ⇒ Object
Trace with carriage return.
-
#trace_(level, str) ⇒ Object
Trace without carriage return.
- #try_fetch_next ⇒ Object
- #try_fetch_remainder ⇒ Object
- #write(str) ⇒ Object
- #writeline(str) ⇒ Object
Constructor Details
#initialize(config, environment = nil) ⇒ Context
Returns a new instance of Context.
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/bijou/context.rb', line 173 def initialize(config, environment=nil) if !environment environment = Environment.new environment.trace_level = config.trace_level environment.trace_buffer = config.trace_buffer end @args = {} @stack = Stack.new @config = config @environment = environment @container_callback = nil @component_callback = nil @request = nil @response = nil @cgi = nil end |
Instance Attribute Details
#cgi ⇒ Object
Returns the value of attribute cgi.
169 170 171 |
# File 'lib/bijou/context.rb', line 169 def cgi @cgi end |
#component_callback ⇒ Object
Returns the value of attribute component_callback.
163 164 165 |
# File 'lib/bijou/context.rb', line 163 def component_callback @component_callback end |
#config ⇒ Object (readonly)
Returns the value of attribute config.
166 167 168 |
# File 'lib/bijou/context.rb', line 166 def config @config end |
#container_callback ⇒ Object
Returns the value of attribute container_callback.
164 165 166 |
# File 'lib/bijou/context.rb', line 164 def container_callback @container_callback end |
#environment ⇒ Object (readonly)
Returns the value of attribute environment.
167 168 169 |
# File 'lib/bijou/context.rb', line 167 def environment @environment end |
#request ⇒ Object
Returns the value of attribute request.
170 171 172 |
# File 'lib/bijou/context.rb', line 170 def request @request end |
#response ⇒ Object
Returns the value of attribute response.
171 172 173 |
# File 'lib/bijou/context.rb', line 171 def response @response end |
#stack ⇒ Object (readonly)
Returns the value of attribute stack.
165 166 167 |
# File 'lib/bijou/context.rb', line 165 def stack @stack end |
Instance Method Details
#add_component(component) ⇒ Object
233 234 235 236 237 238 239 240 241 |
# File 'lib/bijou/context.rb', line 233 def add_component(component) @stack.push_frame(component) # If the owner registered a container load handler, invoke after the # component has been added. if component.class.container && @container_callback @container_callback.call(self, component.class.container) end end |
#argument_exception(method, name) ⇒ Object
398 399 400 401 |
# File 'lib/bijou/context.rb', line 398 def argument_exception(method, name) # BUGBUG: We need to print the page (component) name. raise "Expected argument '#{name}' to method '#{method}'" end |
#cache_filename ⇒ Object
Used to retrieve the last active frame in the event of an exception.
225 226 227 228 229 230 231 |
# File 'lib/bijou/context.rb', line 225 def cache_filename if @environment.component @environment.component.class.cache_filename else nil end end |
#call_next(extra = {}) ⇒ Object
Container modules render their callers by calling the content method once at the location where the caller’s output should be rendered.
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/bijou/context.rb', line 297 def call_next(extra={}) if @stack.index == 0 raise 'next called too many times' end # Flush the first part of the component's output to the stack's buffer. @stack.flush_frame prev_component = @environment.component # REVIEW: Argument merge and override is experimental. # Render the child content. component = @stack.next_frame.component @environment.component = component component.render(@args.merge(extra)) @environment.component = prev_component # The remainder of the content will be flushed at the end of render. # @stack.flush_frame end |
#clear ⇒ Object
211 212 213 |
# File 'lib/bijou/context.rb', line 211 def clear @stack.flush end |
#fetch_next ⇒ Object
326 327 328 |
# File 'lib/bijou/context.rb', line 326 def fetch_next try_fetch_next || raise('fetch_next cannot find next component') end |
#fetch_remainder ⇒ Object
338 339 340 |
# File 'lib/bijou/context.rb', line 338 def fetch_remainder try_fetch_remainder || raise('fetch_remainder cannot find next component') end |
#get_log ⇒ Object
413 414 415 |
# File 'lib/bijou/context.rb', line 413 def get_log() @environment.get_log() end |
#get_trace ⇒ Object
427 428 429 |
# File 'lib/bijou/context.rb', line 427 def get_trace() @environment.get_trace() end |
#invoke(name, args) ⇒ Object
Used to invoke a method or a component. The output is rendered to the buffer. Returns true if a match was found.
383 384 385 386 387 388 389 390 391 392 393 394 395 396 |
# File 'lib/bijou/context.rb', line 383 def invoke(name, args) if name == 'content' # REVIEW: This is an experimental feature. An alternative (without # argument support) is <%content>, but it is an unclosed tag. return call_next(args) end if text = sinvoke(name, args) write text return true end false end |
#log(level, str) ⇒ Object
Logs with carriage return.
404 405 406 |
# File 'lib/bijou/context.rb', line 404 def log(level, str) @environment.log(level, str) end |
#log_(level, str) ⇒ Object
Logs without carriage return.
409 410 411 |
# File 'lib/bijou/context.rb', line 409 def log_(level, str) @environment.log_(level, str) end |
#output ⇒ Object
207 208 209 |
# File 'lib/bijou/context.rb', line 207 def output @stack.buffer end |
#render(args) ⇒ Object
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/bijou/context.rb', line 243 def render(args) trace Bijou::Log::Info, "render init" prev_component = @environment.component # Init may render, after the headers but before the page text. @stack.frames.each { |frame| @environment.component = frame.component frame.component.init(args) } @environment.component = prev_component # Render the component chain to the response target. render_component(args) trace Bijou::Log::Info, "render fini" # Fini may still render to the stream, at the end after the page text. @stack.frames.each { |frame| @environment.component = frame.component frame.component.fini() } @environment.component = prev_component return @output end |
#render_component(args) ⇒ Object
The render method renders the component chain.
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/bijou/context.rb', line 273 def render_component(args) if @stack.frames.length == 0 return end # Set top-level args so they are available to all components. @args = args # Start with the outer-most container at the end of the list. @stack.start prev_component = @environment.component component = @stack.top_frame.component @environment.component = component component.render(@args) @environment.component = prev_component # This flushes the component's output to the stack's buffer. @stack.flush_frame end |
#reset ⇒ Object
Called after clone
194 195 196 197 |
# File 'lib/bijou/context.rb', line 194 def reset() @args = {} @stack = Stack.new end |
#sinvoke(name, args) ⇒ Object
Used to invoke a method or a component. The output is rendered to a string, which is returned as the result. If no match is found returns nil.
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
# File 'lib/bijou/context.rb', line 344 def sinvoke(name, args) # Does this look like a method? We don't include setters, etc. (?!=). if name =~ /[_a-z][_a-z0-9]*/ prev_component = @environment.component # Do any of the components support this method? @stack.frames.each { |f| if f.component.respond_to?(name) @stack.flush_frame @environment.component = f.component m = f.component.method(name) m.call(args) @environment.component = prev_component return @stack.top_frame.flush end } @environment.component = prev_component end # Delegate to context owner if @component_callback # The subcontext wraps a new stack for the component, but shares # common data. This allows us to encapsulate the rendered output # into a separate buffer chain. subcontext = self.clone subcontext.reset # TODO: Handle new context and buffer merging. @component_callback.call(subcontext, name, args) return subcontext.stack.flush end nil end |
#source_filename ⇒ Object
Used to retrieve the last active frame in the event of an exception.
216 217 218 219 220 221 222 |
# File 'lib/bijou/context.rb', line 216 def source_filename if @environment.component @environment.component.class.source_filename else nil end end |
#trace(level, str) ⇒ Object
Trace with carriage return.
418 419 420 |
# File 'lib/bijou/context.rb', line 418 def trace(level, str) @environment.trace(level, str) end |
#trace_(level, str) ⇒ Object
Trace without carriage return.
423 424 425 |
# File 'lib/bijou/context.rb', line 423 def trace_(level, str) @environment.trace_(level, str) end |
#try_fetch_next ⇒ Object
318 319 320 321 322 323 324 |
# File 'lib/bijou/context.rb', line 318 def try_fetch_next if @stack.index == 0 nil else @stack.peek_frame end end |
#try_fetch_remainder ⇒ Object
330 331 332 333 334 335 336 |
# File 'lib/bijou/context.rb', line 330 def try_fetch_remainder if @stack.index == 0 nil else @stack.frames[0, @stack.index].reverse end end |
#write(str) ⇒ Object
199 200 201 |
# File 'lib/bijou/context.rb', line 199 def write(str) @stack.output << str end |
#writeline(str) ⇒ Object
203 204 205 |
# File 'lib/bijou/context.rb', line 203 def writeline(str) @stack.output << str + "\n" end |