def navigation_items(request, node): language = get_active_language() nav = [] ## remove visible_children? Unnecessary with permission checks ## Find top/secondlevel published nodes in one query XXX for toplevel in queries.toplevel_visible_children(language=language): ## make sure /foo/bar does not match in /football by adding the / item = dict(active=False, node=toplevel) content = toplevel.content(language=language) if content: spoke = content.spoke() perm = spoke.permissions.get('view') if not auth.has_access(request, spoke, spoke, perm): continue item['url'] = toplevel.get_absolute_url(language=language) item['title'] = content.title if content else "" if toplevel == node or \ (node and node.path.startswith(toplevel.path + '/')): item['active'] = True sub = [] for secondlevel in queries.get_visible_children(toplevel, language=language): slitem = dict(node=secondlevel) content = secondlevel.content(language=language) spoke = content.spoke() perm = spoke.permissions.get('view') if not auth.has_access(request, spoke, spoke, perm): continue slitem['url'] = secondlevel.get_absolute_url(language=language) slitem['title'] = content.title if content else "" sub.append(slitem) item['sub'] = sub nav.append(item) return dict(toplevel=nav)
def tabs(self, spoke=None): """ return the tabs / actions the user has access to """ if not spoke and self.instance and self.instance.content(): spoke = self.spoke() if spoke: return [tab for tab in spoke.tabs() if auth.has_access(self.request, spoke, spoke, tab.get('permission', permissions.edit_content))]
def post(self, request): config = request.REQUEST.get('config', '') action = request.REQUEST.get('action', '') ## XXX Decorate this! if not auth.has_access(self.request, Spoke, None, p.modify_settings): return self.forbidden() instance = self.get_instance(config) klass = configuration_registry.get(config) self.context['tabs'] = self.construct_tabs(klass.id) k = klass() if action: action_handler = getattr(k, action, None) if action_handler and getattr(action_handler, 'action', False): return getattr(k, action)(self, instance) return klass().process(self, instance)
def handle_list(self): spoke = self.spoke() if spoke: perm = spoke.permissions.get('list') else: perm = Spoke.permissions.get('list') if not auth.has_access(self.request, spoke, spoke, perm): return self.forbidden() if self.toolbar: self.toolbar.status = Toolbar.LIST self.context['breadcrumb'] = self.breadcrumb(operation="Contents") self.context['can_paste'] = \ len(self.request.session.get('clipboard_copy', [])) + \ len(self.request.session.get('clipboard_cut', [])) active = self.active_language() children = [] for child in self.instance.children(): c = dict(node=child, active=None, translations=[], ipath=child.tree_path) for lang, langtitle in translate.languages(): langcontent = child.content(language=lang) c["translations"].append((lang, langcontent, "switch_admin_language?path=" + child.tree_path + "&switchto=" + lang + "&rest=edit")) if lang == active: c["active"] = langcontent if not c['active']: c['active'] = child.primary_content() children.append(c) self.context['children'] = children if spoke: return self.template(spoke.list_template()) return self.template("wheelcms_axle/contents.html")
def view(self): """ frontpage / view """ language = self.active_language() spoke = self.spoke(language=language) if spoke: ## update the context with addtional data from the spoke self.context.update(spoke.context(self, self.request, self.instance)) perm = spoke.permissions.get('view') else: perm = Spoke.permissions.get('view') if not auth.has_access(self.request, spoke, spoke, perm): return self.forbidden() if spoke: tpl = spoke.view_template() ctx = template_registry.context.get((spoke.__class__, tpl)) if ctx: self.context.update(ctx(self, self.request, self.instance)) return self.template(spoke.view_template()) elif self.instance.primary_content(): """ attached but untranslated """ if self.hasaccess(): return self.redirect(self.instance.get_absolute_url(language=language) + "edit", info="This content is not available in this language") elif self.instance.isroot(): return self.template("wheelcms_axle/notranslation.html") return self.notfound() return self.template("wheelcms_axle/nospoke.html")
def edit(self): language = self.active_language() instance = self.instance supported_languages = (l[0] for l in translate.languages()) if language not in supported_languages: return self.redirect(instance.get_absolute_url(), error="Unsupported Language") if self.spoke(): ## update the context with addtional data from the spoke self.context.update(self.spoke().context(self, self.request, self.instance)) content = instance.content(language=language) create_translation = False if content is None: pcontent = instance.primary_content() typename = pcontent.get_name() typeinfo = type_registry.get(typename) create_translation = True spoke = pcontent.spoke() else: typename = content.get_name() typeinfo = type_registry.get(typename) spoke = content.spoke() perm = typeinfo.permissions.get('edit') if not auth.has_access(self.request, typeinfo, spoke, perm): return self.forbidden() # reset tabs with current language tabs self.context['tabs'] = self.tabs(spoke) parent = instance.parent() self.context['redirect_cancel'] = self.instance.get_absolute_url() + \ "?info=Update+cancelled" if self.toolbar: self.toolbar.status = Toolbar.UPDATE formclass = typeinfo.form slug = instance.slug(language=language) if self.is_post: args = dict(parent=parent, data=self.request.POST, reserved=self.reserved(), skip_slug=self.instance.isroot(), node=self.instance, files=self.request.FILES) if content: args['instance'] = content self.context['form'] = form = formclass(**args) if form.is_valid(): try: if create_translation: content = form.save(commit=False) else: # ordinary update content = form.save() except OSError, e: messages.error("An error occured while saving: %s" % str(e)) if create_translation: if self.user().is_authenticated(): content.owner = self.user() content.node = self.instance content.save() form.save_m2m() ## handle changed slug slug = form.cleaned_data.get('slug', None) content_language = form.cleaned_data.get('language', settings.FALLBACK) if slug and slug != self.instance.slug(language=content_language): self.instance.rename(slug, language=content_language) return self.redirect(instance.get_absolute_url(), success="Updated")
def create(self, type=None, attach=False, *a, **b): """ Create new sub-content on a node or attach content to an existing node. WheelCMS's structure doesn't map to two.ol's REST-like Resource structure. In two.ol's setup, you have a resource name and an optional id, e.g. /person/123 GETting /person/create would give the create form and POSTing to /person would create a new person. POSTing to /person/123 would update person 123 But in WheelCMS's case, there's no explicit resource; the resource under which a new object is to be created ("the parent") can be any existing object. This is solved by explicitly posting a create to /..parent../create where ..parent.. is available as self.instance """ language = self.active_language() if type is None: return self.badrequest() ##if not self.hasaccess(): ## return self.forbidden() typeinfo = type_registry.get(type) perm = typeinfo.permissions.get('create') # alternatives: # typeinfo.has_access('edit', request) # ... on instance? if not auth.has_access(self.request, typeinfo, None, perm): return self.forbidden() formclass = typeinfo.form parent = self.instance parentpath = parent.get_absolute_url() self.context['redirect_cancel'] = parentpath + "?info=Create+canceled" self.context['form_action'] = 'create' ## make it absolute? ## Hide tabs since we're creating new content self.context['tabs'] = () ## if attach: do not accept slug if self.is_post: self.context['form'] = \ self.form = formclass(data=self.request.POST, parent=parent, attach=attach, reserved=self.reserved(), files=self.request.FILES) if self.form.is_valid(): target = parent ## where to redirect to p = self.form.save(commit=False) if self.user().is_authenticated(): p.owner = self.user() try: p.save() self.form.save_m2m() if attach: parent.set(p) else: slug = self.form.cleaned_data['slug'] sub = parent.add(slug) sub.set(p) target = sub ## force reindex typeinfo.model.objects.get(pk=p.pk).save() return self.redirect(target.get_absolute_url(), success='"%s" created' % p.title) except OSError, e: messages.error("An error occured while saving: %s" % str(e))
def get(self, request, nodepath=None, handlerpath="", action="", **kw): """ instance - the path to a piece of content path - remaining, specifies operation to be invoked. To be deprecated in favor of +actins """ self.toolbar = get_toolbar() # locale.activate_content_language(None) self.instance = self.resolve(nodepath) ## an action may end in slash: remove it if action: action = action.rstrip('/') language = get_active_language() if self.toolbar: self.toolbar.instance = self.instance self.toolbar.status = Toolbar.VIEW if self.instance is None: return self.notfound() ## make sure the instance is part of the context self.context['instance'] = self.instance ## pre_handler is to be deprecated. It also depends on self.instance self.pre_handler() spoke = self.spoke(language=language) ## retrieve content type info if spoke: ## update the context with addtional data from the spoke self.context.update(spoke.context(self, self.request, self.instance)) perm = spoke.permissions.get('view') else: perm = Spoke.permissions.get('view') ## Set default current tab self.context['tab_action'] = 'attributes' try: if handlerpath: handler = gethandler(self, handlerpath) if handler: return handler() return self.notfound() if action: action_handler = action_registry.get(action, self.instance.path, spoke) if action_handler is None: return self.notfound() ## Should the (decorator for) the action handler do permission checks? required_permission = getattr(action_handler, 'permission', perm) if required_permission is None: # default to spoke permission required_permission = perm if not auth.has_access(self.request, spoke, spoke, required_permission): return self.forbidden() ## if there's an action, assume it's actually an update action. if self.toolbar: self.toolbar.status = Toolbar.UPDATE ## Update context if it's a tab action if tabaction(action_handler): self.context['tab_action'] = tabaction(action_handler) return action_handler(self, request, action) if not handlerpath: ## special case: post to content means edit/update if self.is_post: return self.edit() return self.view() return self.notfound() finally: # XXX Does this work as expected? self.post_handler()