Code

Opened 3 years ago

Last modified 16 months ago

#16391 new New feature

New URL tag for reversing urls with placeholder args/kwargs

Reported by: h.a.clifford@… Owned by: nobody
Component: Core (URLs) Version: 1.3
Severity: Normal Keywords:
Cc: mmitar@… Triage Stage: Someday/Maybe
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by ramiro)

It would be incredibly useful if Django supported a placeholder url tag:

usage would be similar to url, but with args/kwargs that don't match the url regex.

E.g: {% urlplaceholder User username='<%username%>' %}, where my url rule only allows a-z usernames.
(Currently, you can't do this).

This isn't a huge change which is why I'm suggesting it (line 325 urlresolves does the regex check after substituting in the values)

Why is this useful? It would allow *easy* generation of javascript templates on the frontend - all the current methods seem to involve reversing the urls with javasacript which is hardly in keeping DRY.

Example:

<script id='UserTemplate' type='jqueryTemplate'>
<a href='{% urlplaceholder User username='<%username%>' %}'>
<img src='{% get_media_url %}/user.png'>
</a>
</script>

Attachments (0)

Change History (9)

comment:1 Changed 3 years ago by aaugustin

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Design decision needed

I wouldn't dismiss the regex check so quickly. Currently, there's a guarantee that an URL generated with reverse will be resolved correctly. While I understand your reasons to drop this guarantee, we can't do this lightly.

Note that if #16362 was committed, it would rely on the regex check after substituting the values. Those two tickets are incompatible.

You could use a something like r'/users/(?:<% )(\w+)(?: %>)' or r'/users/(\w+|<% \w+ %>)' in your URLconf — sure, it's a hack.

EDIT: while working on this, I missed the fact that the ticket suggested a new tag, not a modification of the existing tag. Please disregard the comment above. Still, it's DDN.

Last edited 3 years ago by aaugustin (previous) (diff)

comment:2 Changed 3 years ago by jezdez

This sounds like a great idea for a 3rd party app, that would provide helpers for JavaScript development.

comment:3 Changed 3 years ago by ramiro

  • Description modified (diff)

comment:4 Changed 3 years ago by anonymous

To follow up on this, would also be useful with URI templates:

http://code.google.com/p/uri-templates/
http://bitworking.org/projects/URI-Templates

comment:5 Changed 3 years ago by jacob

  • Triage Stage changed from Design decision needed to Someday/Maybe

I agree with jezdez - this is something that'd be best done in a third-party app. I'm not going to close this ticket, but I am going to stick it in "someday/maybe" purgatory. I think it's a good idea, but the way to get this in Django is to start with a solid third-party implementation and then push to get that in.

Thanks!

comment:6 Changed 2 years ago by mitar

  • Cc mmitar@… added

Without the support in reverse which would allow caller to skip regex check (but the default would of course still be to check it) it would be hard to implement such a tag (which I am also missing) without duplicating code (and thus breaking the DRY principle).

+1 for at least support for reverse to have an argument to skip regex check. Then tag is simple to implement.

comment:7 Changed 2 years ago by mitar

Maybe I am wrong. This simple version works quite nicely:

@register.simple_tag
def urltemplate(viewname):
    urlconf = urlresolvers.get_urlconf()
    resolver = urlresolvers.get_resolver(urlconf)
    prefix = urlresolvers.get_script_prefix()

    possibilities = resolver.reverse_dict.getlist(viewname)

    if len(possibilities) != 1:
        # TODO: Template tags should not the throwing exceptions (only if TEMPLATE_DEBUG is true)
        raise NotImplementedError

    possibility, pattern, defaults = possibilities[0]

    if len(possibility) != 1:
        # TODO: Template tags should not the throwing exceptions (only if TEMPLATE_DEBUG is true)
        raise NotImplementedError

    result, params = possibility[0]

    for param in params:
        result = result.replace('%%(%s)s' % param, '{%s}' % param)

    return prefix + result

comment:8 Changed 22 months ago by mitar

I add this code (with some improvements) to my library.

comment:9 Changed 16 months ago by aaugustin

  • Component changed from Core (Other) to Core (URLs)

#2615 was a duplicate.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as new
The owner will be changed from nobody to anonymous. Next status will be 'assigned'
as The resolution will be set. Next status will be 'closed'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.