This document details instructions and guidelines for developing site apps to be used with the SODAR Core framework.
It is recommended to read dev_project_app
before this document.
Site apps are basically normal Django apps not hooked to SODAR projects. However, they provide a few nice features to be used in a SODAR-enabled Django site:
- Rules for accessing app data (similar to project apps but without the need for being associated with a project)
- Dynamic inclusion into the site and default templates via plugins
- The ability to show site-wide messages to users
See dev_project_app
.
No specific model implementation is required. However, it is strongly to refer to objects using sodar_uuid
fields instead of the database private key.
Generate a rules.py
file similar to a project app. However, you should not use project predicates in this one. Example:
import rules
# Allow viewing data
rules.add_perm('{APP_NAME}.view_data', rules.is_authenticated)
Create a file plugins.py
in your app's directory. In the file, declare a SiteAppPlugin
class implementing projectroles.plugins.SiteAppPluginPoint
. Within the class, implement member variables and functions as instructed in comments and docstrings.
from projectroles.plugins import SiteAppPluginPoint
from .urls import urlpatterns
class SiteAppPlugin(SiteAppPluginPoint):
"""Plugin for registering a site-wide app"""
name = 'example_site_app'
title = 'Example Site App'
urls = urlpatterns
# ...
The following variables and functions are mandatory:
name
: App name (ideally should correspond to the app package name)title
: Printable app titleurls
: Urlpatterns (usually imported from the app'surls.py
file)icon
: Font Awesome 4.7 icon name (without thefa-*
prefix)entry_point_url_id
: View ID for the app entry pointdescription
: Verbose description of appapp_permission
: Basic permission for viewing app data in project (see above)
Implementing the following is optional:
app_settings
: Implement if project or user specific settings for the app are needed. See the plugin point definition for an example.get_messages()
: Implement if your site app needs to display site-wide messages for users.
In your views, you can still use projectroles mixins which are not related to projects. Especially LoggedInPermissionMixin
is useful to ensure users not allowed to access a view are properly redirected. Example:
from django.views.generic import TemplateView
from projectroles.views import LoggedInPermissionMixin
class ExampleView(LoggedInPermissionMixin, TemplateView):
"""Site app example view"""
permission_required = 'example_site_app.view_data'
template_name = 'example_site_app/example.html'
Note
The entry point URL is not expected to have any URL kwargs in the current implementation. If you intend to use a view which makes use of URL kwargs, you may need to modify it into also accepting a request without any parameters (e.g. displaying default content for the view).
It is recommended for you to extend projectroles/base.html
and put your actual app content within the projectroles
block. Example:
{# Projectroles dependency #}
{% extends 'projectroles/base.html' %}
{% load projectroles_common_tags %}
{% block title %}
Example Site App Page Title
{% endblock title %}
{% block projectroles %}
<div class="container sodar-subtitle-container">
<h2><i class="fa fa-umbrella"></i> Example Site App</h2>
</div>
<div class="container-fluid sodar-page-container">
<div class="alert alert-info">
This is an example and the entry point for <code>example_site_app</code>.
</div>
</div>
{% endblock projectroles %}
The site app provides a way to display certain messages to users. For this, you need to implement get_messages()
in the SiteAppPlugin
class.
If you need to control e.g. which user should see the message or removal of a message after showing, you need to implement relevant logic in the function.
Example:
def get_messages(self, user=None):
"""
Return a list of messages to be shown to users.
:param user: User object (optional)
:return: List of dicts or and empty list if no messages
"""
return [{
'content': 'Message content in here, can contain html',
'color': 'info', # Corresponds to bg-* in Bootstrap
'dismissable': True # False for non-dismissable
'require_auth': True # Only view for authorized users
}]