def page_dispatch(request, *args, **kwargs): """ This is our main entry-point for pages. From here we will determine what page we are working with, check if that page has a custom view. If the page has a custom view, we will dispatch to that view, otherwise we will use our default ``PageView`` """ PAGES_SITE_TREEID = getattr(settings, 'OSTINATO_PAGES_SITE_TREEID', None) ## Some basic page checking and authorization if 'path' in kwargs: if kwargs['path'][-1] == '/': path = kwargs['path'][:-1].split('/') else: path = kwargs['path'].split('/') if PAGES_SITE_TREEID: page = get_object_or_404(Page, slug=path[-1], tree_id=PAGES_SITE_TREEID) else: page = get_object_or_404(Page, slug=path[-1]) else: # If we are looking at the root path, show the root page for the current site if PAGES_SITE_TREEID: page = get_object_or_404(Page, tree_id=PAGES_SITE_TREEID, level=0) else: page = get_object_or_404(Page, tree_id=1, level=0) sm = get_workflow()(instance=page) has_perm = request.user.has_perm('pages.private_view') if not request.user.is_superuser and sm.state == 'Private' and not has_perm: return http.HttpResponseForbidden() content = page.get_content_model() ## Check if the page has a custom view if hasattr(content.ContentOptions, 'view'): module_path, view_class = content.ContentOptions.view.rsplit('.', 1) # Import our custom view v = __import__(module_path, locals(), globals(), [view_class], -1)\ .__dict__[view_class] if hasattr(v, 'as_view'): return v.as_view(page=page)(request, *args, **kwargs) else: # Doesn't look like this is a class based view. Treat it as a # traditional function based view kwargs.update({'page': page, 'template': page.get_template()}) return v(request, *args, **kwargs) else: return PageView.as_view(page=page)(request, *args, **kwargs)
class Meta: permissions = get_workflow().get_permissions('page', 'Page') verbose_name = _("Page") verbose_name_plural = _("Pages")
class Page(MPTTModel): """ A basic page model """ title = models.CharField(_("Title"), max_length=150) slug = models.SlugField(_("Slug"), unique=True, help_text=_("A url friendly slug.")) short_title = models.CharField( _("Short title"), max_length=50, null=True, blank=True, help_text=_("A shorter title which can be used in menus etc. If " "this is not supplied then the normal title field will " "be used.")) template = models.CharField(_("Template"), max_length=250) redirect = models.CharField( _("Redirect"), max_length=200, blank=True, null=True, help_text=_("Use this to point to redirect to another page or " "website.")) show_in_nav = models.BooleanField(_("Show in nav"), default=True) show_in_sitemap = models.BooleanField(_("Show in sitemap"), default=True) state = models.IntegerField(_("State"), default=PAGES_SETTINGS['DEFAULT_STATE'], choices=get_workflow().get_choices()) created_date = models.DateTimeField(_("Created date"), null=True, blank=True) modified_date = models.DateTimeField(_("Modified date"), null=True, blank=True) publish_date = models.DateTimeField(_("Published date"), null=True, blank=True) parent = TreeForeignKey('self', verbose_name=_("Parent"), null=True, blank=True, related_name='page_children') ## Managers objects = PageManager() ## Required for caching some objects _contents = None _content_model = None class Meta: permissions = get_workflow().get_permissions('page', 'Page') verbose_name = _("Page") verbose_name_plural = _("Pages") def __unicode__(self): return '%s' % self.title def save(self, *args, **kwargs): now = timezone.now() if not self.id or not self.created_date: self.created_date = now # since it's created the first time, and we want it # published by default, we need to set the date now. if self.state == 5: self.publish_date = now self.modified_date = now page = super(Page, self).save(*args, **kwargs) # Make sure to clear the url, navbar and breadcrumbs cache Page.objects.clear_url_cache() Page.objects.clear_navbar_cache() Page.objects.clear_breadcrumbs_cache() return page def get_short_title(self): if self.short_title: return self.short_title else: return self.title @models.permalink def perma_url(self, data): """ A seperate method to specifically deal with permalinks """ return data def get_absolute_url(self, clear_cache=False): """ Cycle through the parents and generate the path """ cache = get_cache(PAGES_SETTINGS['CACHE_NAME']) cache_key = 'ostinato:pages:page:%s:url' % self.id if clear_cache: cache.delete(cache_key) url = cache.get(cache_key) if not url: if self.redirect: return self.redirect if self.is_root_node() and self == Page.objects.root_nodes()[0]: url = reverse('ostinato_page_home') else: path = list(self.get_ancestors().values_list('slug', flat=True)) path.append(self.slug) url = self.perma_url(('ostinato_page_view', None, { 'path': '/'.join(path) })) # Set the cache to timeout after a month cache.set(cache_key, url, 60 * 60 * 24 * 7 * 4) # Now that we have the url, we should also cache the path lookup. # This is used by the PageManager.objects.get_from_path() to discover # a page based on the url path. url_cache_key = 'ostinato:pages:page_for_path:%s' % url cache.set(url_cache_key, self, 60 * 60 * 24 * 7 * 4) return url def get_content_model(self): """ A shortcut to load the content model from the ContentRegister """ # FIXME: I dont like the import in here, but this is a requirement # right now, since importing this outside causes circular imports. # This is probably due to a limitation in the appregister code. from ostinato.pages.registry import page_content return page_content.get_content_model(self.template) def get_content(self): """ Returns the content for this page or None if it doesn't exist. """ if not self._contents: obj_model = self.get_content_model() try: self._contents = obj_model.objects.get(page=self.id) except obj_model.DoesNotExist: self._contents = 'empty' return self._contents contents = property(get_content) def get_template(self): return self.get_content_model().get_template()
def page_state(self, obj): sm = get_workflow()(instance=obj) return sm.state