lib/macros4cuke/templating/engine.rb in macros4cuke-0.4.02 vs lib/macros4cuke/templating/engine.rb in macros4cuke-0.4.03
- old
+ new
@@ -1,12 +1,16 @@
# File: engine.rb
-# Purpose: Implementation of the MacroStep class.
+# Purpose: Implementation of the Engine class.
require 'strscan' # Use the StringScanner for lexical analysis.
require_relative '../exceptions' # Load the custom exception classes.
+require_relative 'template-element'
+require_relative 'placeholder'
+require_relative 'section' # Load the Section and ConditionalSection
+
module Macros4Cuke # Module used as a namespace
# Module containing all classes implementing the simple template engine
# used internally in Macros4Cuke.
@@ -78,173 +82,9 @@
def render(aContextObject, theLocals)
return "\n"
end
end # class
-
-# Base class used internally by the template engine.
-# The generalization of any element from a template that has one variable
-# whose actual value influences the rendition.
-class UnaryElement
- # The name of the placeholder/variable.
- attr_reader(:name)
-
- # @param aVarName [String] The name of the placeholder from a template.
- def initialize(aVarName)
- @name = aVarName
- end
-
- protected
-
- # This method has the same signature as the {Engine#render} method.
- # @return [Object] The actual value from the locals or context
- # that is assigned to the variable.
- def retrieve_value_from(aContextObject, theLocals)
- actual_value = theLocals[name]
- if actual_value.nil? && aContextObject.respond_to?(name.to_sym)
- actual_value = aContextObject.send(name.to_sym)
- end
-
- return actual_value
- end
-
-end # class
-
-
-
-# Class used internally by the template engine.
-# Represents a named placeholder in a template, that is,
-# a name placed between <..> in the template.
-# At rendition, a placeholder is replaced by the text value
-# that is associated with it.
-class Placeholder < UnaryElement
-
- public
-
- # Render the placeholder given the passed arguments.
- # This method has the same signature as the {Engine#render} method.
- # @return [String] The text value assigned to the placeholder.
- # Returns an empty string when no value is assigned to the placeholder.
- def render(aContextObject, theLocals)
- actual_value = retrieve_value_from(aContextObject, theLocals)
-
- result = case actual_value
- when NilClass
- ''
-
- when Array
- # TODO: Move away from hard-coded separator.
- actual_value.join('<br/>')
-
- when String
- actual_value
- else
- actual_value.to_s
- end
-
- return result
- end
-
-end # class
-
-
-# Base class used internally by the template engine.
-# Represents a section in a template, that is,
-# a set of template elements for which its rendition depends
-# on the value of a variable.
-class Section < UnaryElement
- # The child elements of the section
- attr_reader(:children)
-
- # @param aVarName [String] The name of the placeholder from a template.
- def initialize(aVarName)
- super(aVarName)
- @children = []
- end
-
- public
-
- # Add a child element as member of the section
- def add_child(aChild)
- children << aChild
- end
-
- # Retrieve all placeholder names that appear in the template.
- # @return [Array] The list of placeholder names.
- def variables()
- all_vars = children.each_with_object([]) do |a_child, subResult|
- case a_child
- when Placeholder
- subResult << a_child.name
- when Section
- subResult.concat(a_child.variables)
- else
- # Do nothing
- end
- end
-
- return all_vars.flatten.uniq
- end
-
-
- # Render the placeholder given the passed arguments.
- # This method has the same signature as the {Engine#render} method.
- # @return [String] The text value assigned to the placeholder.
- # Returns an empty string when no value is assigned to the placeholder.
- def render(aContextObject, theLocals)
- msg = "Method Section.#{__method__} must be implemented in subclass."
- fail(NotImplementedError, msg)
- end
-
-end # class
-
-
-# A specialized section in a template for which its rendition
-# depends on the (in)existence of an actual value bound to the variable name.
-class ConditionalSection < Section
- # A boolean that indicates whether the rendition condition is
- # the existence of a value for the variable (true)
- # or its inexistence (false).
- attr_reader(:existence)
-
- # @param aVarName [String] The name of the placeholder from a template.
- # @param renderWhenExisting [boolean] When true, render the children elements
- # if a value exists for the variable.
- def initialize(aVarName, renderWhenExisting = true)
- super(aVarName)
- @existence = renderWhenExisting
- end
-
- public
-
- # Render the placeholder given the passed arguments.
- # This method has the same signature as the {Engine#render} method.
- # @return [String] The text value assigned to the placeholder.
- # Returns an empty string when no value is assigned to the placeholder.
- def render(aContextObject, theLocals)
- actual_value = retrieve_value_from(aContextObject, theLocals)
- if (!actual_value.nil? && existence) || (actual_value.nil? && !existence)
- # Let render the children
- result = children.each_with_object('') do |a_child, sub_result|
- sub_result << a_child.render(aContextObject, theLocals)
- end
- else
- result = ''
- end
-
- return result
- end
-
-
- # @return [String] The original text representation of the tag.
- def to_s()
- return "<?#{name}>"
- end
-
-end # class
-
-
-SectionEndMarker = Struct.new(:name)
# A very simple implementation of a templating engine.
# Earlier versions of Macros4Cuke relied on the logic-less
# Mustache template engine.