Register all needed templatetags, with these parameters :
            * library_register : the `register` object (result of
                `template.Library()`) in your templatetag module
            * nodename : the node to use for the cache templatetag (the default
                is "cache")
            * nocache_nodename : the node to use for the nocache templatetag

def register(cls, library_register, nodename='cache', nocache_nodename='nocache'):
        """
        Register all needed templatetags, with these parameters :
            * library_register : the `register` object (result of
                `template.Library()`) in your templatetag module
            * nodename : the node to use for the cache templatetag (the default
                is "cache")
            * nocache_nodename : the node to use for the nocache templatetag
        """

        if cls in CacheTag._templatetags:
            raise RuntimeError('The adv-cache-tag class %s is already registered' % cls)

        CacheTag._templatetags[cls] = {}

        def templatetag_cache(parser, token):
            """
            Return a new Node object for the main cache templatetag
            """
            nodelist = parser.parse(('end%s' % nodename,))
            parser.delete_first_token()
            args = cls.get_template_node_arguments(token.contents.split())
            return cls.Node(nodename, nodelist, *args)

        library_register.tag(nodename, templatetag_cache)
        CacheTag._templatetags[cls]['cache'] = templatetag_cache

        def templatetag_raw(parser, token):
            """
            Return a TextNode with all html not parsed, used for templatetags
            that need to not be parsed : the `nocache` one and the `RAW` one,
            used to surround cached html (to be not parsed again)
            Based on http://www.holovaty.com/writing/django-two-phased-rendering/
            """

            # Whatever is between {% nocache %} and {% endnocache %} will be preserved as
            # raw, un-rendered template code.

            text = []
            parse_until = 'end%s' % token.contents
            tag_mapping = {
                TOKEN_TEXT: ('', ''),
                TOKEN_VAR: ('{{', '}}'),
                TOKEN_BLOCK: ('{%', '%}'),
                TOKEN_COMMENT: ('{#', '#}'),
            }
            # By the time this template tag is called, the template system has already
            # lexed the template into tokens. Here, we loop over the tokens until
            # {% endraw %} and parse them to TextNodes. We have to add the start and
            # end bits (e.g. "{{" for variables) because those have already been
            # stripped off in a previous part of the template-parsing process.
            while parser.tokens:
                token = parser.next_token()
                if token.token_type == TOKEN_BLOCK and token.contents == parse_until:
                    return template.TextNode(''.join(text))
                start, end = tag_mapping[token.token_type]
                text.append('%s%s%s' % (start, token.contents, end))
            parser.unclosed_block_tag(parse_until)

        library_register.tag(cls.RAW_TOKEN, templatetag_raw)
        CacheTag._templatetags[cls]['raw'] = templatetag_raw

        def templatetag_nocache(parser, token):
            """
            Return a TextNode with raw html from the `nocache` templatetag,
            and surround it with `endRAW` and `RAW` (precisely
            `cls.RAW_TOKEN_END` and `cls.RAW_TOKEN_START`).
            So for
                {% nocache %}foo{% endnocache %}
            we get
                {% endRAW... %}foo{% RAW... %}
            When the main cache templatetag content will be loaded from cache,
            it will be surrounded by the same templatetags, reversed.
            So if at first we had
                {% cache %}bar{% nocache %}foo{% endnocache %}baz{% endcache %}
            The cached version will be
                bar{% endRAW... %}foo{% RAW... %}baz
            And the final html to be rendered will be
                {% RAW... %}bar{% endRAW... %}foo{% RAW... %}baz{% endRAW... %}
            And the html within `RAW` and `endRAW` will not be parsed, as wanted
            """

            # We'll load in the no-cache part all template tags and filters loaded in the main
            # template, to be able to use it when the no-cache will be rendered

            all_tags_and_filters = cls.get_all_tags_and_filters_by_function()
            available_tags = all_tags_and_filters['tags']
            available_filters = all_tags_and_filters['filters']

            needed = {}
            current_module = cls.get_templatetag_module()

            for function in parser.tags.values():
                if function in available_tags:
                    lib, name = available_tags[function]
                    if lib == current_module:
                        continue
                    needed.setdefault(lib, set()).add(name)

            for function in parser.filters.values():
                if function in available_filters:
                    lib, name = available_filters[function]
                    if lib == current_module:
                        continue
                    needed.setdefault(lib, set()).add(name)

            load_string = ''.join(
                '%sload %s from %s%s' % (
                    template.BLOCK_TAG_START,
                    ' '.join(names),
                    lib,
                    template.BLOCK_TAG_END,
                )
                for lib, names in needed.items()
            )

            node = templatetag_raw(parser, token)
            node.s = cls.RAW_TOKEN_END + load_string + node.s + cls.RAW_TOKEN_START
            return node

        library_register.tag(nocache_nodename, templatetag_nocache)
        CacheTag._templatetags['nocache'] = templatetag_nocache