@register.tag
def paginate(parser, token, paginator_class=None):
    """Paginate objects.

    Usage:

    .. code-block:: html+django

        {% paginate entries %}

    After this call, the *entries* variable in the template context is replaced
    by only the entries of the current page.

    You can also keep your *entries* original variable (usually a queryset)
    and add to the context another name that refers to entries of the current
    page, e.g.:

    .. code-block:: html+django

        {% paginate entries as page_entries %}

    The *as* argument is also useful when a nested context variable is provided
    as queryset. In this case, and only in this case, the resulting variable
    name is mandatory, e.g.:

    .. code-block:: html+django

        {% paginate entries.all as entries %}

    The number of paginated entries is taken from settings, but you can
    override the default locally, e.g.:

    .. code-block:: html+django

        {% paginate 20 entries %}

    Of course you can mix it all:

    .. code-block:: html+django

        {% paginate 20 entries as paginated_entries %}

    By default, the first page is displayed the first time you load the page,
    but you can change this, e.g.:

    .. code-block:: html+django

        {% paginate entries starting from page 3 %}

    When changing the default page, it is also possible to reference the last
    page (or the second last page, and so on) by using negative indexes, e.g:

    .. code-block:: html+django

        {% paginate entries starting from page -1 %}

    This can be also achieved using a template variable that was passed to the
    context, e.g.:

    .. code-block:: html+django

        {% paginate entries starting from page page_number %}

    If the passed page number does not exist, the first page is displayed.

    If you have multiple paginations in the same page, you can change the
    querydict key for the single pagination, e.g.:

    .. code-block:: html+django

        {% paginate entries using article_page %}

    In this case *article_page* is intended to be a context variable, but you
    can hardcode the key using quotes, e.g.:

    .. code-block:: html+django

        {% paginate entries using 'articles_at_page' %}

    Again, you can mix it all (the order of arguments is important):

    .. code-block:: html+django

        {% paginate 20 entries
            starting from page 3 using page_key as paginated_entries %}

    Additionally you can pass a path to be used for the pagination:

    .. code-block:: html+django

        {% paginate 20 entries
            using page_key with pagination_url as paginated_entries %}

    This way you can easily create views acting as API endpoints, and point
    your Ajax calls to that API. In this case *pagination_url* is considered a
    context variable, but it is also possible to hardcode the URL, e.g.:

    .. code-block:: html+django

        {% paginate 20 entries with "/mypage/" %}

    If you want the first page to contain a different number of items than
    subsequent pages, you can separate the two values with a comma, e.g. if
    you want 3 items on the first page and 10 on other pages:

    .. code-block:: html+django

    {% paginate 3,10 entries %}

    You must use this tag before calling the {% show_more %} one.
    """
    # Validate arguments.
    try:
        tag_name, tag_args = token.contents.split(None, 1)
    except __HOLE__:
        msg = '%r tag requires arguments' % token.contents.split()[0]
        raise template.TemplateSyntaxError(msg)

    # Use a regexp to catch args.
    match = PAGINATE_EXPRESSION.match(tag_args)
    if match is None:
        msg = 'Invalid arguments for %r tag' % tag_name
        raise template.TemplateSyntaxError(msg)

    # Retrieve objects.
    kwargs = match.groupdict()
    objects = kwargs.pop('objects')

    # The variable name must be present if a nested context variable is passed.
    if '.' in objects and kwargs['var_name'] is None:
        msg = (
            '%(tag)r tag requires a variable name `as` argumnent if the '
            'queryset is provided as a nested context variable (%(objects)s). '
            'You must either pass a direct queryset (e.g. taking advantage '
            'of the `with` template tag) or provide a new variable name to '
            'store the resulting queryset (e.g. `%(tag)s %(objects)s as '
            'objects`).'
        ) % {'tag': tag_name, 'objects': objects}
        raise template.TemplateSyntaxError(msg)

    # Call the node.
    return PaginateNode(paginator_class, objects, **kwargs)
dataset/ETHPy150Open frankban/django-endless-pagination/endless_pagination/templatetags/endless.py/paginate