Decorator to easily create a jinja extension which acts as a fragment.

def jinja_fragment_extension(tag, endtag=None, name=None, tag_only=False, allow_args=True, callblock_args=None):
    """Decorator to easily create a jinja extension which acts as a fragment.
    """
    if endtag is None:
        endtag = "end" + tag

    def decorator(f):
        def parse(self, parser):
            lineno = parser.stream.next().lineno
            args = []
            kwargs = []
            if allow_args:
                args, kwargs = parse_block_signature(parser)

            call = self.call_method("support_method", args, kwargs, lineno=lineno)
            if tag_only:
                return nodes.Output([call], lineno=lineno)

            call_args = []
            if callblock_args is not None:
                for arg in callblock_args:
                    call_args.append(nodes.Name(arg, 'param', lineno=lineno))

            body = parser.parse_statements(['name:' + endtag], drop_needle=True)
            return nodes.CallBlock(call, call_args, [], body, lineno=lineno)

        def support_method(self, *args, **kwargs):
            return f(*args, **kwargs)

        attrs = {"tags": set([tag]), "parse": parse, "support_method": support_method}
        return type(name or f.__name__, (Extension,), attrs)

    return decorator