Implemented better container filtering for page container inlines.
[philo.git] / models / nodes.py
index f46ddce..14f5063 100644 (file)
@@ -4,13 +4,14 @@ from django.contrib.contenttypes import generic
 from django.contrib.sites.models import Site
 from django.http import HttpResponse, HttpResponseServerError, HttpResponseRedirect
 from django.core.servers.basehttp import FileWrapper
 from django.contrib.sites.models import Site
 from django.http import HttpResponse, HttpResponseServerError, HttpResponseRedirect
 from django.core.servers.basehttp import FileWrapper
-from django.core.urlresolvers import resolve
+from django.core.urlresolvers import resolve, clear_url_caches
 from django.template import add_to_builtins as register_templatetags
 from inspect import getargspec
 from django.template import add_to_builtins as register_templatetags
 from inspect import getargspec
-from philo.models.base import TreeEntity, Entity, QuerySetMapper
+from philo.models.base import TreeEntity, Entity, QuerySetMapper, register_value_model
 from philo.utils import ContentTypeSubclassLimiter
 from philo.validators import RedirectValidator
 from philo.utils import ContentTypeSubclassLimiter
 from philo.validators import RedirectValidator
-from philo.exceptions import ViewDoesNotProvideSubpaths
+from philo.exceptions import ViewDoesNotProvideSubpaths, AncestorDoesNotExist
+from philo.signals import view_about_to_render, view_finished_rendering
 
 
 _view_content_type_limiter = ContentTypeSubclassLimiter(None)
 
 
 _view_content_type_limiter = ContentTypeSubclassLimiter(None)
@@ -30,6 +31,13 @@ class Node(TreeEntity):
        def render_to_response(self, request, path=None, subpath=None, extra_context=None):
                return self.view.render_to_response(self, request, path, subpath, extra_context)
        
        def render_to_response(self, request, path=None, subpath=None, extra_context=None):
                return self.view.render_to_response(self, request, path, subpath, extra_context)
        
+       def get_absolute_url(self):
+               root = Site.objects.get_current().root_node
+               try:
+                       return '/%s' % self.get_path(root=root)
+               except AncestorDoesNotExist:
+                       return None
+       
        class Meta:
                app_label = 'philo'
 
        class Meta:
                app_label = 'philo'
 
@@ -53,6 +61,13 @@ class View(Entity):
                return QuerySetMapper(self.relationship_set, passthrough=node.relationships)
        
        def render_to_response(self, node, request, path=None, subpath=None, extra_context=None):
                return QuerySetMapper(self.relationship_set, passthrough=node.relationships)
        
        def render_to_response(self, node, request, path=None, subpath=None, extra_context=None):
+               extra_context = extra_context or {}
+               view_about_to_render.send(sender=self, node=node, request=request, path=path, subpath=subpath, extra_context=extra_context)
+               response = self.actually_render_to_response(node, request, path, subpath, extra_context)
+               view_finished_rendering.send(sender=self, response=response)
+               return response
+       
+       def actually_render_to_response(self, node, request, path=None, subpath=None, extra_context=None):
                raise NotImplementedError('View subclasses must implement render_to_response.')
        
        class Meta:
                raise NotImplementedError('View subclasses must implement render_to_response.')
        
        class Meta:
@@ -67,17 +82,18 @@ class MultiView(View):
        
        urlpatterns = []
        
        
        urlpatterns = []
        
-       def render_to_response(self, node, request, path=None, subpath=None, extra_context=None):
+       def actually_render_to_response(self, node, request, path=None, subpath=None, extra_context=None):
+               clear_url_caches()
                if not subpath:
                        subpath = ""
                subpath = "/" + subpath
                view, args, kwargs = resolve(subpath, urlconf=self)
                if not subpath:
                        subpath = ""
                subpath = "/" + subpath
                view, args, kwargs = resolve(subpath, urlconf=self)
-               view_args = getargspec(view)[0]
-               if extra_context is not None and 'extra_context' in view_args:
+               view_args = getargspec(view)
+               if extra_context is not None and ('extra_context' in view_args[0] or view_args[2] is not None):
                        if 'extra_context' in kwargs:
                                extra_context.update(kwargs['extra_context'])
                        kwargs['extra_context'] = extra_context
                        if 'extra_context' in kwargs:
                                extra_context.update(kwargs['extra_context'])
                        kwargs['extra_context'] = extra_context
-               if 'node' in view_args:
+               if 'node' in view_args[0] or view_args[2] is not None:
                        kwargs['node'] = node
                return view(request, *args, **kwargs)
        
                        kwargs['node'] = node
                return view(request, *args, **kwargs)
        
@@ -93,7 +109,7 @@ class Redirect(View):
        target = models.CharField(max_length=200, validators=[RedirectValidator()])
        status_code = models.IntegerField(choices=STATUS_CODES, default=302, verbose_name='redirect type')
        
        target = models.CharField(max_length=200, validators=[RedirectValidator()])
        status_code = models.IntegerField(choices=STATUS_CODES, default=302, verbose_name='redirect type')
        
-       def render_to_response(self, node, request, path=None, subpath=None, extra_context=None):
+       def actually_render_to_response(self, node, request, path=None, subpath=None, extra_context=None):
                response = HttpResponseRedirect(self.target)
                response.status_code = self.status_code
                return response
                response = HttpResponseRedirect(self.target)
                response.status_code = self.status_code
                return response
@@ -108,7 +124,7 @@ class File(View):
        mimetype = models.CharField(max_length=255)
        file = models.FileField(upload_to='philo/files/%Y/%m/%d')
        
        mimetype = models.CharField(max_length=255)
        file = models.FileField(upload_to='philo/files/%Y/%m/%d')
        
-       def render_to_response(self, node, request, path=None, subpath=None, extra_context=None):
+       def actually_render_to_response(self, node, request, path=None, subpath=None, extra_context=None):
                wrapper = FileWrapper(self.file)
                response = HttpResponse(wrapper, content_type=self.mimetype)
                response['Content-Length'] = self.file.size
                wrapper = FileWrapper(self.file)
                response = HttpResponse(wrapper, content_type=self.mimetype)
                response['Content-Length'] = self.file.size
@@ -121,4 +137,5 @@ class File(View):
                return self.file.name
 
 
                return self.file.name
 
 
-register_templatetags('philo.templatetags.nodes')
\ No newline at end of file
+register_templatetags('philo.templatetags.nodes')
+register_value_model(Node)
\ No newline at end of file