Package: django_url_alias
================django_url_alias================About-----django_url_alias allows you to completely rewrite certain URLs, if you need to. This is done for incoming URL handling(URL resolving) and outgoing URLs (via `{% url … %}` or `resolve`). URL rewrites are modular, so you may have staticrewrites (like a dict in settings) and database based rewrites. You may even mix both types by having multiple URLrewriters.How it works------------django_url_alias provides a special ROOT_URLCONF which intercepts URL resolving on the lowest level. This way it canrewrite all incoming URLs, so other views will be resolved.For outgoing URLs (to clarify: "outgoing" does only mean URLs generated by the system, these URLs still may beinternal) The process is a little bit more complex. django_url_alias provides a special `{% url %}` template tag andits own version of `reverse`. If you use these, everything will just work fine. Sadly there is no sane way to justreplace Django's default behaviour.Usecase-------Although Django's URL handling is really great there may be scanarios it just cannot handle. The flatpage app is oneof the examples URL handling get weird if you need a catchall pattern. As this still works for flatpages you runinto trouble when more then one app needs a similar mechanism (catchall pattern), as only the first one will be handledcorrectly (URL matches, further urlconf entries will be ignored).Other frameworks / CMS / … often use a completely different way to accomplish great URL structure. Instead of havingeasy to read system / internal URLs they just put an abstraction layer above all URL handling. This means yourblog entry (for example) may still have an ugly (internal) URL like "blog/entry/15". Now the new URL layer willtake that ugly URL and allow the user or system to define aliases. An alias could for example rewrite "blog/entry/15"to just "my-trip-to-paris.html". On input URL handling this needs to be reversed, so the requested URL"my-trip-to-paris.html" will resolve to "blog/entry/15" again.django_url_alias allows you to just do exactly this. As it does not provide any predefined rules / mechanisms forrewriting the URL you are free to use whatever rule you want. In theory you could even reuse the good old `SlugField`and regular expressions. Of course you may use a DB based mapping like so many systems use, too. Below you will findan example for flatpages, without the need for an catchall pattern.Usage-----Installation~~~~~~~~~~~~#. Get django_url_alias into your python `sys.path` (`pip install django_url_alias`)#. Replace `settings.ROOT_URLCONF` with `"django_url_alias.urls"`#. Put your old root urlconf into `settings.URL_ALIAS_ROOT_URLCONF`#. Define your URL rewriting modules using `settings.URL_ALIAS_MODULES`(see https://github.com/ddanier/django_url_alias/blob/master/example/example/url_aliases.pyand example below)#. Put `{% load url_alias %}` into your templates, so `{% url %}` gets replaced#. Use `django_url_alias.resolver.reverse` in your Python codeAbout URL_ALIAS_MODULES~~~~~~~~~~~~~~~~~~~~~~~URL_ALIAS_MODULES is just a list of simple classes to rewrite the URLs Django handles or generates... code:: pythonURL_ALIAS_MODULES = ('path.to.module.aliases.ExampleAliasModule',)Each class will be instantiated without any parameters and should provide two methods:* resolve(self, path): Change incoming URLs* reverse(self, path): Change outgoing URLsA simple example may look like this::class ExampleURLAliasModule(object):def resolve(self, path):if path == 'foo/':return 'bar/'def reverse(self, path):if path == 'bar/':return 'foo/'Both methods must return nothing (/None) when no rewrite is done. The defined classes will be called in order forincoming and outgoing URLs. The first module which returns a replacement URL will shortcut further processing, thuswill define the final URL.Flatpage example----------------The flatpages app is in core, so it just gives an nice example. We don't want to use the catchall pattern any more.For this example to work you will need to go through installation first.First of all we need to define our internal URL structure. This will not be visible to your visitors, althoughthe internal URLs are still accessible.urls.py:: pythonurlpatterns = patterns('',url(r'^flatpage/(?P<pk>[0-9]+)/$', 'example.views.flatpage', name='flatpage'),)Then the rewrite needs to be done, so `flatpage.url` will be used to present the external URL structure, whilethe internal ID-based URL gets used internally.URL Rewrite module:: pythonfrom django.contrib.flatpages.models import FlatPageimport reclass FlatpagesURLAliasModule(object):FLATPAGE_RE = re.compile('^/flatpage/(?P<pk>[0-9]+)/$')def resolve(self, path):path = '/' + path  # we need a trailing slash for flatpagestry:flatpage = FlatPage.objects.get(url=path)return '/flatpage/%d/' % flatpage.pkexcept FlatPage.DoesNotExist:pass  # just return nothingdef reverse(self, path):match = self.FLATPAGE_RE.match(path)if match:try:flatpage = FlatPage.objects.get(pk=match.group('pk'))return flatpage.urlexcept FlatPage.DoesNotExist:pass  # just return nothing*Note:* This is just an example. In an production envirionment you would need to a) check the sites relation and moreimportantly b) use some caching. The above code is very inefficient and should NEVER BE USED IN A PRODUCTIONENVIRIONMENT.Advantages of implementation----------------------------* `request` objects stay clean. You could rewrite URLs using middleware classes which fiddle with `request.path_info`,but this way you will loose information (or even worse: rewrite information).* Least obtrusive way of implementation.Notes-----* You should define canonical tags, so internal URLs will not get indexed by search engines.