An action is a task that user can do with portal site, or with some content.
Examples was:
Actions are usually placed in different places in a site layout. The default categories are:
This would be an example rendering:
... <!-- some stuff -->
<ul id="site-actions">
{% get_actions "site" as site_actions %}
{% for action in site_actions %}
<li id="action-{{ action.name }}">
<a href="{{ action.get_url }}">{% trans action.verbose_name %}</a>
</li>
{% endfor %}
</ul>
... <!-- more stuff -->
<ul id="content-actions">
{% get_actions "content" for content as content_actions %}
{% for action in content_actions %}
<li id="action-{{ action.name }}">
<a href="{{ action.get_url }}">{% trans action.verbose_name %}</a>
</li>
{% endfor %}
</ul>
... <!-- more stuff -->
<ul id="user-actions">
{% get_actions "user" as user_actions %}
{% for action in user_actions %}
<li id="action-{{ action.name }}">
<a href="{{ action.get_url }}">{% trans action.verbose_name %}</a>
</li>
{% endfor %}
</ul>
... <!-- now... we place all user actions -->
<ul id="all-user-actions">
{% for user in all_users %}
{% get_actions "user" for user as user_actions %}
{% for action in user_actions %}
<li id="action-{{ action.name }}">
<a href="{{ action.get_url }}">{% trans action.verbose_name %}</a>
</li>
{% endfor %}
{% endfor %}
</ul>
By default, all actions go to action.urls dispatcher, for perform one action. The URL was:
All this URLs will call to views defined in actions.views. These views will call to perform method in action dispatcher, which is a class definition for this action. See next point for more information.
Action perform usually will occurs in some plugin views. For this reason, an action usually will redirect to one view, with right parameters.
This fragment would be an example for action definitions:
Note
Why dont perform action in action definition class itself? Because less coupling principle: you can have some utility views that make some process (maybe in other apps)... This is independent from actions links. Think in a third app reusable view like this:
If you find a view like previous, you can use it as usual.
Actions registry and configuration setup are implemented using registry application (more info in registry documentation). See this example:
from django.conf import settings
from django.utils.translation import ugettext as _
from registry import params
class PDFExport(ContentAction):
# ... more stuff
config_params = [
params.Single(_('HTML to PDF binary'), default='/usr/bin/pdftotext'),
]
class SendPage(SiteAction):
# ... more stuff
config_params = [
params.Single(name='from_email',
verbose_name=_('From email address'),
default=settings.DEFAULT_FROM_EMAIL),
params.List(name='cc_emails',
verbose_name=_('CC email addresses'))
]
This config parameters would be customized in merengue admin interface.
For accessing to configuration inside an app, you can do like this:
>>> from merengue.registry import get_item
>>> plugins.myplugin.actions import SendPage
>>> sendpage_action = get_item(SendPage)
>>> sendpage_action.get_config()['cc_emails'].get_value()
['info@yoursite.com',]
>>> sendpage_action.get_config()['cc_emails'].label
'CC email addresses'
Then, you can have a decoupled actions from a reusable view with this code:
class SendPage(SiteAction):
# ... more stuff
def get_url(self, request):
return HttpResponseRedirect(
reverse("sendpage",
args=[request.get_full_path()],
kwargs={'from_email': self.get_config()['from_email'].get_value(),
'cc_emails': self.get_config()['cc_emails'].get_value(),}),
)
Or inside view:
from merengue.registry import get_item
from plugins.myplugin.actions import SendPage
def sendpage(request, request_path):
sendpage_action = get_item(SendPage)
from_email = sendpage_action.get_config()['from_email'].get_value()
# ... do stuff
Other way is using actions.get_action function:
from merengue.action import get_action
def sendpage(request, path_to_send):
reg_action = get_action('sendpage')
from_email = reg_action.config['from_email']
cc_emails = reg_action.config['cc_emails']
# do your staff ...
Apr 12, 2011