Skip to content

Commit

Permalink
Follow-up to issue #39: created a demo view and added documentation t…
Browse files Browse the repository at this point in the history
…o the README.
  • Loading branch information
stasm committed Mar 22, 2011
1 parent 0f456b0 commit 7819172
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 3 deletions.
113 changes: 110 additions & 3 deletions README.rst
Expand Up @@ -17,7 +17,11 @@ Installation
Integration
===========

In order to enable *todo* for your app, follow these steps:
In order to enable *todo* for your app, follow the steps below.


Models
------

#. Add a one-to-one relation to your app's project model definition pointing to
``todo.models.Project``::
Expand Down Expand Up @@ -80,8 +84,15 @@ In order to enable *todo* for your app, follow these steps:

The label is always truncated to the first 50 characters.

#. Create or modify views where you want to use the ``todo`` snippets. You must
have at least two views:

Tracker and Task Views
----------------------

The views display data about trackers and/or tasks. ``todo`` provides snippets
that you can configure in your existing views and include in your templates.

#. Create or modify views in which you want to use the ``todo`` snippets. You
must have at least two views:

* a single task view,
* a single tracker view.
Expand Down Expand Up @@ -165,3 +176,99 @@ In order to enable *todo* for your app, follow these steps:
background: url({% url static path="loadingAnimation.gif" %}) no-repeat 0 13px;
}
</style>


Create-New Interface
--------------------

This is a special view which you can use to configure how new trackers and
tasks are created. By default, ``todo`` provides a simple version of this
interface at ``/todo/new``. It is very straightforward: it shows all the
projects (from all the apps using ``todo``) and doesn't let you redirect to the
newly created todos after a successul POST request.

It is possible to customize this interface on a per-app basis, thus allowing to
address the limitations mentioned above. Follow the steps below to create
a custom ersion of the create-new interface for you app.

#. Add a create-new view to your urls.py::

urlpatterns += patterns('yourapp.views',
(r'^\/new-todo$', 'new_todo'),
)

#. Create the view specified in urls.py (``yourapp.view.new_todo`` in the
example above)::

from todo.views import new as create_new_wizard

def new_todo(request):
def locale_filter(appver):
"""Get a QuerySet of Locales related to the project (appver).

This function will be run after the user selects a project to
create new todos for in the create-new interface. It allows you to
narrow the list of available locales to those that actually make
sense for the project chosen by the user. The returned locales
will be displayed in a select box in the form wizard.

"""
return Locale.objects.filter(appvers=appver)

appvers = YourProject.objects.filter(is_archived=False)

config = {
'projects': appvers,
'locale_filter': locale_filter,
'get_template': lambda step: 'yourapp/new_%d.html' % step,
'task_view': 'yourapp.views.task',
'tracker_view': 'yourapp.views.tracker',
'thankyou_view': 'yourapp.views.created',
}
return create_new_wizard(request, **config)

You can control the most important aspects of the wizard's behavior with the
``config`` dict. It accepts the following keys and values:

- `projects`: a QuerySet with the project-like objects in your app. If
`None` (or omitted), all `todo.Project` objects will be shown, possibly
showing objects from outside of your app as well (if your app is not the
only one using ``todo``).

- `locale_filter`: a function accepting a single argument, `project`, which
is an element from the QuerySet passed in `projects` above. The function
should return a QuerySet of `Locales` related to the passed `project`. If
`None` (or omitted), all locale will be displayed regardless of the
projects chosen in the first step.

- `get_template`: a function accepting a single argument, `step`, which is
a zero-based integer index of the step of wizard. It should return
a string which is a name of the template to use for the given step. If
`None` (or omitted), the following default will be used::

'todo/new_%d.html' % step

- `task_view`: a string name of the view responsible for showing a single
task in your application. It will be used for redirecting the user to the
newly created task. If `None` (or omitted), the generic 'thank you' view
will be used, which will not include any link to the newly created task
but can be used to inform the user that the request has been processed
successfully. See `thankyou_view` below.

- `tracker_view`: a string name of the view responsible for showing a single
tracker in your application. It will be used for redirecting the user to
the newly created tracker. If `None` (or omitted), the generic 'thank
you' view will be used, which will not include any link to the newly
created tracker but can be used to inform the user that the request has
been processed successfully. See `thankyou_view` below.

- `thankyou_view`: a string name of the generic 'thank you'/'success' view
that will be displayed in absence of the `task_view` or `tracker_view`.
If `None` (or omitted), the default provided by ``todo`` will be used,
i.e. `todo.views.created`.

#. Grant the following permissions to users/groups that should be able to
create new trackers and tasks::

todo.create_tracker
todo.create_task
3 changes: 3 additions & 0 deletions todo/urls.py
Expand Up @@ -53,6 +53,8 @@
'todo-api-update-tracker'),
)

# the generic create-new wizard views; apps implementing todo should provide
# their own views instead of using these.
new_patterns = patterns('',
(r'^$', 'todo.views.new'),
(r'^created$', 'todo.views.created'),
Expand All @@ -65,6 +67,7 @@
(r'^showcase$', 'showcase'),
(r'^tracker/(?P<tracker_id>\d+)$', 'tracker'),
(r'^trackers$', 'trackers'),
(r'^new-todo$', 'new_todo'),
)

urlpatterns = patterns('',
Expand Down
33 changes: 33 additions & 0 deletions todo/views/demo.py
Expand Up @@ -39,6 +39,7 @@
from django.utils.safestring import mark_safe

from todo.views import snippets
from todo.views import new as create_new_wizard

def task(request, task_id):
from todo.models import Task
Expand Down Expand Up @@ -88,3 +89,35 @@ def trackers(request):
tracker_view='todo.views.demo.tracker')
return render_to_response('todo/demo_tree.html',
{'tree': tree,})

def new_todo(request):
from todo.models import Project
from life.models import Locale
def locale_filter(project):
"""Get a QuerySet of Locales related to the project.
This function will be run after the user selects a project to
create new todos for in the create-new interface. It allows you to
narrow the list of available locales to those that actually make
sense for the project chosen by the user. The returned locales
will be displayed in a select box in the form wizard.
"""
# a silly example: display only Locales whose code starts with the
# second letter of the project label
return Locale.objects.filter(code__istartswith=project.label[1])

# a silly example: display only projects whose label starts with 'f'
projects = Project.objects.filter(label__istartswith='f')

config = {
'projects': projects,
'locale_filter': locale_filter,
# same as the default
'get_template': lambda step: 'todo/new_%d.html' % step,
'task_view': 'todo.views.demo.task',
'tracker_view': 'todo.views.demo.tracker',
# same as the default
'thankyou_view': 'todo.views.created',
}
return create_new_wizard(request, **config)

0 comments on commit 7819172

Please sign in to comment.