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 @@ 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, + })