1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
#
# Copyright (C) 2010 Wikkid Developers
#
# This software is licensed under the GNU Affero General Public License
# version 3 (see the file LICENSE).
"""The base view class."""
import logging
from webob import Response
from wikkid.dispatcher import register_view
from wikkid.view.urls import canonical_url
from wikkid.view.utils import title_for_filename
from wikkid.interface.resource import IDefaultPage, IRootResource
class BaseViewMetaClass(type):
"""This metaclass registers the view with the view registry."""
def __new__(cls, classname, bases, classdict):
"""Called when defining a new class."""
instance = type.__new__(cls, classname, bases, classdict)
register_view(instance)
return instance
class Breadcrumb(object):
"""Breadcrumbs exist to give the user quick links up the path chain."""
def __init__(self, context, request, view=None, title=None):
self.path = canonical_url(context, request, view)
if title is None:
self.title = title_for_filename(context.base_name)
else:
self.title = title
class BaseView(object, metaclass=BaseViewMetaClass):
"""The base view class.
This is an abstract base class.
"""
def __init__(self, context, request, execution_context):
self.execution_context = execution_context
self.context = context
self.request = request
if request is not None:
self.user = request.environ.get('wikkid.user', None)
self.logger = logging.getLogger('wikkid')
def _create_breadcrumbs(self):
crumbs = [Breadcrumb(self.context, self.request)]
current = self.context.parent
while not IRootResource.providedBy(current):
crumbs.append(Breadcrumb(current, self.request))
current = current.parent
# And add in the default page if the context isn't the default.
if not IDefaultPage.providedBy(self.context):
crumbs.append(Breadcrumb(current.default_resource, self.request))
return reversed(crumbs)
def initialize(self):
"""Provide post-construction initialization."""
@property
def breadcrumbs(self):
return self._create_breadcrumbs()
@property
def title(self):
return title_for_filename(self.context.base_name)
@property
def last_modified_by(self):
return self.context.last_modified_by
@property
def last_modified_date(self):
last_modified = self.context.last_modified_date
if last_modified is None:
return None
return last_modified.strftime('%Y-%m-%d %H:%M:%S')
def before_render(self):
"""A hook to do things before rendering."""
def canonical_url(self, context, view=None):
return canonical_url(context, self.request, view)
def template_args(self):
"""Needs to be implemented in the derived classes.
:returns: A dict of values.
"""
return {
'view': self,
'user': self.user,
'context': self.context,
'request': self.request,
'canonical_url': self.canonical_url,
}
def _render(self, skin):
"""Get the template and render with the args.
If a template isn't going to be used or provide the conent,
this is the method to override.
"""
template = skin.get_template(self.template)
content = template.render(**self.template_args())
# Return the encoded content.
return self.make_response(content.encode('utf-8'))
def make_response(self, body):
"""Construct the response object for this request.
:param body: The body of the response, as a unicode string.
:return: A `Response` object.
"""
return Response(body)
def render(self, skin):
"""Render the page.
Return a tuple of content type and content.
"""
self.before_render()
return self._render(skin)
class DirectoryBreadcrumbView(BaseView):
"""A view that uses the directories as breadcrumbs."""
def _create_breadcrumbs(self):
crumbs = []
current = self.context
view = None
while not IRootResource.providedBy(current):
crumbs.append(Breadcrumb(
current, self.request, view, title=current.base_name))
current = current.parent
# Add listings to subsequent urls.
view = 'listing'
# Add in the root dir.
crumbs.append(Breadcrumb(current, self.request, 'listing',
title='wiki root'))
# And add in the default page.
crumbs.append(Breadcrumb(current.default_resource, self.request))
return reversed(crumbs)
|