lib/view.rb in garterbelt-0.0.9 vs lib/view.rb in garterbelt-0.1.0

- old
+ new

@@ -1,27 +1,25 @@ module Garterbelt class View - # include RuPol::Swimsuit + attr_accessor :output, :_buffer, :_level, :_escape, :block, :initialization_options, :render_style + attr_reader :_curator - attr_accessor :output, :buffer, :level, :escape, :block, :options, :render_style - attr_reader :curator - def initialize(opts={}, &block) - self.options = opts - self.buffer = [] - self.level = options.delete(:level) || 0 - self.render_style = options.delete(:style) || :pretty + self.initialization_options = opts + self._buffer = [] + self._level = initialization_options.delete(:_level) || 0 + self.render_style = initialization_options.delete(:style) || :pretty self.output = "" - self.escape = true + self._escape = true self.block = block if block_given? - self.curator = options.delete(:curator) || self + self._curator = initialization_options.delete(:_curator) || self params = self.class.default_variables.merge(opts) keys = params.keys - unless ((self.class.required || []) - keys).empty? + unless (self.class.required - keys).empty? raise ArgumentError, "#{(self.class.required - keys).inspect} required as an initialization option" end if self.class.selective_require && keys != self.class.required raise ArgumentError, "Allowed initalization options are only #{self.class.required.inspect}" @@ -31,30 +29,35 @@ self.class.add_accessor(key) unless respond_to?(key) instance_variable_set "@#{key}", value end end - def curator=(parent_view) - @curator = parent_view + def _curator=(parent_view) + @_curator = parent_view if parent_view != self - self.buffer = parent_view.buffer - self.level = parent_view.level + self._buffer = parent_view._buffer + self._level = parent_view._level self.output = parent_view.output - self.escape = parent_view.escape + self._escape = parent_view._escape self.render_style = parent_view.render_style end end def curated? - curator === self + _curator === self end # VARIABLE ACCESS ----------------------------- class << self - attr_accessor :required, :selective_require + attr_writer :required + attr_accessor :selective_require end + def self.required + @required ||= [] + end + def self.add_accessor key key = key.to_s return if accessories.include?(key) if (instance_methods - Object.instance_methods).include?(key) raise ArgumentError, ":#{key} cannot be a required variable because it maps to an existing method" @@ -71,11 +74,11 @@ def self.superclass? @superclassed ||= superclass.respond_to?( :required ) end def self.super_required - superclass? ? superclass.required || [] : [] + superclass? ? superclass.required : [] end def self.default_variables @default_variables ||= superclass? ? superclass.default_variables.dup : Hash.new end @@ -85,11 +88,11 @@ self.default_variables.merge!(args.pop) args += default_variables.keys.map{ |x| x.to_sym } end args = super_required + args - self.required = args.uniq + self.required += args.uniq build_accessors required end def self.requires_only(*args) @@ -109,11 +112,11 @@ end # TAG HELPERS ----------------------- def add_to_buffer(renderer) - buffer << renderer + _buffer << renderer renderer end def tag(type, *args, &block) t = if block_given? @@ -127,54 +130,54 @@ def closed_tag(type, *args) add_to_buffer ClosedTag.new(parse_tag_arguments(type, args)) end def non_escape_tag(*args, &block) - if escape - curator.escape = false + if _escape + _curator._escape = false t = block_given? ? tag(*args, &block) : tag(*args) - curator.escape = true + _curator._escape = true t else block_given? ? tag(*args, &block) : tag(*args) end end def text(content) - add_to_buffer Text.new(:view => curator, :content => content) + add_to_buffer Text.new(:view => _curator, :content => content) end alias :h :text def raw_text(content) - if escape - curator.escape = false + if _escape + _curator._escape = false t = text(content) - curator.escape = true + _curator._escape = true t else text(content) end end alias :raw :raw_text alias :rawtext :raw_text def comment_tag(content) - add_to_buffer Comment.new(:view => curator, :content => content) + add_to_buffer Comment.new(:view => _curator, :content => content) end def doctype(type=:transitional) - add_to_buffer Doctype.new(:view => curator, :type => type) + add_to_buffer Doctype.new(:view => _curator, :type => type) end def xml(opts={}) opts = {:version => 1.0, :encoding => 'utf-8'}.merge(opts) add_to_buffer Xml.new(parse_tag_arguments(:xml, [opts])) end def parse_tag_arguments(type, args) - opts = {:type => type, :view => curator} + opts = {:type => type, :view => _curator} if args.size == 2 opts[:content] = args.shift opts[:attributes] = args.first else if args.first.is_a?(Hash) @@ -196,12 +199,12 @@ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'html', 'i', 'iframe', 'ins', 'kbd', 'label', 'legend', 'li', 'map', 'noframes', 'noscript', 'object', 'ol', 'optgroup', 'option', 'p', 'param', 'q', 's', - 'samp', 'script', 'select', 'small', 'span', - 'strong', 'style', 'sub', 'sup', + 'samp', 'select', 'small', 'span', + 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'tr', 'tt', 'u', 'ul', 'var' ] CONTENT_TAGS.each do |type| class_eval <<-RUBY @@ -209,11 +212,11 @@ block_given? ? tag(:#{type}, *args, &block) : tag(:#{type}, *args) end RUBY end - NON_ESCAPE_TAGS = ['code', 'pre'] + NON_ESCAPE_TAGS = ['code', 'pre', 'script', 'style'] NON_ESCAPE_TAGS.each do |type| class_eval <<-RUBY def #{type}(*args, &block) block_given? ? non_escape_tag(:#{type}, *args, &block) : non_escape_tag(:#{type}, *args) end @@ -268,23 +271,28 @@ @default_content_method ||= :content end def render(*args) if args.first.is_a?(Hash) - options = args.shift - content_method = options[:method] + initialization_options = args.shift + content_method = initialization_options[:method] else content_method = args.shift - options = args.shift || {} + initialization_options = args.shift || {} end content_method ||= self.class.default_content_method - self.render_style = options[:style] || self.class.default_render_style + self.render_style = initialization_options[:style] || self.class.default_render_style self.output = "" if curated? - send(content_method) + if block + send(content_method, &block) + else + send(content_method) + end + render_buffer output end alias :to_s :render @@ -300,12 +308,12 @@ def call_block block.call if block end def render_buffer - array = buffer.dup - buffer.clear + array = _buffer.dup + _buffer.clear array.each do |item| if item.respond_to?(:render) item.render else output << item.to_s @@ -319,22 +327,29 @@ output = content_method ? view.render(content_method) : view.render output end def partial(*args, &block) - if (klass = args.first).is_a?(Class) + view = if (klass = args.first).is_a?(Class) args.shift - view = if block - klass.new(*args, &block) + partial_opts = args.shift || {} + available_opts = self.class.default_variables.merge(initialization_options) + opts = if klass.selective_require + klass.required.each do |key| + partial_opts[key] ||= available_opts[key] + end + partial_opts else - klass.new(*args) + available_opts.merge(partial_opts) end + klass.new(opts) else - view = args.first + args.first end - view.curator = curator - self.buffer << view + view.block = block if block + view._curator = _curator + self._buffer << view view end alias :widget :partial @@ -373,10 +388,10 @@ detail ||= CACHE_DETAIL_DEFAULT "#{cache_key_base}_#{detail}" end def cache(key, opts={}, &block) - opts = opts.merge(:key => cache_key(key), :view => curator) + opts = opts.merge(:key => cache_key(key), :view => _curator) add_to_buffer Cache.new(opts, &block) end end end \ No newline at end of file