Author: | Keryn Knight |
---|---|
Version: | 0.2.0 |
Release | Status |
---|---|
stable (0.2.0) | |
master |
Sections
intercooler_helpers
is a small reusable app for Django which provides a
few improvements for working with Intercooler.js.
It provides a middleware which extracts relevant Intercooler.js data from the
querystring, and attaches it to the request as a separate QueryDict
(ie: it
behaves like request.POST
or request.GET
)
It also provides a small middleware for changing request method based on either the
query string (_method=PUT
) or a request header(X-HTTP-Method-Override: PUT
)
Between them, they should capture all the incoming Intercooler.js data on which the server may act.
This application depends on django-intercoolerjs which provides a copy of Intercooler.js bundled up for use with the standard Django staticfiles application.
You can grab 0.2.0
from PyPI like so:
pip install django-intercooler-helpers==0.2.0
Or you can grab it from GitHub like this:
pip install -e git+https://github.com/kezabelle/django-intercoolerjs-helpers.git#egg=django-intercoolerjs-helpers
You need to add intercooler_helpers.middleware.IntercoolerData
to your
MIDDLEWARE_CLASSES
(or MIDDLEWARE
on Django 1.10+).
You may optionally want to add intercooler_helpers.middleware.HttpMethodOverride
as well, if you don't already have a method by which to fake the HTTP Method change.
If you're using <meta name="intercoolerjs:use-actual-http-method" content="true"/>
then you don't need HttpMethodOverride
at all.
To install all the middleware, you want something like:
# MIDDLEWARE = ... for newer Django MIDDLEWARE_CLASSES = ( # ... 'intercooler_helpers.middleware.HttpMethodOverride', 'intercooler_helpers.middleware.IntercoolerData', 'intercooler_helpers.middleware.IntercoolerRedirector', # ... )
HttpMethodOverride
and IntercoolerData
ought to be near the top of the iterable, as they both make use of process_request(request)
.
IntercoolerRedirector
ought to be near the bottom, as it operates on process_response(request, response)
and you probably want to convert the response to a client-side redirect at the earliest opportunity.
A brief overview of the public API provided so far:
For fully correct detection of Intercooler.js requests, you can call
request.is_intercooler()
.
Behind the scenes, it uses request.maybe_intercooler()
to
detect whether ic-request
was present, indicating it may have been a
valid Intercooler.js request, and also checks request.is_ajax()
To parse the Intercooler-related data out of the query-string, you can use
request.intercooler_data
(not a method!) which is a QueryDict
and should
behave exactly like request.GET
- It pulls all of the ic-*
keys out
of request.GET
and puts them in a separate data structure, leaving
your request.GET
cleaned of extraenous data.
request.intercooler_data
is a lazy data structure, like request.user
,
so will not modify request.GET
until access is attempted.
The following properties exist, mapping back to the keys mentioned in the Intercooler.js Reference document
request.intercooler_data.url
returns anamedtuple
containing- the
ic-current-url
(converted viaurlparse
) orNone
- A Django
ResolverMatch
pointing to the view which made the request (based onic-current-url
) orNone
- the
request.intercooler_data.element
returns anamedtuple
containingic-element-name
orNone
ic-element-id
orNone
request.intercooler_data.id
- the
ic-id
which made the request. an ever-incrementing integer.
- the
request.intercooler_data.request
- a boolean indicating that it was an Intercooler.js request. Should always
be true if
request.is_intercooler()
said so.
- a boolean indicating that it was an Intercooler.js request. Should always
be true if
request.intercooler_data.target_id
ic-target-id
orNone
request.intercooler_data.trigger
returns anamedtuple
containingic-trigger-name
orNone
ic-trigger-id
orNone
request.intercooler_data.prompt_value
- If no
ic-prompt-name
was given and a prompt was used, this will contain the user's response. Appears to be undocumented?
- If no
request.changed_method
is a boolean indicating that the request was toggled from being aPOST
to something else (one ofGET
,HEAD
,POST
,PUT
,PATCH
,DELETE
,OPTIONS
... though why you'd want toPOST
and have it act as aGET
is beyond me. But that's your choice)request.original_method
if either_method=X
orX-HTTP-Method-Override: X
caused the request to change method, then this will contain the original request. It should always bePOST
request.method
will reflect the desired HTTP method, rather than the one originally used (POST
)
If a redirect status code is given (> 300, < 400), and the request originated from Intercooler.js (assumes IntercoolerData
is installed so that request.is_intercooler()
may be called), remove the Location
header from the response, and create a new HttpResponse
with all the other headers, and also the X-IC-Redirect
header to indicate to Intercooler.js that it needs to do a client side-redirect.
The tests are run against Django 1.8 through 1.10, and Python 2.7, 3.3, 3.4 and 3.5.
If you have a cloned copy, you can do:
python setup.py test
If you have tox, you can just do:
tox
A barebones demo is provided. It assumes you're using something like virtualenv and virtualenvwrapper but you can probably figure it out otherwise:
mktmpenv --python=`which python3` pip install -e git+https://github.com/kezabelle/django-intercooler-helpers.git#egg=django-intercooler-helpers
Then probably:
cd src/django-intercooler-helpers python demo_project.py runserver
It shows off a few of the same demos that the Intercooler.js website does.
Please do!
The project is hosted on GitHub in the kezabelle/django-intercooler-helpers repository.
Bug reports and feature requests can be filed on the repository's issue tracker.
If something can be discussed in 140 character chunks, there's also my Twitter account.
TODO.
It's FreeBSD. There's should be a LICENSE
file in the root of the repository, and in any archives.