1

I am trying to set up django flat pages that would be accessible via a url like /pages/page1.html instead of /pages/page1.

Followed the flatpages docs, and instead of the flatpages middleware used this code in the root urls.py (in the same folder with settings.py):

re_path('pages/.*\.html$', include('django.contrib.flatpages.urls')), 

But this results in a 404 error.

I tried specifying the extension as a non-capturing group:

re_path('pages/.*(?:\.html)$', include('django.contrib.flatpages.urls')),

but I'm still getting a 404.

What would be the correct way to have the .html suffix for flatpages?

ccpizza
  • 28,968
  • 18
  • 162
  • 169

1 Answers1

1

You can't use include that way. The .* part of the match will simply be thrown away, and not passed to the flatpage view.

But you can hook up your flatpages view directly, and capture the url part in a group.

Since the flatpages app requires the url part to have both a leading and trailing slash (/foobar/), you must adapt the flatpage view function with a decorator that replaces the .html extension with a /.

from functools import wraps
import re
from django.contrib.flatpages.views import flatpage

def replace_dot_html_with_slash(f):
    """Decorator that adapt the flatpage view to accept .html urls"""
    @wraps(f)
    def wrapper(request, url):
        # pretend the url has a trailing slash instead of `.html`
        return f(request, re.sub(r'\.html$', '/', url))
    return wrapper

adapted_flatpage = replace_dot_html_with_slash(flatpage)

urlpatterns = [
   ...
   re_path(r'^pages/(.*)$', adapted_flatpage)
]

Alternatively, you could simply write your own flatpage view. It doesn't do anything very complicated.

There are more examples of how to configure flatpages routes in the docs. https://docs.djangoproject.com/en/2.0/ref/contrib/flatpages/#using-the-urlconf

Håken Lid
  • 22,318
  • 9
  • 52
  • 67
  • thanks, but this doesn't seem to be working. Also django appends slash after `.html` turning the URL into `/pages/page1.html/` – ccpizza Jul 21 '18 at 10:16
  • How? Is the url not matched? Is there a redirect? Which url are you trying? Are you using `APPEND_SLASH = True` in your settings, perhaps? This will mess things up if you also want to support `.html` endings. – Håken Lid Jul 21 '18 at 10:21
  • `APPEND_SLASH ` is true by default, even if it's not present in `settings.py` https://docs.djangoproject.com/en/2.0/ref/settings/#append-slash – ccpizza Jul 21 '18 at 10:27
  • You're right. Seems that the flatpages app expects urls to have trailing slashes in any case. So you need to either use a decorator to adapt the view parameters or you must write your own `flatepage()` view function. I've updated my answer with a suggestion for how to write such a decorator. – Håken Lid Jul 21 '18 at 10:43
  • Thank you for your time! Much appreciated! – ccpizza Jul 21 '18 at 11:16