def url(parser, token):
    """
    Returns an absolute URL matching given view with its parameters.

    This is a way to define links that aren't tied to a particular URL
    configuration::

        {% url "path.to.some_view" arg1 arg2 %}

        or

        {% url "path.to.some_view" name1=value1 name2=value2 %}

    The first argument is a path to a view. It can be an absolute python path
    or just ``app_name.view_name`` without the project name if the view is
    located inside the project.  Other arguments are comma-separated values
    that will be filled in place of positional and keyword arguments in the
    URL. All arguments for the URL should be present.

    For example if you have a view ``app_name.client`` taking client's id and
    the corresponding line in a URLconf looks like this::

        ('^client/(\d+)/$', 'app_name.client')

    and this app's URLconf is included into the project's URLconf under some
    path::

        ('^clients/', include('project_name.app_name.urls'))

    then in a template you can create a link for a certain client like this::

        {% url "app_name.client" client.id %}

    The URL will look like ``/clients/client/123/``.
    """
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError("'%s' takes at least one argument"
                                  " (path to a view)" % bits[0])
    viewname = parser.compile_filter(bits[1])
    args = []
    kwargs = {}
    asvar = None
    bits = bits[2:]
    if len(bits) >= 2 and bits[-2] == 'as':
        asvar = bits[-1]
        bits = bits[:-2]

    if len(bits):
        for bit in bits:
            match = kwarg_re.match(bit)
            if not match:
                raise TemplateSyntaxError("Malformed arguments to url tag")
            name, value = match.groups()
            if name:
                kwargs[name] = parser.compile_filter(value)
            else:
                args.append(parser.compile_filter(value))

    return URLNode(viewname, args, kwargs, asvar, legacy_view_name=False)
示例#2
0
def backend_url(parser, token):
    from django.template.base import kwarg_re
    from django.template.defaulttags import URLNode
    from django_backend import state

    bits = token.split_contents()
    if len(bits) < 2:
        raise template.TemplateSyntaxError("'%s' takes at least one argument"
                                  " (path to a view)" % bits[0])
    viewname = parser.compile_filter(bits[1])
    args = []
    kwargs = {}
    asvar = None
    bits = bits[2:]
    if len(bits) >= 2 and bits[-2] == 'as':
        asvar = bits[-1]
        bits = bits[:-2]

    if len(bits):
        for bit in bits:
            match = kwarg_re.match(bit)
            if not match:
                raise template.TemplateSyntaxError("Malformed arguments to url tag")
            name, value = match.groups()
            if name:
                kwargs[name] = parser.compile_filter(value)
            else:
                args.append(parser.compile_filter(value))

    kwargs.setdefault('site', template.Variable('"%s"' % Site.objects.get_current().pk))
    kwargs.setdefault('language', template.Variable('"%s"' % state.language.active))

    return URLNode(viewname, args, kwargs, asvar)
示例#3
0
 def test_repr(self):
     url_node = URLNode(view_name='named-view',
                        args=[],
                        kwargs={},
                        asvar=None)
     self.assertEqual(
         repr(url_node),
         "<URLNode view_name='named-view' args=[] kwargs={} as=None>",
     )
     url_node = URLNode(
         view_name='named-view',
         args=[1, 2],
         kwargs={'action': 'update'},
         asvar='my_url',
     )
     self.assertEqual(
         repr(url_node),
         "<URLNode view_name='named-view' args=[1, 2] "
         "kwargs={'action': 'update'} as='my_url'>",
     )
示例#4
0
def murl(parser, token):
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError("'%s' takes at least one argument"
                                  " (path to a view)" % bits[0])
    viewname_str = bits[1]
    viewname = parser.compile_filter(viewname_str)
    args = []
    kwargs = {}
    asvar = None
    bits = bits[2:]
    if len(bits) >= 2 and bits[-2] == 'as':
        asvar = bits[-1]
        bits = bits[:-2]

    if len(bits):
        for bit in bits:
            match = kwarg_re.match(bit)
            if not match:
                raise TemplateSyntaxError("Malformed arguments to url tag")
            name, value = match.groups()
            if name:
                kwargs[name] = parser.compile_filter(value)
            else:
                args.append(parser.compile_filter(value))

    request = current_request()
    site_id_val = parser.compile_filter(str(request.site_id))
    if hasattr(request,'site_id'):
        if args is None and kwargs is None:
            kwargs = {'site_id': site_id_val}
        elif args is None and kwargs is not None:
            kwargs['site_id'] = site_id_val
        elif args is not None and kwargs is None:
            args = [site_id_val]+args
        elif len(args) == 0:
            kwargs['site_id'] = site_id_val
        elif len(kwargs) == 0:
            args = [site_id_val]+list(args)
        else:
            kwargs['site_id'] = site_id_val

    return URLNode(viewname, args, kwargs, asvar)
示例#5
0
    def resolve(self, context, resolved_object=None):
        AccessControlList = apps.get_model(app_label='acls',
                                           model_name='AccessControlList')

        request = Variable('request').resolve(context)
        current_path = request.META['PATH_INFO']
        current_view = resolve(current_path).view_name

        # ACL is tested agains the resolved_object or just {{ object }} if not
        if not resolved_object:
            try:
                resolved_object = Variable('object').resolve(context=context)
            except VariableDoesNotExist:
                pass

        # If this link has a required permission check that the user has it
        # too
        if self.permissions:
            if resolved_object:
                try:
                    AccessControlList.objects.check_access(
                        permissions=self.permissions,
                        user=request.user,
                        obj=resolved_object,
                        related=self.permissions_related)
                except PermissionDenied:
                    return None
            else:
                try:
                    Permission.check_permissions(requester=request.user,
                                                 permissions=self.permissions)
                except PermissionDenied:
                    return None

        # Check to see if link has conditional display function and only
        # display it if the result of the conditional display function is
        # True
        if self.condition:
            if not self.condition(context):
                return None

        resolved_link = ResolvedLink(current_view=current_view, link=self)

        if self.view:
            view_name = Variable('"{}"'.format(self.view))
            if isinstance(self.args, list) or isinstance(self.args, tuple):
                # TODO: Don't check for instance check for iterable in try/except
                # block. This update required changing all 'args' argument in
                # links.py files to be iterables and not just strings.
                args = [Variable(arg) for arg in self.args]
            else:
                args = [Variable(self.args)]

            # If we were passed an instance of the view context object we are
            # resolving, inject it into the context. This help resolve links for
            # object lists.
            if resolved_object:
                context['resolved_object'] = resolved_object

            try:
                kwargs = self.kwargs(context)
            except TypeError:
                # Is not a callable
                kwargs = self.kwargs

            kwargs = {key: Variable(value) for key, value in kwargs.items()}

            # Use Django's exact {% url %} code to resolve the link
            node = URLNode(view_name=view_name,
                           args=args,
                           kwargs=kwargs,
                           asvar=None)
            try:
                resolved_link.url = node.render(context)
            except Exception as exception:
                logger.error('Error resolving link "%s" URL; %s', self.text,
                             exception)
        elif self.url:
            resolved_link.url = self.url

        # This is for links that should be displayed but that are not clickable
        if self.conditional_disable:
            resolved_link.disabled = self.conditional_disable(context)
        else:
            resolved_link.disabled = False

        # Lets a new link keep the same URL query string of the current URL
        if self.keep_query:
            # Sometimes we are required to remove a key from the URL QS
            parsed_url = furl(
                force_str(request.get_full_path() or request.META.get(
                    'HTTP_REFERER', resolve_url(settings.LOGIN_REDIRECT_URL))))

            for key in self.remove_from_query:
                try:
                    parsed_url.query.remove(key)
                except KeyError:
                    pass

            # Use the link's URL but with the previous URL querystring
            new_url = furl(resolved_link.url)
            new_url.args = parsed_url.querystr
            resolved_link.url = new_url.url

        resolved_link.context = context
        return resolved_link
示例#6
0
def url(parser, token):

    bits = token.split_contents()
    if len(bits) < 2: 
        raise TemplateSyntaxError("'%s' takes at least one argument"
                                  " (path to a view)" % bits[0])
    viewname = bits[1]
    args = []
    kwargs = {}
    asvar = None
    bits = bits[2:]
    if len(bits) >= 2 and bits[-2] == 'as':
        asvar = bits[-1]
        bits = bits[:-2]

    # Backwards compatibility: check for the old comma separated format
    # {% url urlname arg1,arg2 %}
    # Initial check - that the first space separated bit has a comma in it
    if bits and ',' in bits[0]:
        check_old_format = True
        # In order to *really* be old format, there must be a comma
        # in *every* space separated bit, except the last.
        for bit in bits[1:-1]:
            if ',' not in bit:
                # No comma in this bit. Either the comma we found
                # in bit 1 was a false positive (e.g., comma in a string),
                # or there is a syntax problem with missing commas
                check_old_format = False
                break
    else:
        # No comma found - must be new format.
        check_old_format = False

    if check_old_format:
        # Confirm that this is old format by trying to parse the first
        # argument. An exception will be raised if the comma is
        # unexpected (i.e. outside of a static string).
        match = kwarg_re.match(bits[0])
        if match:
            value = match.groups()[1]
            try:
                parser.compile_filter(value)
            except TemplateSyntaxError:
                bits = ''.join(bits).split(',')

    # Now all the bits are parsed into new format,
    # process them as template vars

    if len(bits):
        for bit in bits:
            match = kwarg_re.match(bit)
            if not match:
                raise TemplateSyntaxError("Malformed arguments to url tag")
            name, value = match.groups()
            if name:
                kwargs[name] = parser.compile_filter(value)
            else:
                args.append(parser.compile_filter(value))
    
    viewname =  OptinThemeManager.getThemeStaticUrl(viewname, args)
    return URLNode(viewname, args, kwargs, asvar)
示例#7
0
    def resolve(self, context, resolved_object=None):
        request = Variable('request').resolve(context)
        current_path = request.META['PATH_INFO']
        current_view = resolve(current_path).view_name

        # ACL is tested agains the resolved_object or just {{ object }} if not
        if not resolved_object:
            try:
                resolved_object = Variable('object').resolve(context=context)
            except VariableDoesNotExist:
                pass

        # If this link has a required permission check that the user have it
        # too
        if self.permissions:
            try:
                Permission.check_permissions(request.user, self.permissions)
            except PermissionDenied:
                # If the user doesn't have the permission, and we are passed
                # an instance, check to see if the user has at least ACL
                # access to the instance.
                if resolved_object:
                    try:
                        AccessControlList.objects.check_access(
                            self.permissions, request.user, resolved_object)
                    except PermissionDenied:
                        return None
                else:
                    return None

        # Check to see if link has conditional display function and only
        # display it if the result of the conditional display function is
        # True
        if self.condition:
            if not self.condition(context):
                return None

        resolved_link = ResolvedLink(current_view=current_view, link=self)

        view_name = Variable('"{}"'.format(self.view))
        if isinstance(self.args, list) or isinstance(self.args, tuple):
            # TODO: Don't check for instance check for iterable in try/except
            # block. This update required changing all 'args' argument in
            # links.py files to be iterables and not just strings.
            args = [Variable(arg) for arg in self.args]
        else:
            args = [Variable(self.args)]

        # If we were passed an instance of the view context object we are
        # resolving, inject it into the context. This help resolve links for
        # object lists.
        if resolved_object:
            context['resolved_object'] = resolved_object

        try:
            kwargs = self.kwargs(context)
        except TypeError:
            # Is not a callable
            kwargs = self.kwargs

        kwargs = {key: Variable(value) for key, value in kwargs.iteritems()}

        # Use Django's exact {% url %} code to resolve the link
        node = URLNode(view_name=view_name,
                       args=args,
                       kwargs=kwargs,
                       asvar=None)

        try:
            resolved_link.url = node.render(context)
        except Exception as exception:
            logger.error('Error resolving link "%s" URL; %s', self.text,
                         exception)

        # This is for links that should be displayed but that are not clickable
        if self.conditional_disable:
            resolved_link.disabled = self.conditional_disable(context)
        else:
            resolved_link.disabled = False

        # Lets a new link keep the same URL query string of the current URL
        if self.keep_query:
            # Sometimes we are required to remove a key from the URL QS
            previous_path = smart_unicode(
                urllib.unquote_plus(
                    smart_str(request.get_full_path()) or smart_str(
                        request.META.get('HTTP_REFERER',
                                         reverse(
                                             settings.LOGIN_REDIRECT_URL)))))
            query_string = urlparse.urlparse(previous_path).query
            parsed_query_string = urlparse.parse_qs(query_string)

            for key in self.remove_from_query:
                try:
                    del parsed_query_string[key]
                except KeyError:
                    pass

            resolved_link.url = '%s?%s' % (urlquote(
                resolved_link.url), urlencode(parsed_query_string, doseq=True))

        return resolved_link
示例#8
0
def url(parser, token):
    r"""
    Return an absolute URL matching the given view with its parameters.

    This is a way to define links that aren't tied to a particular URL
    configuration::

        {% url "url_name" arg1 arg2 %}

        or

        {% url "url_name" name1=value1 name2=value2 %}

    The first argument is a django.conf.urls.url() name. Other arguments are
    space-separated values that will be filled in place of positional and
    keyword arguments in the URL. Don't mix positional and keyword arguments.
    All arguments for the URL must be present.

    For example, if you have a view ``app_name.views.client_details`` taking
    the client's id and the corresponding line in a URLconf looks like this::

        url('^client/(\d+)/$', views.client_details, name='client-detail-view')

    and this app's URLconf is included into the project's URLconf under some
    path::

        url('^clients/', include('app_name.urls'))

    then in a template you can create a link for a certain client like this::

        {% url "client-detail-view" client.id %}

    The URL will look like ``/clients/client/123/``.

    The first argument may also be the name of a template variable that will be
    evaluated to obtain the view name or the URL name, e.g.::

        {% with url_name="client-detail-view" %}
        {% url url_name client.id %}
        {% endwith %}
    """
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError(
            "'%s' takes at least one argument, the name of a url()." % bits[0])
    viewname = parser.compile_filter(bits[1])
    args = []
    kwargs = {}
    asvar = None
    bits = bits[2:]
    if len(bits) >= 2 and bits[-2] == 'as':
        asvar = bits[-1]
        bits = bits[:-2]

    if len(bits):
        for bit in bits:
            match = kwarg_re.match(bit)
            if not match:
                raise TemplateSyntaxError("Malformed arguments to url tag")
            name, value = match.groups()
            if name:
                kwargs[name] = parser.compile_filter(value)
            else:
                args.append(parser.compile_filter(value))

    return URLNode(viewname, args, kwargs, asvar)