Inversion::Template::

BeginTag class

Inversion ‘begin’ tag.

This tag causes a section of the template to be rendered only if no exceptions are raised while it’s being rendered. If an exception is raised, it is checked against any ‘rescue’ blocks, and the first one with a matching exception is rendered instead. If no ‘rescue’ block is found, the exception is handled by the configured exception behavior for the template, and the resulting replaces the block.

Syntax

<?begin ?><?call employees.length ?><?end?>

<?begin ?>
    <?for employee in employees.all ?>
        <?attr employee.name ?> --> <?attr employee.title ?>
    <?end for?>
<?rescue DatabaseError => err ?>
    Oh no!! I can't talk to the database for some reason.  The
    error was as follows:
    <pre>
        <?attr err.message ?>
    </pre>
<?end?>

Attributes

rescue_clauses R

The tuples of rescue clauses handled by the begin

Public Instance Methods

<<( subnode )

Override the append operator to separate out RescueTags and the nodes that follow them.

# File lib/inversion/template/begintag.rb, line 55
def <<( subnode )
        case

        # If this node is a <?rescue?>, add a container for the subnodes that belong to it
        # and the list of exception types that it rescues
        when subnode.is_a?( Inversion::Template::RescueTag )
                @rescue_clauses << [ subnode.exception_types, [] ]

        # If there's already at least one rescue clause in effect, add any subnodes to
        # the last one
        when !@rescue_clauses.empty?
                @rescue_clauses.last[1] << subnode

        # Append nodes in the begin, but before any rescue to the begin tag
        else
                super
        end

        return self
end
handle_exception( state, node, exception )

The replacement exception-handler provided to RenderState.

# File lib/inversion/template/begintag.rb, line 99
def handle_exception( state, node, exception )
        self.log.debug "Handling %p raised by %p: %s" % [ exception.class, node, exception.message ]
        state.destination.clear

        self.rescue_clauses.each do |errclasses, nodes|
                self.log.debug "  considering rescue clause: %p -> %p" % [ errclasses, nodes ]
                if errclasses.any? {|eclass| eclass === exception }
                        self.log.debug "  rescued by a clause for %p" % [ errclasses ]
                        nodes.each {|innernode| state << innernode }
                        throw :stop_rendering
                end
        end

        # Use the default error handler
        self.log.debug "  no rescue clause for a %p: falling back to the default error handler" %
                [ exception.class ]
        state.destination << state.default_error_handler( state, node, exception )
        throw :stop_rendering
end
render( state )

Render the tag’s contents if the condition is true, or any else or elsif sections if the condition isn’t true.

# File lib/inversion/template/begintag.rb, line 79
def render( state )
        output = []

        errhandler = self.method( :handle_exception )
        state.with_destination( output ) do
                state.with_error_handler( errhandler ) do
                        catch( :stop_rendering ) do
                                super
                        end
                        self.log.debug "  leaving the error-handler block"
                end
                self.log.debug "  leaving the overridden output block"
        end

        self.log.debug "Rendered begin section as: %p" % [ output ]
        return output
end

Protected Instance Methods

initialize( body='', linenum=nil, colnum=nil )

Initialize a new BeginTag.

# File lib/inversion/template/begintag.rb, line 39
def initialize( body='', linenum=nil, colnum=nil ) # :notnew:
        super
        @rescue_clauses = [] # [ [RuntimeError, ArgumentError], [subnodes] ]
end