A decorator that is used for inserting the decorated block function in
    the block template hierarchy.

    The :func:`block` decorator accepts the following arguments:

    :param context_name: key in the `g.blocks` dictionary in which the result
                         of the decorated block function will be stored for
                         further processing by the parent block function
                         `parent_block_func`.
    :param parent_block_func: parent block function in the template hierarchy
                              which will use the stored result.
    :param view_func: the decorated block will take an effect only in the
                      execution context of the specified view function.  If the
                      default value of `None` is used, then the block will be
                      used as default for the specified `context_name`.
                      Internally this parameter is converted to a Werkzeug
                      endpoint in the same way Flask is doing that with the
                      `Flask.route` decorator.

def block(context_name, parent_block_func, view_func=None):
    """A decorator that is used for inserting the decorated block function in
    the block template hierarchy.

    The :func:`block` decorator accepts the following arguments:

    :param context_name: key in the `g.blocks` dictionary in which the result
                         of the decorated block function will be stored for
                         further processing by the parent block function
                         `parent_block_func`.
    :param parent_block_func: parent block function in the template hierarchy
                              which will use the stored result.
    :param view_func: the decorated block will take an effect only in the
                      execution context of the specified view function.  If the
                      default value of `None` is used, then the block will be
                      used as default for the specified `context_name`.
                      Internally this parameter is converted to a Werkzeug
                      endpoint in the same way Flask is doing that with the
                      `Flask.route` decorator.
    """
    def decorator(block_func):
        block = Block(block_func, view_func)
        parent_block = Block.block_mapping[parent_block_func]
        parent_block.append_context_block(context_name, block)
        return block_func
    return decorator