diff --git a/openslides/agenda/models.py b/openslides/agenda/models.py
index f1b7efd78..8e9efa75c 100644
--- a/openslides/agenda/models.py
+++ b/openslides/agenda/models.py
@@ -140,5 +140,3 @@ from projector.api import register_slidefunc
from agenda.slides import agenda_show
register_slidefunc('agenda_show', agenda_show, category=_('Agenda'))
-
-
diff --git a/openslides/agenda/views.py b/openslides/agenda/views.py
index 984e01796..91bb5d7b0 100644
--- a/openslides/agenda/views.py
+++ b/openslides/agenda/views.py
@@ -19,6 +19,7 @@ from django.views.generic.detail import SingleObjectMixin
from utils.pdf import stylesheet
from utils.views import TemplateView, RedirectView, UpdateView, CreateView, DeleteView, PDFView, FormView
+from utils.template import Tab
from system import config
@@ -47,7 +48,7 @@ class Overview(TemplateView):
template_name = 'agenda/overview.html'
def get_context_data(self, **kwargs):
- context = super(TemplateView, self).get_context_data(**kwargs)
+ context = super(Overview, self).get_context_data(**kwargs)
context.update({
'items': Item.objects.all(),
'overview': get_active_slide(only_sid=True) == 'agenda_show',
@@ -56,6 +57,7 @@ class Overview(TemplateView):
return context
def post(self, request, *args, **kwargs):
+ #todo: check for permission
context = self.get_context_data(**kwargs)
#todo: check for any erros in the forms befor saving the data
for item in Item.objects.all():
@@ -209,3 +211,13 @@ class Config(FormView):
config['agenda_countdown_time'] = form.cleaned_data['agenda_countdown_time']
messages.success(self.request, _('Agenda settings successfully saved.'))
return super(Config, self).form_valid(form)
+
+
+def register_tab(request):
+ selected = True if request.path.startswith('/agenda/') else False
+ return Tab(
+ title=_('Agenda'),
+ url=reverse('item_overview'),
+ permission=request.user.has_perm('agenda.can_see_agenda') or request.user.has_perm('agenda.can_manage_agenda'),
+ selected=selected,
+ )
diff --git a/openslides/application/views.py b/openslides/application/views.py
index 3c5477754..479173847 100644
--- a/openslides/application/views.py
+++ b/openslides/application/views.py
@@ -43,6 +43,7 @@ from poll.views import PollFormView
from utils.utils import template, permission_required, \
render_to_forbitten, del_confirm_form, gen_confirm_form
from utils.views import FormView
+from utils.template import Tab
from utils.pdf import print_application, print_application_poll
@@ -611,3 +612,13 @@ class Config(FormView):
config['application_pdf_preamble'] = form.cleaned_data['application_pdf_preamble']
messages.success(self.request, _('Application settings successfully saved.'))
return super(Config, self).form_valid(form)
+
+
+def register_tab(request):
+ selected = True if request.path.startswith('/application/') else False
+ return Tab(
+ title=_('Application'),
+ url=reverse('application_overview'),
+ permission=request.user.has_perm('application.can_see_application') or request.user.has_perm('application.can_support_application') or request.user.has_perm('application.can_support_application') or request.user.has_perm('application.can_manage_application'),
+ selected=selected,
+ )
diff --git a/openslides/assignment/models.py b/openslides/assignment/models.py
index 2e060dc79..a748ceffc 100644
--- a/openslides/assignment/models.py
+++ b/openslides/assignment/models.py
@@ -146,3 +146,4 @@ class AssignmentPoll(BasePoll, CountInvalid, CountVotesCast, PublishPollMixin):
CountVotesCast.append_pollform_fields(self, fields)
#register_slidemodel(AssignmentPoll, category=_('Elections'))
+
diff --git a/openslides/assignment/views.py b/openslides/assignment/views.py
index 206f370bb..bab780075 100644
--- a/openslides/assignment/views.py
+++ b/openslides/assignment/views.py
@@ -19,6 +19,7 @@ from django.utils.translation import ugettext as _
from utils.utils import template, permission_required, gen_confirm_form, del_confirm_form, ajax_request
from utils.pdf import print_assignment, print_assignment_poll
from utils.views import FormView
+from utils.template import Tab
from system import config
@@ -291,3 +292,13 @@ class Config(FormView):
config['assignment_pdf_preamble'] = form.cleaned_data['assignment_pdf_preamble']
messages.success(self.request, _('Election settings successfully saved.'))
return super(Config, self).form_valid(form)
+
+
+def register_tab(request):
+ selected = True if request.path.startswith('/assignment/') else False
+ return Tab(
+ title=_('Elections'),
+ url=reverse('assignment_overview'),
+ permission=request.user.has_perm('assignment.can_see_assignment') or request.user.has_perm('assignment.can_nominate_other') or request.user.has_perm('assignment.can_nominate_self') or request.user.has_perm('assignment.can_manage_assignment'),
+ selected=selected,
+ )
diff --git a/openslides/openslides_settings.py b/openslides/openslides_settings.py
index 42ab7dd3e..0c59035d2 100644
--- a/openslides/openslides_settings.py
+++ b/openslides/openslides_settings.py
@@ -101,14 +101,14 @@ INSTALLED_APPS = (
'django.contrib.messages',
'django.contrib.admin',
'mptt',
- 'system',
'utils',
- 'projector',
'poll',
+ 'projector',
'agenda',
- 'participant',
'application',
'assignment',
+ 'participant',
+ 'system',
)
TEMPLATE_CONTEXT_PROCESSORS = (
diff --git a/openslides/participant/models.py b/openslides/participant/models.py
index d1f20bfcb..32c06d3a3 100644
--- a/openslides/participant/models.py
+++ b/openslides/participant/models.py
@@ -52,4 +52,3 @@ class Profile(models.Model):
('can_see_participant', "Can see participant"),
('can_manage_participant', "Can manage participant"),
)
-
diff --git a/openslides/participant/views.py b/openslides/participant/views.py
index 9b3e81641..b4c6ee9b6 100644
--- a/openslides/participant/views.py
+++ b/openslides/participant/views.py
@@ -36,6 +36,7 @@ from participant.api import gen_username, gen_password
from participant.forms import UserNewForm, UserEditForm, ProfileForm, UsersettingsForm, UserImportForm, GroupForm, AdminPasswordChangeForm
from utils.utils import template, permission_required, gen_confirm_form
from utils.pdf import print_userlist, print_passwords
+from utils.template import Tab
from system import config
from django.db.models import Avg, Max, Min, Count
@@ -373,3 +374,13 @@ def reset_password(request, user_id):
gen_confirm_form(request, _('Do you really want to reset the password for %s?') % user,
reverse('user_reset_password', args=[user_id]))
return redirect(reverse('user_edit', args=[user_id]))
+
+
+def register_tab(request):
+ selected = True if request.path.startswith('/participant/') else False
+ return Tab(
+ title=_('Participants'),
+ url=reverse('user_overview'),
+ permission=request.user.has_perm('participant.can_see_participant') or request.user.has_perm('participant.can_manage_participant'),
+ selected=selected,
+ )
diff --git a/openslides/poll/__init__.py b/openslides/poll/__init__.py
index bd6a1282e..75a918bfb 100644
--- a/openslides/poll/__init__.py
+++ b/openslides/poll/__init__.py
@@ -1,13 +1,13 @@
-from django.utils.translation import ugettext as _
-
-from models import BasePoll
-from views import PollFormView
-
-
-class DesicionPoll(PollFormView):
- vote_values = [_('yes'), _('no'), _('contained')]
- poll_class = BasePoll
-
-
-class ChoicePoll(PollFormView):
- poll_class = BasePoll
+## from django.utils.translation import ugettext as _
+##
+## from models import BasePoll
+## from views import PollFormView
+##
+##
+## class DesicionPoll(PollFormView):
+ ## vote_values = [_('yes'), _('no'), _('contained')]
+ ## poll_class = BasePoll
+##
+##
+## class ChoicePoll(PollFormView):
+ ## poll_class = BasePoll
diff --git a/openslides/projector/models.py b/openslides/projector/models.py
index 07685a431..14cccf501 100644
--- a/openslides/projector/models.py
+++ b/openslides/projector/models.py
@@ -24,3 +24,4 @@ class ProjectorSlide(models.Model, SlideMixin):
)
register_slidemodel(ProjectorSlide, category=_('Projector'), model_name=_('Projector Slide'))
+
diff --git a/openslides/projector/views.py b/openslides/projector/views.py
index c2d51a693..065bc9a8e 100644
--- a/openslides/projector/views.py
+++ b/openslides/projector/views.py
@@ -22,6 +22,7 @@ from utils.views import TemplateView, RedirectView
from utils.utils import template, permission_required, \
del_confirm_form, ajax_request
from utils.template import render_block_to_string
+from utils.template import Tab
from system import config
@@ -146,3 +147,14 @@ def projector_countdown(request, command, time=60):
return ajax_request({'countdown_visible': config['countdown_visible'],
'link': link})
return redirect(reverse('projector_control'))
+
+
+def register_tab(request):
+ selected = True if request.path.startswith('/projector/') else False
+ return Tab(
+ title=_('Projector'),
+ url=reverse('projector_control'),
+ permission=request.user.has_perm('projector.can_manag_projector'),
+ selected=selected,
+ )
+
diff --git a/openslides/system/models.py b/openslides/system/models.py
index 030f7cb94..33646b04d 100644
--- a/openslides/system/models.py
+++ b/openslides/system/models.py
@@ -75,5 +75,37 @@ class Config(object):
c.save()
self.config[key] = value
+from django.dispatch import receiver
+from django.core.urlresolvers import reverse
+from django.utils.importlib import import_module
+import settings
+
+from openslides.utils.signals import template_manipulation
+
+
+
+@receiver(template_manipulation, dispatch_uid="system_base_system")
+def set_submenu(sender, request, context, **kwargs):
+ selected = True if request.path == reverse('config_general') else False
+ menu_links = [
+ (reverse('config_general'), _('General'), selected),
+ ]
+ for app in settings.INSTALLED_APPS:
+ try:
+ mod = import_module(app + '.views')
+ mod.Config
+ except (ImportError, AttributeError):
+ continue
+
+ appname = mod.__name__.split('.')[0]
+ selected = True if reverse('config_%s' % appname) == request.path else False
+ menu_links.append(
+ (reverse('config_%s' % appname), _(appname.title()), selected)
+ )
+
+ context.update({
+ 'menu_links': menu_links,
+ })
+
diff --git a/openslides/system/views.py b/openslides/system/views.py
index df862b3a3..0bc14f0b1 100644
--- a/openslides/system/views.py
+++ b/openslides/system/views.py
@@ -15,19 +15,16 @@ from django.core.urlresolvers import reverse
from django.contrib import messages
from django.contrib.auth.models import Group, Permission
from django.utils.translation import ugettext as _
-from django.dispatch import receiver
from django.template.loader import render_to_string
-from django.utils.importlib import import_module
from utils.utils import template, permission_required
from utils.views import FormView
+from utils.template import Tab
from system.forms import SystemConfigForm, EventConfigForm
-from openslides.utils.signals import template_manipulation
-
from system import config
-import settings
+
class GeneralConfig(FormView):
@@ -92,25 +89,12 @@ class Config(FormView):
return super(Config, self).form_valid(form)
-@receiver(template_manipulation, dispatch_uid="system_base_system")
-def set_submenu(sender, request, context, **kwargs):
- selected = True if request.path == reverse('config_general') else False
- menu_links = [
- (reverse('config_general'), _('General'), selected),
- ]
- for app in settings.INSTALLED_APPS:
- try:
- mod = import_module(app + '.views')
- mod.Config
- except (ImportError, AttributeError):
- continue
+def register_tab(request):
+ selected = True if request.path.startswith('/config/') else False
+ return Tab(
+ title=_('Configuration'),
+ url=reverse('config_general'),
+ permission=request.user.has_perm('system.can_manage_system'),
+ selected=selected,
+ )
- appname = mod.__name__.split('.')[0]
- selected = True if reverse('config_%s' % appname) == request.path else False
- menu_links.append(
- (reverse('config_%s' % appname), _(appname.title()), selected)
- )
-
- context.update({
- 'menu_links': menu_links,
- })
diff --git a/openslides/templates/base.html b/openslides/templates/base.html
index 83b5eb0ca..ed8512d48 100644
--- a/openslides/templates/base.html
+++ b/openslides/templates/base.html
@@ -33,30 +33,13 @@
{% block mainmenu %}
- -
- {%trans "Projector" %}
-
- {% if perms.agenda.can_see_agenda or perms.agenda.can_manage_agenda %}
- -
- {%trans "Agenda" %}
- {% endif %}
- {% if perms.application.can_see_application or perms.application.can_create_application or perms.application.can_support_application or perms.application.can_manage_application %}
- -
- {%trans "Applications" %}
- {% endif %}
- {% if perms.assignment.can_see_assignment or perms.assignment.can_nominate_other or perms.assignment.can_nominate_self or perms.assignment.can_manage_assignment %}
- -
- {%trans "Elections" %}
- {% endif %}
- {% if perms.participant.can_see_participant or perms.participant.can_manage_participant %}
- -
- {%trans "Participants" %}
- {% endif %}
- {% if perms.system.can_manage_system %}
- -
- {%trans "Configuration" %}
- {% endif %}
+ {% for tab in tabs %}
+ {% if tab.permission %}
+ -
+ {{ tab.title }}
+
+ {% endif %}
+ {% endfor %}
{% endblock %}
diff --git a/openslides/utils/template.py b/openslides/utils/template.py
index cb390c7af..c900a12fc 100644
--- a/openslides/utils/template.py
+++ b/openslides/utils/template.py
@@ -14,20 +14,33 @@ from django.template.loader_tags import BlockNode, ExtendsNode
from django.template import loader, Context, RequestContext, TextNode
from django.http import HttpResponse
+
+class Tab(object):
+ def __init__(self, title='', url='', permission='', selected=False):
+ self.selected = False
+ self.title = title
+ self.permission = permission
+ self.selected = selected
+ self.url = url
+
+
def get_template(template):
if isinstance(template, (tuple, list)):
return loader.select_template(template)
return loader.get_template(template)
+
class BlockNotFound(Exception):
pass
+
def render_template_block(template, block, context):
"""
Renders a single block from a template. This template should have previously been rendered.
"""
return render_template_block_nodelist(template.nodelist, block, context)
+
def render_template_block_nodelist(nodelist, block, context):
for node in nodelist:
if isinstance(node, BlockNode) and node.name == block:
@@ -46,6 +59,7 @@ def render_template_block_nodelist(nodelist, block, context):
pass
raise BlockNotFound
+
def render_block_to_string(template_name, block, dictionary=None, context_instance=None):
"""
Loads the given template_name and renders the given block with the given dictionary as
@@ -60,6 +74,7 @@ def render_block_to_string(template_name, block, dictionary=None, context_instan
t.render(context_instance)
return render_template_block(t, block, context_instance)
+
def direct_block_to_template(request, template, block, extra_context=None, mimetype=None, **kwargs):
"""
Render a given block in a given template with any extra URL parameters in the context as
diff --git a/openslides/utils/utils.py b/openslides/utils/utils.py
index 7c31715fe..aaaa9aecb 100644
--- a/openslides/utils/utils.py
+++ b/openslides/utils/utils.py
@@ -25,8 +25,11 @@ from django.contrib import messages
from django.contrib.auth.models import Permission
from django.utils.translation import ugettext as _
+from openslides.utils.signals import template_manipulation
+
from openslides import get_version
+
def revision(request):
return {'openslides_version': get_version()}
@@ -50,10 +53,13 @@ def render_response(req, *args, **kwargs):
def template(template_name):
def renderer(func):
- def wrapper(request, *args, **kw):
- output = func(request, *args, **kw)
+ def wrapper(request, *args, **kwargs):
+ output = func(request, *args, **kwargs)
if not isinstance(output, dict):
return output
+ context = {}
+ template_manipulation.send(sender='utils_template', request=request, context=context)
+ output.update(context)
response = render_to_response(template_name, output, context_instance=RequestContext(request))
if 'cookie' in output:
response.set_cookie(output['cookie'][0], output['cookie'][1])
diff --git a/openslides/utils/views.py b/openslides/utils/views.py
index 337e5738f..0a7ba0e06 100644
--- a/openslides/utils/views.py
+++ b/openslides/utils/views.py
@@ -20,6 +20,7 @@ from django.template import loader, RequestContext
from django.template.loader import render_to_string
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
+from django.dispatch import receiver
from django.views.generic import (
TemplateView as _TemplateView,
RedirectView as _RedirectView,
@@ -28,8 +29,9 @@ from django.views.generic import (
View as _View,
FormView as _FormView,
)
-
from django.views.generic.detail import SingleObjectMixin
+from django.utils.importlib import import_module
+import settings
from utils import render_to_forbitten
from openslides.utils.signals import template_manipulation
@@ -132,6 +134,11 @@ class CreateView(PermissionMixin, _CreateView):
return reverse('item_edit', args=[self.object.id])
return reverse(super(CreateView, self).get_success_url())
+ def get_context_data(self, **kwargs):
+ context = super(CreateView, self).get_context_data(**kwargs)
+ template_manipulation.send(sender=self, request=self.request, context=context)
+ return context
+
class DeleteView(RedirectView, SingleObjectMixin):
def pre_redirect(self, request, *args, **kwargs):
@@ -181,3 +188,21 @@ def server_error(request, template_name='500.html'):
"""
t = loader.get_template("500.html") # You need to create a 500.html template.
return HttpResponseServerError(render_to_string('500.html', context_instance=RequestContext(request)))
+
+
+@receiver(template_manipulation, dispatch_uid="send_register_tab")
+def send_register_tab(sender, request, context, **kwargs):
+ #del kwargs['signal']
+ #register_tab.send(sender='register', request=request, context=context, **kwargs)
+
+ tabs = []
+ for app in settings.INSTALLED_APPS:
+ try:
+ mod = import_module(app + '.views')
+ tabs.append(mod.register_tab(request))
+ except (ImportError, AttributeError):
+ continue
+
+ context.update({
+ 'tabs': tabs,
+ })