Class: RocketIO::Controller
- Inherits:
-
Object
- Object
- RocketIO::Controller
- Extended by:
- Forwardable
- Defined in:
- lib/rocketio-views/engine.rb,
lib/rocketio-views/layout.rb,
lib/rocketio-views/layouts.rb,
lib/rocketio-views/templates.rb,
lib/rocketio-views/controller.rb,
lib/rocketio-views/template_vars.rb
Class Method Summary collapse
- .define_engine_methods(source = self) ⇒ Object
-
.define_layout(name, file: nil, &block) ⇒ Object
if only name given it will search for a file with same name in controller’s dirname.
- .define_layout_methods(source = self) ⇒ Object
- .define_layouts_methods(source = self) ⇒ Object
-
.define_template(name, file: nil, &block) ⇒ Object
if only name given it will search for a file with same name in controller’s dirname.
-
.define_template_var(name, value = nil, &block) ⇒ Object
define variables to be used on templates alongside provided locals.
- .define_template_vars_methods(source = self) ⇒ Object
- .define_templates_methods(source = self) ⇒ Object
-
.engine(engine = nil, *engine_options, &block) ⇒ Object
if no engine set, templates will be rendered using ERB engine.
-
.layout(layout) ⇒ Object
by default templates will be rendered without layout.
Instance Method Summary collapse
- #__template_vars__ ⇒ Object
- #engine ⇒ Object
-
#layout ⇒ Object
by default no layout used, so this method returns nil.
- #layouts ⇒ Object
-
#render(template = nil, opts = {}) ⇒ Object
if called without arguments render a template with lowercased name of current request method, e.g.
-
#render_layout(template = nil, opts = {}, &block) ⇒ Object
render a template that yields the given block.
- #template_vars ⇒ Object
- #templates ⇒ Object
Class Method Details
.define_engine_methods(source = self) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/rocketio-views/engine.rb', line 59 def self.define_engine_methods source = self return unless engine = source.instance_variable_get(:@__engine__) if Proc === engine selfengine = allocate.engine api.delete define_method(:__rocketio_engine__, &engine) api.delete define_method(:engine) { engine, * = __rocketio_engine__ return selfengine unless engine [RocketIO.engine_class(engine), .freeze].freeze } else api.delete define_method(:engine) {engine} end end |
.define_layout(name, file: nil, &block) ⇒ Object
files will be searched relative to controller’s dirname, that’s it, the folder controller was defined in and operates from.
when searching for file multiple extensions will be tried, that’s it, all extensions controller’s engine actually supports.
controllers that inherits named layouts will always search for files in own dirname. controllers that inherits :file layouts will search files in the original controller’s dirname.
if only name given it will search for a file with same name in controller’s dirname.
if file name differs from layout name pass it as :file option. file path should be relative to controller’s dirname. also a block accepted for :file option. the block will be executed at controllers’s instance level and should return path to layout file. file name should NOT include extension.
if a block given NO file will be searched and returned value will be used as layout.
50 51 52 53 54 |
# File 'lib/rocketio-views/layouts.rb', line 50 def self.define_layout name, file: nil, &block file && block && raise(::ArgumentError, 'both file and block given, please use either one') (@__layouts__ ||= {})[name.to_sym] = {block: block, root: dirname, file: file, name: name}.freeze define_layouts_methods end |
.define_layout_methods(source = self) ⇒ Object
17 18 19 20 21 |
# File 'lib/rocketio-views/layout.rb', line 17 def self.define_layout_methods source = self return unless source.instance_variables.include?(:@__layout__) layout = source.instance_variable_get(:@__layout__) api.delete define_method(:layout) {layout} end |
.define_layouts_methods(source = self) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/rocketio-views/layouts.rb', line 56 def self.define_layouts_methods source = self return unless source.instance_variables.include?(:@__layouts__) layouts = source.instance_variable_get(:@__layouts__).each_with_object(allocate.layouts.dup) do |(name,setup),o| o[name] = :"__#{name}_layout__" if setup[:block] # block given, do not search for file, use returned value instead api.delete define_method(o[name], &setup[:block]) elsif setup[:file] # file given, search the file in original controller dirname meth_name = :"__#{name}_layout_file__" meth_proc = setup[:file].is_a?(::Proc) ? setup[:file] : -> {setup[:file]} api.delete define_method(meth_name, &meth_proc) api.delete define_method(o[name]) { engine, * = resolve_engine read_template(find_template(setup[:root], __send__(meth_name), engine)) } else # only name given, search for a file with same name in controller's dirname api.delete define_method(o[name]) { engine, * = resolve_engine read_template(find_template(self.dirname, setup[:name], engine)) } end end.freeze api.delete define_method(:layouts) {layouts} end |
.define_template(name, file: nil, &block) ⇒ Object
files will be searched relative to controller’s dirname, that’s it, the folder controller was defined in and operates from.
when searching for file multiple extensions will be tried, that’s it, all extensions controller’s engine actually supports.
controllers that inherits named templates will always search for files in own dirname. controllers that inherits :file templates will search files in the original controller’s dirname.
if only name given it will search for a file with same name in controller’s dirname
if file name differs from template name pass it as :file option. file path should be relative to controller’s dirname. also a block accepted for :file option. the block will be executed at controllers’s instance level and should return path to template file. file name should NOT include extension.
if a block given NO file will be searched and returned value will be used as template.
48 49 50 51 52 |
# File 'lib/rocketio-views/templates.rb', line 48 def self.define_template name, file: nil, &block file && block && raise(ArgumentError, 'both file and block given, please use either one') (@__templates__ ||= {})[name.to_sym] = {block: block, root: dirname, file: file, name: name}.freeze define_templates_methods end |
.define_template_var(name, value = nil, &block) ⇒ Object
define variables to be used on templates alongside provided locals.
9 10 11 12 13 |
# File 'lib/rocketio-views/template_vars.rb', line 9 def self.define_template_var name, value = nil, &block value || block || raise(ArgumentError, 'A value or a block expected') (@__template_vars__ ||= {})[name.to_sym] = (block || value).freeze define_template_vars_methods end |
.define_template_vars_methods(source = self) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/rocketio-views/template_vars.rb', line 15 def self.define_template_vars_methods source = self return unless source.instance_variables.include?(:@__template_vars__) vars = source.instance_variable_get(:@__template_vars__).each_with_object(allocate.__template_vars__.dup) do |(name,value),o| o[name] = :"__#{name}_template_var__" if value.is_a?(Proc) api.delete define_method(o[name], &value) else api.delete define_method(o[name]) {value} end end.freeze api.delete define_method(:__template_vars__) {vars} end |
.define_templates_methods(source = self) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/rocketio-views/templates.rb', line 54 def self.define_templates_methods source = self return unless source.instance_variables.include?(:@__templates__) templates = source.instance_variable_get(:@__templates__).each_with_object(allocate.templates.dup) do |(name,setup),o| o[name] = :"__#{name}_template__" if setup[:block] # block given, do not search for file, use returned value instead api.delete define_method(o[name], &setup[:block]) elsif setup[:file] # file given, search the file in original controller dirname meth_name = :"__#{name}_template_file__" meth_proc = setup[:file].is_a?(Proc) ? setup[:file] : -> {setup[:file]} api.delete define_method(meth_name, &meth_proc) api.delete define_method(o[name]) { engine, * = resolve_engine read_template(find_template(setup[:root], __send__(meth_name), engine)) } else # only name given, search for a file with same name in controller's dirname api.delete define_method(o[name]) { engine, * = resolve_engine read_template(find_template(self.dirname, setup[:name], engine)) } end end.freeze api.delete define_method(:templates) {templates} end |
.engine(engine = nil, *engine_options, &block) ⇒ Object
if a block given it will be executed at instance level and result used for engine. To have any options passed at engine initialization the block should return an array having engine as first element and options as consequent elements.
if given block returns no engine, inherited engine will be used
if no engine set, templates will be rendered using ERB engine. any engine supported by [Tilt](github.com/rtomayko/tilt) can be used. to set engine use symbolized constant name, e.g. :Slim, :Haml engine name is Case Sensitive and there should be a Tilt::ENGINETemplate class defined e.g. ‘engine :Slim` will look for Tilt::SlimTemplate and `engine RDiscount` will look for Tilt::RDiscountTemplate
54 55 56 57 |
# File 'lib/rocketio-views/engine.rb', line 54 def self.engine engine = nil, *, &block @__engine__ = block || [RocketIO.engine_class(engine), .freeze].freeze define_engine_methods end |
.layout(layout) ⇒ Object
to disable layout set it to false: ‘layout false`
by default templates will be rendered without layout. to make them render inside a layout use ‘layout :layout_name` at class level. to use a layout it should be defined at first (@see define_layout)
12 13 14 15 |
# File 'lib/rocketio-views/layout.rb', line 12 def self.layout layout @__layout__ = layout define_layout_methods end |
Instance Method Details
#__template_vars__ ⇒ Object
28 |
# File 'lib/rocketio-views/template_vars.rb', line 28 def __template_vars__; RocketIO::EMPTY_HASH end |
#engine ⇒ Object
74 |
# File 'lib/rocketio-views/engine.rb', line 74 def engine; RocketIO::DEFAULT_ENGINE end |
#layout ⇒ Object
by default no layout used, so this method returns nil. controllers that uses a layout will override this method.
25 |
# File 'lib/rocketio-views/layout.rb', line 25 def layout; end |
#layouts ⇒ Object
83 |
# File 'lib/rocketio-views/layouts.rb', line 83 def layouts; RocketIO::EMPTY_HASH end |
#render(template = nil, opts = {}) ⇒ Object
if called without arguments render a template with lowercased name of current request method, e.g. get for GET, post for POST etc. at first it will look between defined templates. then it will search a file. it will try each extension the effective engine has registered, e.g. .erb, .rhtml for ERB. it will search in the folder the controller was defined in(NOT in path_to_templates, which is used for defined templates only). so put each controller in a separate folder to avoid templates clash.
if no file found a TemplateError will be raised. if a block given it will use the the string returned by the block as template and wont search for defined nor file templates.
by default ERB engine will be used (@see engine).
for layout it will take one given through options or one defined at class level. if none given, it will render without layout. to use a layout path_to_layouts should be defined at class level.
by default it will use current instance as scope. to render in a isolated scope, set it via :scope option
to pass some local variables use :locals option
70 71 72 73 74 75 76 77 78 79 |
# File 'lib/rocketio-views/controller.rb', line 70 def render template = nil, opts = {} opts, template = template, nil if template.is_a?(::Hash) engine, engine_opts = resolve_engine(opts) template = block_given? ? yield : resolve_template(template, engine) scope = opts.fetch(:scope, self) locals = template_vars.merge(opts.fetch(:locals, RocketIO::EMPTY_HASH)).freeze layout = opts.fetch(:layout, self.layout) template = compile_template(template, engine, engine_opts).render(scope, locals) layout ? render_layout(layout, opts) {template} : template end |
#render_layout(template = nil, opts = {}, &block) ⇒ Object
render a template that yields the given block. that’s it, a layout is a template that yields given string.
layout can be specified two ways:
- as layout name
- as string
if both given a ArgumentError error raised. if :template option given, no layout lookups will occur.
otherwise… if no layout name given, it will use the one set at class level. if no layout set at class level and no layout given, it will raise a RuntimeError.
then it will search for given layout between defined ones. if none found, it will search a file in ‘path_to_layouts` folder. it will try each extension registered with effective engine. if no file found it will raise a TemplateError.
block is required and should return the string to be yielded.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/rocketio-views/controller.rb', line 102 def render_layout template = nil, opts = {}, &block template && opts[:template] && raise(ArgumentError, 'Both layout name and :template option given. Please use either one.') opts, template = template, nil if template.is_a?(::Hash) engine, engine_opts = resolve_engine(opts) template = if template resolve_layout(template, engine) else opts[:template] || begin self.layout || raise(RocketIO::LayoutError, 'No default layout set and no explicit layout given') resolve_layout(self.layout, engine) end end scope = opts.fetch(:scope, self) locals = template_vars.merge(opts.fetch(:locals, RocketIO::EMPTY_HASH)).freeze compile_template(template, engine, engine_opts) .render(scope, locals, &(block || RocketIO::EMPTY_STRING_PROC)) end |
#template_vars ⇒ Object
30 31 32 |
# File 'lib/rocketio-views/template_vars.rb', line 30 def template_vars __template_vars__.each_with_object({}) {|(k,v),o| o[k] = __send__(v)} end |
#templates ⇒ Object
81 |
# File 'lib/rocketio-views/templates.rb', line 81 def templates; RocketIO::EMPTY_HASH end |