-from django.http import Http404, HttpResponse
-from django.template import RequestContext
-from django.contrib.sites.models import Site
-from philo.models import Node
+from django.conf import settings
+from django.core.urlresolvers import resolve
+from django.http import Http404, HttpResponseRedirect
+from django.views.decorators.vary import vary_on_headers
+from philo.exceptions import MIDDLEWARE_NOT_CONFIGURED
+@vary_on_headers('Accept')
def node_view(request, path=None, **kwargs):
- node = None
- subpath = None
- if path is None:
- path = '/'
- current_site = Site.objects.get_current()
- try:
- node, subpath = Node.objects.get_with_path(path, root=current_site.root_node, absolute_result=False)
- except Node.DoesNotExist:
+ if "philo.middleware.RequestNodeMiddleware" not in settings.MIDDLEWARE_CLASSES:
+ raise MIDDLEWARE_NOT_CONFIGURED
+
+ if not request.node:
+ if settings.APPEND_SLASH and request.path != "/":
+ path = request.path
+
+ if path[-1] == "/":
+ path = path[:-1]
+ else:
+ path += "/"
+
+ view, args, kwargs = resolve(path)
+ if view != node_view:
+ return HttpResponseRedirect(path)
raise Http404
- if not node:
- raise Http404
- try:
- if subpath and not node.accepts_subpath:
+
+ node = request.node
+ subpath = request.node.subpath
+
+ # Explicitly disallow trailing slashes if we are otherwise at a node's url.
+ if request._cached_node_path != "/" and request._cached_node_path[-1] == "/" and subpath == "/":
+ return HttpResponseRedirect(node.get_absolute_url())
+
+ if not node.handles_subpath(subpath):
+ # If the subpath isn't handled, check settings.APPEND_SLASH. If
+ # it's True, try to correct the subpath.
+ if not settings.APPEND_SLASH:
raise Http404
- return node.render_to_response(request, path=path, subpath=subpath)
- except Http404, e:
- try:
- Http404View = node.relationships['Http404']
- except KeyError:
- Http404View = None
- if not Http404View:
- raise e
+ if subpath[-1] == "/":
+ subpath = subpath[:-1]
+ else:
+ subpath += "/"
+
+ redirect_url = node.construct_url(subpath)
+
+ if node.handles_subpath(subpath):
+ return HttpResponseRedirect(redirect_url)
- return Http404View.render_to_response(node, request, path, subpath)
\ No newline at end of file
+ # Perhaps there is a non-philo view at this address. Can we
+ # resolve *something* there besides node_view? If not,
+ # raise a 404.
+ view, args, kwargs = resolve(redirect_url)
+
+ if view == node_view:
+ raise Http404
+ else:
+ return HttpResponseRedirect(redirect_url)
+
+ return node.render_to_response(request, kwargs)
\ No newline at end of file