[Checkins] SVN: megrok.quarry/trunk/ add ContentProvider support
with ITALNamespaceData
Kevin Smith
kevin at mcweekly.com
Thu May 3 15:24:14 EDT 2007
Log message for revision 75071:
add ContentProvider support with ITALNamespaceData
Changed:
U megrok.quarry/trunk/README.txt
U megrok.quarry/trunk/src/megrok/quarry/__init__.py
U megrok.quarry/trunk/src/megrok/quarry/components.py
U megrok.quarry/trunk/src/megrok/quarry/directive.py
U megrok.quarry/trunk/src/megrok/quarry/meta.py
-=-
Modified: megrok.quarry/trunk/README.txt
===================================================================
--- megrok.quarry/trunk/README.txt 2007-05-03 19:20:37 UTC (rev 75070)
+++ megrok.quarry/trunk/README.txt 2007-05-03 19:24:13 UTC (rev 75071)
@@ -197,6 +197,7 @@
The Grok team lead by Martijn and Philipp and Zope3 community for making web programming
entirely too much fun. :)
+>>>>>>> MERGE-SOURCE
Modified: megrok.quarry/trunk/src/megrok/quarry/__init__.py
===================================================================
--- megrok.quarry/trunk/src/megrok/quarry/__init__.py 2007-05-03 19:20:37 UTC (rev 75070)
+++ megrok.quarry/trunk/src/megrok/quarry/__init__.py 2007-05-03 19:24:13 UTC (rev 75071)
@@ -1,5 +1,5 @@
# this directory is a package
-from directive import layer, template, viewletmanager
-from components import Layer, Skin, View, Viewlet, ViewletManager
+from directive import layer, template, viewletmanager, talnamespace
+from components import Layer, Skin, View, Viewlet, ViewletManager, ContentProvider
Modified: megrok.quarry/trunk/src/megrok/quarry/components.py
===================================================================
--- megrok.quarry/trunk/src/megrok/quarry/components.py 2007-05-03 19:20:37 UTC (rev 75070)
+++ megrok.quarry/trunk/src/megrok/quarry/components.py 2007-05-03 19:24:13 UTC (rev 75071)
@@ -16,58 +16,24 @@
pass
-class View(BrowserPage):
- interface.implements(interfaces.IGrokView)
+class ViewBase(object):
- def __init__(self, context, request):
- super(View, self).__init__(context, request)
- self.static = component.queryAdapter(
- self.request,
- interface.Interface,
- name=self.module_info.package_dotted_name
- )
-
-
- @property
- def response(self):
- return self.request.response
-
- def __call__(self):
- mapply(self.update, (), self.request)
- if self.request.response.getStatus() in (302, 303):
- # A redirect was triggered somewhere in update(). Don't
- # continue rendering the template or doing anything else.
- return
-
- template = getattr(self, 'template', None)
- if template is not None:
- return self._render_template()
- return mapply(self.render, (), self.request)
-
def _render_template(self):
namespace = self.template.pt_getContext()
namespace['request'] = self.request
namespace['view'] = self
namespace['context'] = self.context
- # XXX need to check whether we really want to put None here if missing
namespace['static'] = self.static
return self.template.pt_render(namespace)
-
- def __getitem__(self, key):
- # XXX give nice error message if template is None
- return self.template.macros[key]
- def application_obj(self):
+ def application_url(self):
obj = self.context
- while obj:
+ while obj is not None:
if isinstance(obj, grok.Application):
- return obj
+ return self.url(obj)
obj = obj.__parent__
raise ValueErrror("No application found.")
- def application_url(self):
- return self.url(self.application_obj())
-
def url(self, obj=None, name=None):
# if the first argument is a string, that's the name. There should
# be no second argument
@@ -90,11 +56,59 @@
def redirect(self, url):
return self.request.response.redirect(url)
+ @property
+ def response(self):
+ return self.request.response
+
+
+
+
+class View(BrowserPage, ViewBase):
+ interface.implements(interfaces.IGrokView)
+
+ def __init__(self, context, request):
+ super(View, self).__init__(context, request)
+ self.static = component.queryAdapter(
+ self.request,
+ interface.Interface,
+ name=self.module_info.package_dotted_name
+ )
+
+
+ def __call__(self):
+ mapply(self.update, (), self.request)
+ if self.request.response.getStatus() in (302, 303):
+ # A redirect was triggered somewhere in update(). Don't
+ # continue rendering the template or doing anything else.
+ return
+
+ template = getattr(self, 'template', None)
+ if template is not None:
+ return self._render_template()
+ return mapply(self.render, (), self.request)
+
def update(self):
pass
+
+ def render(self):
+ mapply(self.update, (), self.request)
+ if self.request.response.getStatus() in (302, 303):
+ # A redirect was triggered somewhere in update(). Don't
+ # continue rendering the template or doing anything else.
+ return
+
+ template = getattr(self, 'template', None)
+ if template is not None:
+ return self._render_template()
+
+ def __getitem__(self, key):
+ # XXX give nice error message if template is None
+ return self.template.macros[key]
-class ViewletManager(ViewletManagerBase):
+
+
+class ViewletManager(ViewletManagerBase, ViewBase):
""" A grok.View-like ViewletManager
"""
@@ -107,7 +121,11 @@
interface.Interface,
name=self.module_info.package_dotted_name
)
-
+
+ def update(self):
+ super(ViewletManager, self).update()
+
+
def render(self):
"""See zope.contentprovider.interfaces.IContentProvider"""
# Now render the view
@@ -116,49 +134,14 @@
return self._render_template()
else:
return u'\n'.join([viewlet.render() for viewlet in self.viewlets])
-
- @property
- def response(self):
- return self.request.response
- def _render_template(self):
- namespace = self.template.pt_getContext()
- namespace['request'] = self.request
- namespace['view'] = self
- namespace['viewlets'] = self.viewlets
- namespace['static'] = self.static
- namespace['context'] = self.context
- # XXX need to check whether we really want to put None here if missing
- return self.template.pt_render(namespace)
-
def sort(self, viewlets):
# sort by viewlet class name as default
return sorted(viewlets, lambda x,y: cmp(x[0], y[0]))
- def url(self, obj=None, name=None):
- # if the first argument is a string, that's the name. There should
- # be no second argument
- if isinstance(obj, basestring):
- if name is not None:
- raise TypeError(
- 'url() takes either obj argument, obj, string arguments, '
- 'or string argument')
- name = obj
- obj = None
- if name is None and obj is None:
- # create URL to view itself
- obj = self
- elif name is not None and obj is None:
- # create URL to view on context
- obj = self.context
- return util.url(self.request, obj, name)
- def redirect(self, url):
- return self.request.response.redirect(url)
-
-
-class Viewlet(ViewletBase):
+class Viewlet(ViewletBase, ViewBase):
""" A grok.View-like viewlet
"""
@@ -171,12 +154,9 @@
name=self.module_info.package_dotted_name
)
+ def update(self):
+ pass
- @property
- def response(self):
- return self.request.response
-
-
def render(self):
mapply(self.update, (), self.request)
if self.request.response.getStatus() in (302, 303):
@@ -188,42 +168,34 @@
if template is not None:
return self._render_template()
- def _render_template(self):
- namespace = self.template.pt_getContext()
- namespace['request'] = self.request
- namespace['view'] = self
- namespace['context'] = self.context
- # XXX need to check whether we really want to put None here if missing
- namespace['static'] = self.static
- return self.template.pt_render(namespace)
- def __getitem__(self, key):
- # XXX give nice error message if template is None
- return self.template.macros[key]
- def url(self, obj=None, name=None):
- # if the first argument is a string, that's the name. There should
- # be no second argument
- if isinstance(obj, basestring):
- if name is not None:
- raise TypeError(
- 'url() takes either obj argument, obj, string arguments, '
- 'or string argument')
- name = obj
- obj = None
+class ContentProvider(ViewBase):
- if name is None and obj is None:
- # create URL to view itself
- obj = self
- elif name is not None and obj is None:
- # create URL to view on context
- obj = self.context
- return util.url(self.request, obj, name)
+ def __init__(self, context, request, view):
+ self.__parent__ = view
+ self.context = context
+ self.request = request
+ self.static = component.queryAdapter(
+ self.request,
+ interface.Interface,
+ name=self.module_info.package_dotted_name
+ )
+ return self.request.response
- def redirect(self, url):
- return self.request.response.redirect(url)
-
def update(self):
pass
+ def render(self):
+ mapply(self.update, (), self.request)
+ if self.request.response.getStatus() in (302, 303):
+ # A redirect was triggered somewhere in update(). Don't
+ # continue rendering the template or doing anything else.
+ return
+ template = getattr(self, 'template', None)
+ if template is not None:
+ return self._render_template()
+
+
+
Modified: megrok.quarry/trunk/src/megrok/quarry/directive.py
===================================================================
--- megrok.quarry/trunk/src/megrok/quarry/directive.py 2007-05-03 19:20:37 UTC (rev 75070)
+++ megrok.quarry/trunk/src/megrok/quarry/directive.py 2007-05-03 19:24:13 UTC (rev 75071)
@@ -1,4 +1,4 @@
-from grok.directive import InterfaceOrClassDirective, ClassOrModuleDirectiveContext
+from grok.directive import InterfaceOrClassDirective, ClassOrModuleDirectiveContext, InterfaceDirective
from grok.directive import SingleTextDirective, ClassDirectiveContext
layer = InterfaceOrClassDirective('quarry.layer',
@@ -9,3 +9,5 @@
viewletmanager = InterfaceOrClassDirective('quarry.viewletmanager',
ClassDirectiveContext())
+talnamespace = InterfaceDirective('quarry.talnamespace',
+ ClassDirectiveContext())
Modified: megrok.quarry/trunk/src/megrok/quarry/meta.py
===================================================================
--- megrok.quarry/trunk/src/megrok/quarry/meta.py 2007-05-03 19:20:37 UTC (rev 75070)
+++ megrok.quarry/trunk/src/megrok/quarry/meta.py 2007-05-03 19:24:13 UTC (rev 75071)
@@ -14,7 +14,11 @@
from zope.dottedname.resolve import resolve
from zope import interface, component
import zope.component.interface
+import zope.interface
+from zope.contentprovider.interfaces import IContentProvider
+from zope.contentprovider.interfaces import ITALNamespaceData
+
class LayerGrokker(grok.ClassGrokker):
component_class = quarry.Layer
@@ -141,6 +145,114 @@
% (method.__name__, factory), factory)
+class ContentProviderGrokker(grok.ClassGrokker):
+ component_class = quarry.ContentProvider
+
+
+ def register(self, context, name, factory, module_info, templates):
+
+
+ # transfer namespace data
+ namespace = util.class_annotation(factory, 'quarry.talnamespace',
+ None)
+
+ if namespace:
+ interface.classImplements(factory, namespace)
+ interface.directlyProvides(namespace, ITALNamespaceData)
+
+ layer = util.class_annotation(factory, 'quarry.layer',
+ None) or module_info.getAnnotation('quarry.layer',
+ None) or IDefaultBrowserLayer
+ factory_name = factory.__name__.lower()
+ view_name = util.class_annotation(factory, 'grok.name',
+ factory_name)
+ view_context = util.determine_class_context(factory, context) #grok.context
+
+ factory.module_info = module_info
+ factory_name = factory.__name__.lower()
+
+ if util.check_subclass(factory, components.GrokForm):
+ # setup form_fields from context class if we've encountered a form
+ if getattr(factory, 'form_fields', None) is None:
+ factory.form_fields = formlib.get_auto_fields(view_context)
+
+ if not getattr(factory.render, 'base_method', False):
+ raise GrokError(
+ "It is not allowed to specify a custom 'render' "
+ "method for form %r. Forms either use the default "
+ "template or a custom-supplied one." % factory,
+ factory)
+
+ # can't use grok.template
+ if util.class_annotation(factory, 'grok.template',
+ None):
+ raise GrokError(
+ "%s may not use grok.template, use quarry.template instead."
+ % factory.__name__, factory)
+
+ template_name = util.class_annotation(factory, 'quarry.template',
+ None)
+ if template_name is None:
+ template_name = factory_name
+
+ template = templates.get(template_name)
+
+
+ if factory_name != template_name:
+ # quarry.template is being used
+ if templates.get(factory_name):
+ raise GrokError("Multiple possible templates for view %r. It "
+ "uses quarry.template('%s'), but there is also "
+ "a template called '%s'."
+ % (factory, template_name, factory_name),
+ factory)
+ # no conflicts, lets try and load the template
+ # using quarry.template('with.dotted.name')
+ try:
+ factory.template = resolve(template_name)
+ # accept string and unicode objects, useful if .__doc__ is referenced
+ if isinstance(factory.template, (str, unicode)):
+ factory.template = grok.PageTemplate(factory.template)
+ except ImportError:
+ # verify this is a dotted name
+ if template_name.find('.') >=0:
+ raise GrokError(
+ "'%s' is not importable. Check the path and"
+ "be sure it's a grok.PageTemplate,"
+ "grok.PageTemplateFile, string, or unicode object"
+ % template_name, factory)
+
+ # support in-class imports template = grok.PageTemplateFile
+ factory_template = getattr(factory, 'template', None)
+
+ if template:
+ if (getattr(factory, 'render', None) and not
+ util.check_subclass(factory, components.GrokForm)):
+ # we do not accept render and template both for a view
+ # (unless it's a form, they happen to have render.
+ raise GrokError(
+ "Multiple possible ways to render view %r. "
+ "It has both a 'render' method as well as "
+ "an associated template." % factory, factory)
+
+ templates.markAssociated(template_name)
+ factory.template = template
+ elif factory_template:
+ pass
+ else:
+ if not getattr(factory, 'render', None):
+ # we do not accept a view without any way to render it
+ raise GrokError("View %r has no associated template or "
+ "'render' method." % factory, factory)
+
+
+ component.provideAdapter(factory,
+ adapts=(zope.interface.Interface, # TODO: Make configurable
+ layer, # TODO: Make configurable
+ view_context),
+ provides=IContentProvider,
+ name=view_name)
+
class ViewletManagerGrokker(grok.ClassGrokker):
component_class = quarry.ViewletManager
@@ -148,6 +260,15 @@
factory.module_info = module_info # to make /static available
factory_name = factory.__name__.lower()
+
+ # transfer namespace data
+ namespace = util.class_annotation(factory, 'quarry.talnamespace',
+ None)
+
+ if namespace:
+ interface.classImplements(factory, namespace)
+ interface.directlyProvides(namespace, ITALNamespaceData)
+
permissions = grok.util.class_annotation(factory, 'grok.require', [])
if not permissions:
More information about the Checkins
mailing list