django-postman / docs / features.rst

Features

Direct write to

In the pages of your site, you can put links containing the recipient name(s).

Example:

<a href="{% url 'postman_write' username %}">write to {{ username }}</a>

Separate multiple usernames with a : character.

Example:

<a href="{% url 'postman_write' 'adm1:adm2:adm3' %}">write to admins</a>

Prefilled fields

You may prefill the contents of some fields by providing a query string in the link.

Example:

<a href="{% url 'postman_write' %}?subject=details request&body=give me details about ...">
ask for details
</a>

Recipients Min/Max

If you need to constraint the maximum number of recipients in the forms, you can pass the optional max parameter to the view. There is no parameter for a minimum number, but you can code a custom form and pass a min parameter to the recipient field (see Advanced Usage below for details).

Views supporting the parameter are: write, reply.

But this parameter does not apply to the default AnonymousWriteForm for visitors: The maximum is enforced to 1 (see Advanced Usage below for knowing how), in order to keep the features available to anonymous users to a strict minimum.

Example:

urlpatterns = patterns('postman.views',
    # ...
    url(r'^write/(?:(?P<recipients>[\w.@+-:]+)/)?$', 'write',
        {'max': 3}, name='postman_write'),
    # ...
)

Advanced usage

If you define your own custom form, you may specify a min parameter and a max parameter to the recipients field.

For example:

from postman.forms import WriteForm
class MyWriteForm(WriteForm):
    recipients = CommaSeparatedUserField(label="Recipients", min=2, max=5)

If you do not want the fixed max parameter of the recipients field in your custom form, to be superseded by the parameter passed to the view, set the can_overwrite_limits form attribute to False.

For example:

class MyThreeAnonymousWriteForm(MyBaseAnonymousWriteForm):
    can_overwrite_limits = False
    recipients = CommaSeparatedUserField(label="Recipients", max=3)

See also:

User filter

If there are some situations where a user should not be a recipient, you can write a filter and pass it to the view.

Views supporting a user filter are: write, reply.

Example:

def my_user_filter(user):
    if user.get_profile().is_absent:
        return "is away"
    return None

urlpatterns = patterns('postman.views',
    # ...
    url(r'^write/(?:(?P<recipients>[\w.@+-:]+)/)?$', 'write',
        {'user_filter': my_user_filter}, name='postman_write'),
    # ...
)

The filter will be called for each recipient, for validation.

Input:

  • user: a User instance, as the recipient of the message

Output:

If the recipient is allowed, just return None.

To forbid the message, use one of these means:

  • return False or '', if you do not want to give a reason for the refusal. The error message will be: "Some usernames are rejected: foo, bar."
  • return a string, as a reason for the refusal. The error message will be: "Some usernames are rejected: foo (reason), bar (reason)."
  • raise a ValidationError with an error message to your liking.

Advanced usage

If you define your own custom form, you may specify a user filter inside.

For example:

def my_user_filter(user):
    # ...
    return None

from postman.forms import WriteForm
class MyWriteForm(WriteForm):
    recipients = CommaSeparatedUserField(label="Recipients", user_filter=my_user_filter)

Exchange filter

If there are some situations where an exchange should not take place, you can write a filter and pass it to the view. Typical usages would be: blacklists, users that do not want solicitation from visitors.

Views supporting an exchange filter are: write, reply.

An example, with the django-relationships application:

def my_exchange_filter(sender, recipient, recipients_list):
    if recipient.relationships.exists(sender, RelationshipStatus.objects.blocking()):
        return "has blacklisted you"
    return None

urlpatterns = patterns('postman.views',
    # ...
    url(r'^write/(?:(?P<recipients>[\w.@+-:]+)/)?$', 'write',
        {'exchange_filter': my_exchange_filter}, name='postman_write'),
    # ...
)

The filter will be called for each couple, to validate that the exchange is possible.

Inputs:

  • sender: a User instance, as the sender of the message, or None if the writer is not authenticated
  • recipient: a User instance, as the recipient of the message
  • recipients_list: the full list of recipients. Provided as a convenient additional element of decision.

Output:

If the exchange is allowed, just return None.

To forbid the exchange, use one of these means:

  • return False or '', if you do not want to give a reason for the refusal. The error message will be: "Writing to some users is not possible: foo, bar."
  • return a string, as a reason for the refusal. The error message will be: "Writing to some users is not possible: foo (reason), bar (reason)."
  • raise a ValidationError with an error message to your liking.

Advanced usage

If you define your own custom form, you may specify an exchange filter inside.

For example:

def my_exchange_filter(sender, recipient, recipients_list):
    # ...
    return None

from postman.forms import WriteForm
class MyWriteForm(WriteForm):
    exchange_filter = staticmethod(my_exchange_filter)

Auto-complete field

An auto-complete functionality may be useful on the recipients field.

To activate the option, set at least the arg_default key in the POSTMAN_AUTOCOMPLETER_APP dictionary. If the default ajax_select application is used, define a matching entry in the AJAX_LOOKUP_CHANNELS dictionary.

Example:

AJAX_LOOKUP_CHANNELS = {
    'postman_users': dict(model='auth.user', search_field='username'),
}
POSTMAN_AUTOCOMPLETER_APP = {
    'arg_default': 'postman_users',
}

In case of version 1.1.4/5 of django-ajax-selects:

Support for multiple recipients is not turned on by default by django-ajax-selects. To allow this capability, you have to pass the option multiple: true to jquery-plugin-autocomplete.

Make your own templates, based on these two files, given as implementation examples:

These examples include a correction necessary for the support of the 'multiple' option.

In case of version 1.2.x of django-ajax-selects:

Refer to the installation guide of this application, in particular the use of AJAX_SELECT_BOOTSTRAP and AJAX_SELECT_INLINES. Support for multiple recipients is not as simple as an option: see the examples in the jQuery UI demos.
The directory postman/templates/ doesn't currently provide any examples for this version.

Customization

You may attach a specific channel, different from the default one, to a particular view.

Views supporting an auto-complete parameter are: write, reply.

For the write view, the parameter is named autocomplete_channels (note the plural). It supports two variations:

  • a 2-tuple of channels names: the first one for authenticated users, the second for visitors. Specify None if you let the default channel name for one of the tuple parts.
  • a single channel name: the same for users and visitors

For the reply view, the parameter is named autocomplete_channel (note the singular). The value is the channel name.

Example:

urlpatterns = patterns('postman.views',
    # ...
    url(r'^write/(?:(?P<recipients>[\w.@+-:]+)/)?$', 'write',
        {'autocomplete_channels': (None,'anonymous_ac')}, name='postman_write'),
    url(r'^reply/(?P<message_id>[\d]+)/$', 'reply',
        {'autocomplete_channel': 'reply_ac'}, name='postman_reply'),
    # ...
)

Example:

urlpatterns = patterns('postman.views',
    # ...
    url(r'^write/(?:(?P<recipients>[\w.@+-:]+)/)?$', 'write',
        {'autocomplete_channels': 'write_ac'}, name='postman_write'),
    # ...
)

Advanced usage

If you define your own custom form, you may specify an autocomplete channel inside.

For example:

from postman.forms import WriteForm
class MyWriteForm(WriteForm):
    recipients = CommaSeparatedUserField(label="Recipients", channel='my_channel')
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.