diff --git a/docs/_themes b/docs/_themes
index 09eeca52..91eee537 160000
--- a/docs/_themes
+++ b/docs/_themes
@@ -1 +1 @@
-Subproject commit 09eeca526b2b5675cc29f45917f5d0f795395035
+Subproject commit 91eee537e91594f752224a5847719f6d4fb38c2d
diff --git a/docs/conf.py b/docs/conf.py
index f9f7867e..18e8f309 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -140,7 +140,7 @@ html_sidebars = {
#html_additional_pages = {}
# If false, no module index is generated.
-#html_use_modindex = True
+html_use_modindex = False
# If false, no index is generated.
#html_use_index = True
@@ -152,7 +152,7 @@ html_sidebars = {
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
+html_show_sphinx = False
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
diff --git a/docs/patterns/index.rst b/docs/patterns/index.rst
index 61162372..fcd482d7 100644
--- a/docs/patterns/index.rst
+++ b/docs/patterns/index.rst
@@ -28,3 +28,4 @@ Snippet Archives `_.
flashing
jquery
errorpages
+ lazyloading
diff --git a/docs/patterns/lazyloading.rst b/docs/patterns/lazyloading.rst
new file mode 100644
index 00000000..2c331ca9
--- /dev/null
+++ b/docs/patterns/lazyloading.rst
@@ -0,0 +1,104 @@
+Lazily Loading Views
+====================
+
+Flask is usually used with the decorators. Decorators are simple and you
+have the URL right next to the function that is called for that specific
+URL. However there is a downside to this approach: it means all your code
+that uses decorators has to be imported upfront or Flask will never
+actually find your function.
+
+This can be a problem if your application has to import quick. It might
+have to do that on systems like Google's AppEngine or other systems. So
+if you suddenly notice that your application outgrows this approach you
+can fall back to a centralized URL mapping.
+
+The system that enables having a central URL map is the
+:meth:`~flask.Flask.add_url_rule` function. Instead of using decorators,
+you have a file that sets up the application with all URLs.
+
+Converting to Centralized URL Map
+---------------------------------
+
+Imagine the current application looks somewhat like this::
+
+ from flask import Flask
+ app = Flask(__name__)
+
+ @app.route('/')
+ def index():
+ pass
+
+ @app.route('/user/')
+ def user(username):
+ pass
+
+Then the centralized approach you would have one file with the views
+(`views.py`) but without any decorator::
+
+ def index():
+ pass
+
+ def user(username):
+ pass
+
+And then a file that sets up an application which maps the functions to
+URLs::
+
+ from flask import Flask
+ from yourapplication import views
+ app = Flask(__name__)
+ app.add_url_rule('/', view_func=views.index)
+ app.add_url_rule('/user/', view_func=views.user)
+
+Loading Late
+------------
+
+So far we only split up the views and the routing, but the module is still
+loaded upfront. The trick to actually load the view function as needed.
+This can be accomplished with a helper class that behaves just like a
+function but internally imports the real function on first use::
+
+ from werkzeug import import_string, cached_property
+
+ class LazyView(object):
+
+ def __init__(self, import_name):
+ self.__module__, self.__name__ = import_name.rsplit('.', 1)
+ self.import_name = import_name
+
+ @cached_property
+ def view(self):
+ return import_string(self.import_name)
+
+ def __call__(self, *args, **kwargs):
+ return self.view(*args, **kwargs)
+
+What's important here is is that `__module__` and `__name__` are properly
+set. This is used by Flask internally to figure out how to do name the
+URL rules in case you don't provide a name for the rule yourself.
+
+Then you can define your central place to combine the views like this::
+
+ from flask import Flask
+ from yourapplication.helpers import LazyView
+ app = Flask(__name__)
+ app.add_url_rule('/',
+ view_func=LazyView('yourapplication.views.index'))
+ app.add_url_rule('/user/',
+ view_func=LazyView('yourapplication.views.user'))
+
+You can further optimize this in terms of amount of keystrokes needed to
+write this by having a function that calls into
+:meth:`~flask.Flask.add_url_rule` by prefixing a string with the project
+name and a dot, and by wrapping `view_func` in a `LazyView` as needed::
+
+ def url(url_rule, import_name, **options):
+ view = LazyView('yourapplication.' + import_name)
+ app.add_url_rule(url_rule, view_func=view, **options)
+
+ url('/', 'views.index')
+ url('/user/', 'views.user')
+
+One thing to keep in mind is that before and after request handlers have
+to be in a file that is imported upfront to work propery on the first
+request. The same goes for any kind of remaining decorator.
diff --git a/docs/tutorial/css.rst b/docs/tutorial/css.rst
index c2a6ba5b..76265a65 100644
--- a/docs/tutorial/css.rst
+++ b/docs/tutorial/css.rst
@@ -1,3 +1,5 @@
+.. _tutorial-css:
+
Step 7: Adding Style
====================
@@ -25,3 +27,5 @@ folder we created before:
.flash { background: #CEE5F5; padding: 0.5em;
border: 1px solid #AACBE2; }
.error { background: #F0D6D6; padding: 0.5em; }
+
+Continue with :ref:`tutorial-testing`.
diff --git a/docs/tutorial/dbcon.rst b/docs/tutorial/dbcon.rst
index 9741dabb..50aba04d 100644
--- a/docs/tutorial/dbcon.rst
+++ b/docs/tutorial/dbcon.rst
@@ -1,3 +1,5 @@
+.. _tutorial-dbcon:
+
Step 4: Request Database Connections
------------------------------------
@@ -31,3 +33,5 @@ request only and is available from within each function. Never store such
things on other objects because this would not work with threaded
environments. That special :data:`~flask.g` object does some magic behind
the scenes to ensure it does the right thing.
+
+Continue to :ref:`tutorial-views`.
diff --git a/docs/tutorial/dbinit.rst b/docs/tutorial/dbinit.rst
index 0dc87d58..602b999d 100644
--- a/docs/tutorial/dbinit.rst
+++ b/docs/tutorial/dbinit.rst
@@ -1,3 +1,5 @@
+.. _tutorial-dbinit:
+
Step 3: Creating The Database
=============================
@@ -61,3 +63,5 @@ importing and calling that function::
If you get an exception later that a table cannot be found check that
you did call the `init_db` function and that your table names are
correct (singular vs. plural for example).
+
+Continue with :ref:`tutorial-dbcon`
diff --git a/docs/tutorial/folders.rst b/docs/tutorial/folders.rst
index 80697a94..5e685c7e 100644
--- a/docs/tutorial/folders.rst
+++ b/docs/tutorial/folders.rst
@@ -1,3 +1,5 @@
+.. _tutorial-folders:
+
Step 0: Creating The Folders
============================
@@ -16,4 +18,6 @@ This is the place where css and javascript files go. Inside the
`templates` folder Flask will look for `Jinja2`_ templates. Drop all the
templates there.
+Continue with :ref:`tutorial-schema`.
+
.. _Jinja2: http://jinja.pocoo.org/2/
diff --git a/docs/tutorial/introduction.rst b/docs/tutorial/introduction.rst
index 04396a9d..ff7cdcab 100644
--- a/docs/tutorial/introduction.rst
+++ b/docs/tutorial/introduction.rst
@@ -1,3 +1,5 @@
+.. _tutorial-introduction:
+
Introducing Flaskr
==================
@@ -26,4 +28,6 @@ Here a screenshot from the final application:
:class: screenshot
:alt: screenshot of the final application
+Continue with :ref:`tutorial-folders`.
+
.. _SQLAlchemy: http://www.sqlalchemy.org/
diff --git a/docs/tutorial/schema.rst b/docs/tutorial/schema.rst
index ed329539..c078667e 100644
--- a/docs/tutorial/schema.rst
+++ b/docs/tutorial/schema.rst
@@ -1,3 +1,5 @@
+.. _tutorial-schema:
+
Step 1: Database Schema
=======================
@@ -19,3 +21,5 @@ This schema consists of a single table called `entries` and each row in
this table has an `id`, a `title` and a `text`. The `id` is an
automatically incrementing integer and a primary key, the other two are
strings that must not be null.
+
+Continue with :ref:`tutorial-setup`.
diff --git a/docs/tutorial/setup.rst b/docs/tutorial/setup.rst
index 1214c22f..f9a0b302 100644
--- a/docs/tutorial/setup.rst
+++ b/docs/tutorial/setup.rst
@@ -1,3 +1,5 @@
+.. _tutorial-setup:
+
Step 2: Application Setup Code
==============================
@@ -62,3 +64,5 @@ focus on that a little later. First we should get the database working.
Want your server to be publically available? Check out the
:ref:`externally visible server ` section for more
information.
+
+Continue with :ref:`tutorial-dbinit`.
diff --git a/docs/tutorial/templates.rst b/docs/tutorial/templates.rst
index 66b1dec6..5ec5584d 100644
--- a/docs/tutorial/templates.rst
+++ b/docs/tutorial/templates.rst
@@ -1,3 +1,5 @@
+.. _tutorial-templates:
+
Step 6: The Templates
=====================
@@ -105,3 +107,5 @@ the user to login:
{% endblock %}
+
+Continue with :ref:`tutorial-css`.
diff --git a/docs/tutorial/testing.rst b/docs/tutorial/testing.rst
index c3075e3a..051e915a 100644
--- a/docs/tutorial/testing.rst
+++ b/docs/tutorial/testing.rst
@@ -1,3 +1,5 @@
+.. _tutorial-testing:
+
Bonus: Testing the Application
===============================
diff --git a/docs/tutorial/views.rst b/docs/tutorial/views.rst
index 29be65fa..03c7709b 100644
--- a/docs/tutorial/views.rst
+++ b/docs/tutorial/views.rst
@@ -1,3 +1,5 @@
+.. _tutorial-views:
+
Step 5: The View Functions
==========================
@@ -85,3 +87,5 @@ that case if the user was logged in.
session.pop('logged_in', None)
flash('You were logged out')
return redirect(url_for('show_entries'))
+
+Continue with :ref:`tutorial-templates`.
diff --git a/examples/minitwit/minitwit.py b/examples/minitwit/minitwit.py
index 07ffe4c7..4e01cecb 100644
--- a/examples/minitwit/minitwit.py
+++ b/examples/minitwit/minitwit.py
@@ -127,6 +127,7 @@ def user_timeline(username):
follower.who_id = ? and follower.whom_id = ?''',
[session['user_id'], profile_user['user_id']],
one=True) is not None
+ broken_just_for_djangocon
return render_template('timeline.html', messages=query_db('''
select message.*, user.* from message, user where
user.user_id = message.author_id and user.user_id = ?