Login

Smart append slash middleware

Author:
akaihola
Posted:
February 15, 2008
Language:
Python
Version:
.96
Score:
1 (after 1 ratings)

This middleware replaces the behavior of the APPEND_SLASH setting in the CommonMiddleware. Please set APPEND_SLASH = False and SMART_APPEND_SLASH = True if you are going to use this middleware.

In your URL patterns, omit the trailing slash for URLs you want accessible without the slash. Include the slash for those URLs you wish to be automatically redirected from an URL with the slash missing.

If a URL pattern exists both with and without a slash, they are treated as two distinct URLs and no redirection is done.

Example

urlpatterns = patterns('some_site.some_app.views',
    (r'^test/no_append$','test_no_append'),
    (r'^test/append/$','test_append'),
    (r'^test/distinct_url$', 'view_one'),
    (r'^test/distinct_url/$', 'view_two'), )

Behavior of URLs against the above patterns with SMART_APPEND_SLASH enabled:

http://some_site/test/no_append     → test_no_append()
http://some_site/test/no_append/    → 404
http://some_site/test/append        → http://some_site/test/append/
http://some_site/test/append/       → test_append()
http://some_site/test/distinct_url  → view_one()
http://some_site/test/distinct_url/ → view_two()

This module is also available in our SVN repository.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from django.conf import settings
from django import http
from django.core.urlresolvers import resolve

class SmartAppendSlashMiddleware(object):
    """
    "SmartAppendSlash" middleware for taking care of URL rewriting.

    This middleware appends a missing slash, if:
    * the SMART_APPEND_SLASH setting is True
    * the URL without the slash does not exist
    * the URL with an appended slash does exist.
    Otherwise it won't touch the URL.
    """

    def process_request(self, request):
        """
        Rewrite the URL based on settings.SMART_APPEND_SLASH
        """

        # Check for a redirect based on settings.SMART_APPEND_SLASH
        host = http.get_host(request)
        old_url = [host, request.path]
        new_url = old_url[:]
        # Append a slash if SMART_APPEND_SLASH is set and the resulting URL
        # resolves.
        if settings.SMART_APPEND_SLASH and (not old_url[1].endswith('/')) and not _resolves(old_url[1]) and _resolves(old_url[1] + '/'):
            new_url[1] = new_url[1] + '/'
            if settings.DEBUG and request.method == 'POST':
                raise RuntimeError, "You called this URL via POST, but the URL doesn't end in a slash and you have SMART_APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to %s%s (note the trailing slash), or set SMART_APPEND_SLASH=False in your Django settings." % (new_url[0], new_url[1])
        if new_url != old_url:
            # Redirect
            if new_url[0]:
                newurl = "%s://%s%s" % (request.is_secure() and 'https' or 'http', new_url[0], new_url[1])
            else:
                newurl = new_url[1]
            if request.GET:
                newurl += '?' + request.GET.urlencode()
            return http.HttpResponsePermanentRedirect(newurl)

        return None

def _resolves(url):
    try:
        resolve(url)
        return True
    except http.Http404:
        return False

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 3 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

Please login first before commenting.