rtfd/readthedocs.org — pull request #544 by toffer (2013-11-17 23:43:56+00:00)
Title: Refactor URL Routing for Docs

I'm gearing up to tackle Issue #293 (adding the ability to serve pages at the base domain, rather than redirecting to `///`), but before I start on that, I decided to refactor how URL routing is handled for serving docs. My goal was to make the redirect logic easier to follow, and to consolidate the rewriting logic in one place.

What URLs Should Be Redirected
------------------------------
The main challenge of URL routing in Readthedocs is handling redirects correctly. Both in the interest of redirecting older URLs that are now obsolete, and in the interest of handling "logical-looking" URLs (leaving out the lang_slug or version_slug shouldn't result in a 404), the following redirects should be handled:

/docs/pip/ -> /docs/pip/en/latest/
/docs/pip/en/ -> /docs/pip/en/latest/
/docs/pip/latest/ -> /docs/pip/en/latest/

In addition, URLs with the 'page directory' should be redirected as well:

/docs/pip/page/installing.html -> /docs/pip/en/latest/installing.html

The examples above are given for RTD URLs (for example, http://readthedocs.org/docs/pip/), but the same redirects should also work for subdomain URLs (http://pip.readthedocs.org/).

How It Works Now
----------------
Previously, the redirect logic was handled in several places in the codebase.

In `core.views`, `serve_docs()` handled RTD URLs, while `subdomain_handler()` handled subdomain URLs. Redirects were handled by a series of if/else statements to check for missing URL parameters, add the appropriate ones, and redirect.

In addition, URL parameters were modified in the URLconfs (`urls.py` and `subdomain_urls.py`).

What Has Been Refactored
------------------------
1. Now, `serve_docs()` is strictly concerned with serving docs. No redirects are done within `serve_docs()`. It handles both RTD and subdomain URLs.
2. Since `serve_docs()` handles all the serving, `subdomain_handler()` has been removed.
3. I created several `redirect_*` views to handle redirects.
4. URLs that need to be redirected are dispatched to the appropriate `redirect_*` view. (Previously, they were dispatched to `serve_docs()` or `subdomain_handler()`.)
5. No URL parameters are modified in URLconfs.

Questions
---------
Does this approach make sense? Does this seem like a helpful approach to making the redirect logic clearer?

I've added additional tests to test_redirects.py (everything passes!), but I'm concerned about making a big change to such a core part of the site. Are there some additional things I should test?

For example, the current `subdomain_handler()` has a section that handles aliases. From the RTD Hack Day, I got the impression that you don't use aliases for anything any more, so I don't do anything with aliases. If I got that wrong, let me know what the best way to test it is.

In addition, I don't have any testing around projects and sub-projects. Suggestions for how to test that would be helpful.

Lastly, I'm looking for any suggestions/comments/feedback. Please let me know what can be improved...or, if you think I'm on the wrong track entirely!