Class: OM::XML::TemplateRegistry

Inherits:
Object
  • Object
show all
Defined in:
lib/om/xml/template_registry.rb

Overview

Extend an OM::XML::Document with reusable templates, then use them to add content to instance documents.

Example:

require 'om/samples/mods_article'

class OM::Samples::ModsArticle
  define_template :personalName do |xml, family, given, address|
    xml.name(:type => 'personal') do
      xml.namePart(:type => 'family') { xml.text(family) }
      xml.namePart(:type => 'given') { xml.text(given) }
      xml.namePart(:type => 'termsOfAddress') { xml.text(address) }
    end
  end

  define_template :role do |xml, text, attrs|
    xml.role do
      attrs = { :type => 'text' }.merge(attrs)
      xml.roleTerm(attrs) { xml.text(text) }
    end
  end
end

mods = OM::Samples::ModsArticle.from_xml(File.read('./spec/fixtures/CBF_MODS/ARS0025_016.xml'))

mods.add_previous_sibling_node([:person => 0], :personalName, 'Shmoe', 'Joseph', 'Dr.') { |person|
  person.add_child(mods.template(:role, 'author', :authority => 'marcrelator'))
  person.add_child(mods.template(:role, 'sub', :authority => 'local', :type => 'code'))
  person
}

Instance Method Summary collapse

Constructor Details

#initialize(templates = {}) ⇒ TemplateRegistry

Returns a new instance of TemplateRegistry.



35
36
37
# File 'lib/om/xml/template_registry.rb', line 35

def initialize(templates={})
  @templates = templates.dup
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args) ⇒ Object



139
140
141
142
143
144
145
146
# File 'lib/om/xml/template_registry.rb', line 139

def method_missing(sym,*args)
  sym = sym.to_s.sub(/_$/,'').to_sym
  if @templates.has_key?(sym)
    instantiate(sym,*args)
  else
    super(sym,*args)
  end
end

Instance Method Details

#add_child(target_node, node_type, *args, &block) ⇒ Object

instantiate a node and add it as a child of the [Nokogiri::XML::Node] specified by target_node

Returns:

  • the new [Nokogiri::XML::Node]



90
91
92
# File 'lib/om/xml/template_registry.rb', line 90

def add_child(target_node, node_type, *args, &block)
  attach_node(:add_child, target_node, :self, node_type, *args, &block)
end

#add_next_sibling(target_node, node_type, *args, &block) ⇒ Object

instantiate a node and add it as a following sibling of the [Nokogiri::XML::Node] specified by target_node

Returns:

  • the new [Nokogiri::XML::Node]



96
97
98
# File 'lib/om/xml/template_registry.rb', line 96

def add_next_sibling(target_node, node_type, *args, &block)
  attach_node(:add_next_sibling, target_node, :parent, node_type, *args, &block)
end

#add_previous_sibling(target_node, node_type, *args, &block) ⇒ Object

instantiate a node and add it as a preceding sibling of the [Nokogiri::XML::Node] specified by target_node

Returns:

  • the new [Nokogiri::XML::Node]



102
103
104
# File 'lib/om/xml/template_registry.rb', line 102

def add_previous_sibling(target_node, node_type, *args, &block)
  attach_node(:add_previous_sibling, target_node, :parent, node_type, *args, &block)
end

#after(target_node, node_type, *args, &block) ⇒ Object

instantiate a node and add it as a following sibling of the [Nokogiri::XML::Node] specified by target_node

Returns:

  • target_node



108
109
110
# File 'lib/om/xml/template_registry.rb', line 108

def after(target_node, node_type, *args, &block)
  attach_node(:after, target_node, :parent, node_type, *args, &block)
end

#before(target_node, node_type, *args, &block) ⇒ Object

instantiate a node and add it as a preceding sibling of the [Nokogiri::XML::Node] specified by target_node

Returns:

  • target_node



114
115
116
# File 'lib/om/xml/template_registry.rb', line 114

def before(target_node, node_type, *args, &block)
  attach_node(:before, target_node, :parent, node_type, *args, &block)
end

#define(node_type) {|builder| ... } ⇒ Object

Define an XML template

Parameters:

  • node_type (Symbol)

    key to associate with this template

Yields:

  • (builder)

    a block that will receive a [Nokogiri::XML::Builder] object and any arbitrary parameters passed to instantiate

Yield Parameters:

  • (Nokogiri::XML::Builder)

Returns:

  • the node_type Symbol



44
45
46
47
48
49
50
51
# File 'lib/om/xml/template_registry.rb', line 44

def define(node_type, &block)
  unless node_type.is_a?(Symbol)
    raise TypeError, "Registered node type must be a Symbol (e.g., :person)"
  end

  @templates[node_type] = block
  node_type
end

#dupObject



130
131
132
133
# File 'lib/om/xml/template_registry.rb', line 130

def dup
  result = self.class.new(@templates)
  result
end

#has_node_type?(node_type) ⇒ True

Check whether a particular node_type is defined

Parameters:

  • node_type (Symbol)

    the node_type key to check

Returns:

  • (True)

    or [False]



64
65
66
# File 'lib/om/xml/template_registry.rb', line 64

def has_node_type?(node_type)
  @templates.has_key?(node_type)
end

#instantiate(node_type, *args) ⇒ Object

Instantiate a detached, standalone node

Parameters:

  • node_type (Symbol)

    the node_type to instantiate

  • args (Hash)

    additional arguments to pass to the template



77
78
79
80
81
82
83
84
85
86
# File 'lib/om/xml/template_registry.rb', line 77

def instantiate(node_type, *args)
  result = create_detached_node(nil, node_type, *args)
  # Strip namespaces from text and CDATA nodes. Stupid Nokogiri.
  result.traverse { |node|
    if node.is_a?(Nokogiri::XML::CharacterData)
      node.namespace = nil
    end
  }
  return result
end

#methodsObject



135
136
137
# File 'lib/om/xml/template_registry.rb', line 135

def methods
  super + @templates.keys.collect { |k| k.to_s }
end

#node_typesArray

List defined node_types

Returns:

  • (Array)

    of node_type symbols.



70
71
72
# File 'lib/om/xml/template_registry.rb', line 70

def node_types
  @templates.keys
end

#replace(target_node, node_type, *args, &block) ⇒ Object

instantiate a node replace the [Nokogiri::XML::Node] specified by target_node with it

Returns:

  • the new [Nokogiri::XML::Node]



120
121
122
# File 'lib/om/xml/template_registry.rb', line 120

def replace(target_node, node_type, *args, &block)
  attach_node(:replace, target_node, :parent, node_type, *args, &block)
end

#swap(target_node, node_type, *args, &block) ⇒ Object

instantiate a node replace the [Nokogiri::XML::Node] specified by target_node with it

Returns:

  • target_node



126
127
128
# File 'lib/om/xml/template_registry.rb', line 126

def swap(target_node, node_type, *args, &block)
  attach_node(:swap, target_node, :parent, node_type, *args, &block)
end

#undefine(node_type) ⇒ Object

Undefine an XML template

Parameters:

  • node_type (Symbol)

    the node_type key of the template to undefine

Returns:

  • the node_type Symbol



56
57
58
59
# File 'lib/om/xml/template_registry.rb', line 56

def undefine(node_type)
  @templates.delete(node_type)
  node_type
end