4

Is there a way to have reversible, named URLs for Django flatpages (or multilingual-ng, which is flatpages + translations)?

If not, is there a similar app available which can have named URLs for pages which are editable through the admin? (And I'd rather avoid any behemoth CMSs, please.)

edit: Please see the comments in the answers below for more discussion and clarification of the question.

aehlke
  • 15,225
  • 5
  • 36
  • 45
  • What do you mean by "Reversible" - can you give examples? – Mez Nov 08 '10 at 07:21
  • So that I can give a name to the page's URL, which will work with reverse() and {% url my-flatpages-url-name %}. Preferably for multilingual-ng! – aehlke Nov 08 '10 at 10:19

3 Answers3

9

As the very last thing in your root URLConf, put

(r'^(?P<url>.*)$', 'django.contrib.flatpages.views.flatpage'),

Now you can use the {% url %} tag, with the view name flatpage and the keyword argument url. You can also use the reverse() function in views.

James Bennett
  • 10,903
  • 4
  • 35
  • 24
  • Great stuff, only one remark - shouldn't *flatpage* be preceded by *django.contrib.flatpages.views*, like in *django/contrib/flatpages/urls.py* ? – Tomasz Zieliński Nov 10 '10 at 09:51
  • Thanks for answering - I think I didn't ask my question clearly enough though, since this does sort of satisfy what I asked in a clever, clean way (although I don't think you can call these "named URLs"), but doesn't help the situation I was trying to avoid: hard-coding URLs in my templates. – aehlke Nov 12 '10 at 07:46
  • A flatpage only has two unique attributes: one is its database ID, the other is its URL. So those are the only things you've got to go on for uniquely identifying a flatpage, and generally the URL's a lot more memorable (and shouldn't be changing over time). – James Bennett Nov 15 '10 at 13:06
  • 1
    There's no benefit to using the URL as a keyword to lookup the URL itself though. I'm not adverse to adding another field to the FlatPage model for a URL name, if I could figure out how to hook it into the patterns that reverse() references. – aehlke Nov 16 '10 at 16:53
  • 1
    If there's a risk someone will change the URL of your flatpages, there's a risk they'll change whatever "safe" field you go with instead. Which means you don't have a technical problem; you have a process/people problem. Fix that, then do what I suggested. – James Bennett Nov 18 '10 at 04:41
5

{% url %} template tag works with URLconf, whereas flatpages are handling nonexistent urls.

If you really want to reverse flatpages into URLs, my guess is that you have to write your own {% flatpage_url %} tag, which would looks like this:

    @register.simple_tag
    def flatpage_url(self, name):
        return FlatPage.objects.get({param}=name).url

-- where {param} is one of FlatPage model fields.

Also, you can merge {% url %} and {% flatpageurl %} tags together, so that the latter fallbacks to reverse() in case FlatPage is not found (and reverse() is what {% url %} uses).

EDIT:

I don't accept any more upvotes as James Bennet's answer is The One for this question (and I'm ashamed I overlooked such trivial solution) - so please upvote it.
Tomasz Zieliński
  • 16,136
  • 7
  • 59
  • 83
  • Thanks, unfortunately there's no good field in the FlatPage model to use for this, so I'll probably just add a `name` field. Maybe I can override the {% url %} tag somehow with a proxy templatetag that checks flatpage names for matches before handing it off to the django internal url templatetag. – aehlke Nov 12 '10 at 07:55
1

Aren't the proposed solutions basically the same as hardcoding the URL in the template? What's the difference between hardcoding the URL in href="URL" vs. doing it in {% url URL %}?

I think a better solution is found on: How can I get the reverse url for a Django Flatpages template, proposed by bufh.

I think the optimal way of achieving this would be adding an extra 'name' field on the FlatPage model.

Community
  • 1
  • 1
  • Thanks, I'm glad you understood what I now realize was an imprecisely defined question. The end-goal wasn't to be able to use `{% url %}` for flatpages, but to avoid hard-coding their URLs in my templates. The other 2 answers are well-intended and solve another interpretation of my question, but I think yours helps the most. – aehlke Nov 12 '10 at 07:50
  • bufh's solution is a good start, but it still makes you write the URL for a flatpage in two places, and it makes you edit urls.py instead of being able to do it all through the admin. – aehlke Nov 12 '10 at 07:58