Opened 5 years ago

Closed 14 months ago

#16391 closed New feature (wontfix)

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 Morales)

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>

Change History (10)

comment:1 Changed 5 years ago by Aymeric Augustin

Triage Stage: UnreviewedDesign 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 5 years ago by Aymeric Augustin (previous) (diff)

comment:2 Changed 5 years ago by Jannis Leidel

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

comment:3 Changed 5 years ago by Ramiro Morales

Description: modified (diff)

comment:4 Changed 5 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 5 years ago by Jacob

Triage Stage: Design decision neededSomeday/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 4 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 4 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 4 years ago by Mitar

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

comment:9 Changed 4 years ago by Aymeric Augustin

Component: Core (Other)Core (URLs)

#2615 was a duplicate.

comment:10 Changed 14 months ago by Tim Graham

Resolution: wontfix
Status: newclosed

I haven't heard of much demand for this feature, so living as a third-party library seems okay to me.

Note: See TracTickets for help on using tickets.
Back to Top