class Datagnan

Attributes

doc[RW]
vars[RW]

Public Class Methods

new(file_path, options = {}, local_vars = {}) click to toggle source
Constructor

@param [String] file_path

path to .html-template file

@param [Hash] options

options for parsing and filling the template

@param [Hash] locals

local variables for filling the template
# File lib/datagnan.rb, line 15
def initialize(file_path, options = {}, local_vars = {})
        @doc = Oga.parse_html File.read(file_path)
        ## debug
        # puts "-- @doc = #{@doc}"
        @options = {}
        @options[:attrs_sep] = options[:attrs_sep] || ";"
        @options[:path_filters] = options[:path_filters] || {}
        @scope = options[:scope] || self
        @vars = (options[:local_vars] || {}).merge local_vars
        @vars.merge! Hash[@scope.instance_variables.map { |name| [name.to_s, @scope.instance_variable_get(name)] } ] unless @scope.nil?
        ## debug
        # puts "-- Datagnan.new ( @vars = #{@vars} )"
end
open(file_path, options = {}, local_vars = {}) { |obj| ... } click to toggle source
Create Datagnan instance and return this.
Can receive implicity block for 'yield.
Like File.open(file_path)

@param [String] file_path

path to .html-template file

@param [Hash] options

options for parsing and filling the template

@param [Hash] locals

local variables for filling the template
# File lib/datagnan.rb, line 38
def self.open(file_path, options = {}, local_vars = {})
        obj = Datagnan.new(file_path, options, local_vars).write
        yield obj if block_given?
        return obj
end
read(file_path, options = {}, local_vars = {}) click to toggle source
Create Datagnan instance and return the filling with variables HTML-template as String.
Like File.read(file_path)

@param [String] file_path

path to .html-template file

@param [Hash] options

options for parsing and filling the template

@param [Hash] locals

local variables for filling the template
# File lib/datagnan.rb, line 52
def self.read(file_path, options = {}, local_vars = {})
        Datagnan.new(file_path, options, local_vars).write.read
end

Public Instance Methods

read() click to toggle source

Return HTML-String. As File.new.read

# File lib/datagnan.rb, line 57
def read
        ## debug
        # puts "-- Datagnan.read ( @doc = #{@doc} )"
        @doc.to_xml
end
write(vars = {}, root = nil) click to toggle source
Parse and replace
Like File.new.write

@param [Hash] vars

variables for filling the template

@param [Oga::XML::Document] root

HTML-element for fill it
# File lib/datagnan.rb, line 69
def write(vars = {}, root = nil)
        ## debug
        # puts "Datagnan.write ( vars = #{vars} )"
        # puts "Datagnan.write ( @doc = #{@doc} )"
        ## use global if empty
        vars = @vars if vars.is_a?(Hash) && vars.empty?
        root = @doc if root.nil?
        ## debug
        # puts "-- Datagnan.write ( vars = #{vars.inspect} )"
        # puts "-- Datagnan.write ( root = #{root.to_xml} )"
        ## replace data-each
        data_each(vars, root)
        ## debug
        # puts "-- Datagnan.write after each ( vars = #{vars} )"
        # puts "-- Datagnan.write after each ( root = #{root.to_xml} )"
        ## replace data-when
        data_when(vars, root)
        data_when_not(vars, root)
        ## debug
        # puts "-- Datagnan.write after when ( vars = #{vars} )"
        # puts "-- Datagnan.write after when ( root = #{root.to_xml} )"
        ## replace data-var
        data_var(vars, root)
        ## debug
        # puts "Datagnan.write after vars ( vars = #{vars} )"
        # puts "Datagnan.write after vars ( root = #{root.to_xml} )"
        ## replace data-attrs
        data_attrs(vars, root)
        ## debug
        # puts "Datagnan.write after attrs ( vars = #{vars} )"
        # puts "Datagnan.write after attrs ( root = #{root.to_xml} )"
        ## replace data-attr-*
        data_attr(vars, root)
        ## debug
        # puts "Datagnan.write after attr ( vars = #{vars} )"
        # puts "Datagnan.write after attr ( root = #{root.to_xml} )"
        ## result
        return self
end

Private Instance Methods

class_exists?(class_name) click to toggle source

check class exists

# File lib/datagnan.rb, line 112
def class_exists?(class_name)
        klass = Module.const_get(class_name)
        return klass.is_a?(Class)
rescue NameError
        return false
end
data_attr(vars, root) click to toggle source
node attributes (DOMtempl-comaptible)

@since 1.2.0

# File lib/datagnan.rb, line 206
def data_attr(vars, root)
        root.xpath("//@*[starts-with(name(), 'data-attr-')]").each do |attr|
                node = attr.element

                key = attr.name.sub(/^data\-attr\-/, '')
                val = attr.value

                var = find_value(val, vars)
                ## debug
                # puts "-- Datagnan.data_attr each after find_value ( var = #{var} )"
                # puts "-- Datagnan.data_attr each after find_value ( var.to_s = #{var.to_s} )"

                unless var.nil? || var == false
                        ## debug
                        # puts "-- Datagnan.data_attr each before insert ( node.to_xml = #{node.to_xml} )"
                        node.unset(key)
                        node.attributes.insert(
                                node.attributes.index(attr),
                                Oga::XML::Attribute.new(
                                        :name => key,
                                        :value => var.to_s,
                                        :element => node
                                )
                        )
                        ## debug
                        # puts "-- Datagnan.data_attr each after insert ( node.to_xml = #{node.to_xml} )"
                end
                node.unset(attr.name)
                ## debug
                # puts "-- Datagnan.data_attr each ( node.to_xml = #{node.to_xml} )"
        end
        ## debug
        # puts "-- Datagnan.data_attr after ( root.to_xml = #{root.to_xml} )"
end
data_attrs(vars, root) click to toggle source

node attributes

# File lib/datagnan.rb, line 242
def data_attrs(vars, root)
        ## debug
        # puts "-- Datagnan.data_attrs ( vars = #{vars} )"
        # puts "-- Datagnan.data_attrs ( root = #{root.to_xml} )"
        # puts "-- Datagnan.data_attrs ( @options[:attrs_sep] = #{@options[:attrs_sep]} )"
        root.css('*[data-attrs]').each do |node|
                ## debug
                # puts "-- Datagnan.data_attrs each ( node = #{node} )"
                # puts "-- Datagnan.data_attrs each ( node.to_xml = #{node.to_xml} )"
                node_data_attrs = node.attribute('data-attrs')
                node_data_attrs.value.split(@options[:attrs_sep]).each do |attr|
                        key_val = attr.split(':')
                        key = key_val[0]
                        val = key_val.size.odd? ? key_val[0] : key_val[1]
                        ## debug
                        # puts "-- Datagnan.data_attrs each attr ( key = #{key}, val = #{val} )"
                        # puts "-- Datagnan.data_attrs each attr ( vars = #{vars} )"
                        var = find_value(val, vars)
                        ## debug
                        # puts "-- Datagnan.data_attrs each attr ( var = #{var} )"

                        unless var.nil? || var == false
                                node.unset(key)
                                node.attributes.insert(
                                        node.attributes.index(node_data_attrs),
                                        Oga::XML::Attribute.new(
                                                :name => key,
                                                :value => var.to_s,
                                                :element => node
                                        )
                                )
                        end
                        # puts "-- Datagnan.data_attrs each ( node.to_xml = #{node.to_xml} )"
                        ## TODO: if attr not exist remember it (maybe return to model)
                end
                node.unset('data-attrs')
        end
end
data_each(vars, root) click to toggle source

fill template by array

# File lib/datagnan.rb, line 282
def data_each(vars, root)
        ## debug
        # puts "-- Datagnan.data_each ( vars = #{vars} )"
        # puts "-- Datagnan.data_each ( root = #{root.to_xml} )"
        # puts "-- Datagnan.data_each ( root.css('[data-each]') = #{root.css('[data-each]').inspect} )"
        root.css('*[data-each]').each do |node|

                var = find_value(node.get('data-each'), vars)

                unless var.nil?
                # --------
                        node.unset('data-each')
                        var.each do |key, item|
                                item ||= key
                                # puts "-- Datagnan.data_each each ( item = #{item} )"
                                # puts "-- Datagnan.data_each each ( item.inspect = #{item.inspect} )"
                                new_node = Oga.parse_html(node.to_xml)
                                # puts "-- Datagnan.data_each each ( node after clone = #{node} )"
                                # puts "-- Datagnan.data_each each ( node.to_xml after clone = #{node.to_xml} )"
                                # puts "-- Datagnan.data_each each ( node.parent.to_xml = #{node.parent.to_xml} )"
                                # puts "-- Datagnan.data_each each ( new_node = #{new_node} )"
                                # puts "-- Datagnan.data_each each ( new_node.to_xml = #{new_node.to_xml} )"
                                write(item, new_node)
                                # puts "-- Datagnan.data_each each ( new_node after write = #{new_node} )"
                                # puts "-- Datagnan.data_each each ( new_node.to_xml after write = #{new_node.to_xml} )"
                                # puts "-- Datagnan.data_each each ( node after write= #{node} )"
                                # puts "-- Datagnan.data_each each ( node.to_xml after write= #{node.to_xml} )"
                                node.before(new_node.children.pop) unless new_node.children.empty?
                                # puts "-- Datagnan.data_each each ( node = #{node} )"
                                # puts "-- Datagnan.data_each each ( node.to_xml after insert = #{node.to_xml} )"
                                # puts "-- Datagnan.data_each each ( node.parent = #{node.parent.to_xml} )"
                        end
                end
                node.remove
        end
end
data_var(vars, root) click to toggle source

node content

# File lib/datagnan.rb, line 182
def data_var(vars, root)
        ## debug
        # puts "-- Datagnan.data_var ( vars = #{vars} )"
        # puts "-- Datagnan.data_var ( root.to_xml = #{root.to_xml} )"
        root.css('*[data-var]').each do |node|

                var = find_value(node.get('data-var'), vars)

                unless var.nil?
                        begin
                                node.children = Oga.parse_html(var.to_s).children
                        rescue
                                node.inner_text = var.to_s
                        end
                        node.unset('data-var')
                end
                ## TODO: if var not exist remember it (maybe return to model)
        end
        ## debug
        # puts "Datagnan.data_var end ( root = #{root} )"
end
data_when(vars, root) click to toggle source

display if true

# File lib/datagnan.rb, line 320
def data_when(vars, root)
        ## debug
        # puts "-- Datagnan.data_when ( vars = #{vars} )"
        # puts "-- Datagnan.data_when ( root.to_xml = #{root.to_xml} )"
        root.css('*[data-when]').each do |node|

                var = node.get('data-when').split(@options[:attrs_sep]).each do |key|
                        ## debug
                        # puts "-- Datagnan.data_when each split ( key = #{key} )"
                        var = find_value(key, vars)
                        # puts "-- Datagnan.data_when each split ( var = #{var} )"
                        break var unless var
                end
                ## debug
                # puts "-- Datagnan.data_when each ( node.to_xml = #{node.to_xml} )"
                # puts "-- Datagnan.data_when each ( var = #{var} )"

                ## allow for nil
                var ? node.unset('data-when') : node.remove
                ## TODO: if var not exist remember it (maybe return to model)
        end
        ## debug
        # puts "Datagnan.data_when end ( root = #{root} )"
end
data_when_not(vars, root) click to toggle source
display if false

@since 1.1.0

# File lib/datagnan.rb, line 347
def data_when_not(vars, root)
        ## debug
        # puts "Datagnan.data_when_not ( vars = #{vars} )"
        # puts "Datagnan.data_when_not ( root = #{root} )"
        root.css('*[data-when-not]').each do |node|

                var = node.get('data-when-not').split(@options[:attrs_sep]).each do |key|
                        ## debug
                        # puts "-- Datagnan.data_when_not each split ( key = #{key} )"
                        var = find_value(key, vars)
                        # puts "-- Datagnan.data_when_not each split ( var = #{var} )"
                        break var unless var
                end

                ## allow for nil
                var ? node.remove : node.unset('data-when-not')
                ## TODO: if var not exist remember it (maybe return to model)
        end
        ## debug
        # puts "Datagnan.data_when_not end ( root = #{root} )"
end
find_value(path, vars) click to toggle source

find value in vars and scope

# File lib/datagnan.rb, line 120
def find_value(path, vars)
        ## recursive access to property
        ## debug
        # puts "-- Datagnan.find_value ( path = #{path} )"
        # puts "-- Datagnan.find_value ( vars = #{vars} )"
        # beginning_time = Time.now
        var = vars

        ## path_filters for replace
        ## Example:
        ## path => '/foo/bar'
        ## :path_filters = { /^\// => '', '/' => '.' }
        ## path => 'foo.bar'
        @options[:path_filters].each { |key, val| path.gsub!(key, val) }

        dot_keys = path.split('.')
        dot_keys = dot_keys.drop_while do |dot_key|
                ## debug
                # puts "-- Datagnan.find_value drop_while ( dot_key = #{dot_key} )"
                # puts "-- Datagnan.find_value drop_while ( var.has_key?(dot_key) = #{var.has_key?(dot_key)} )" if var.is_a?(Hash)
                var.is_a?(Hash) ?
                        (var.has_key?(dot_key) ?
                                var = var[dot_key] :
                                false
                        ) :
                        false
        end
        ## debug
        # puts "-- Datagnan.find_value after drop_while ( var = #{var} )"
        # puts "-- Datagnan.find_value after drop_while ( dot_keys = #{dot_keys} )"
        # puts "-- Datagnan.find_value before eval ( dot_keys = #{dot_keys} )"

        begin
                ## debug
                # puts "-- Datagnan.find_value before eval var.instance_eval"
                # puts "-- Datagnan.find_value before eval ( var.instance_eval(dot_keys.join('.')) = #{var.instance_eval(dot_keys.join('.'))} )"
                var = var.instance_eval(dot_keys.join('.'))
        rescue Exception => e
                begin
                        ## debug
                        # puts "-- Datagnan.find_value before eval @scope.instance_eval('var.')"
                        # puts "-- Datagnan.find_value before eval ( @scope.instance_eval('var.'+dot_keys.join('.')) = #{@scope.instance_eval('var.'+dot_keys.join('.'))} )"
                        var = @scope.instance_eval('var.'+dot_keys.join('.'))
                rescue Exception => e
                        begin
                                ## debug
                                # puts "-- Datagnan.find_value before eval @scope.instance_eval"
                                # puts "-- Datagnan.find_value before eval ( @scope.instance_eval(dot_keys.join('.')) = #{@scope.instance_eval(dot_keys.join('.'))} )"
                                var = @scope.instance_eval(dot_keys.join('.'))
                        rescue Exception => e
                                var = nil
                        end
                end
        end if dot_keys.any?
        ## debug
        # puts "-- Datagnan.find_value result ( var = #{var} )"
        # end_time = Time.now
        # puts "Time elapsed for find_value #{(end_time - beginning_time)*1000} milliseconds"
        var
end