Plone技术资料

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 4493|回复: 0

plone.directives.form学习

[复制链接]
发表于 2015-1-4 20:12:33 | 显示全部楼层 |阅读模式
plone.directives.form.form学习
代码:
  1. from inspect import ismethod

  2. import zope.interface
  3. import zope.component

  4. import zope.interface.interface

  5. from zope.component.zcml import handler

  6. import martian
  7. from martian.error import GrokError

  8. import grokcore.security
  9. import grokcore.view

  10. import five.grok

  11. from plone.z3cform import layout

  12. from plone.dexterity.interfaces import IDexterityFTI
  13. from plone.dexterity.browser import add, edit, view

  14. from zope.publisher.interfaces.browser import IBrowserRequest
  15. from zope.publisher.interfaces.browser import IDefaultBrowserLayer

  16. from App.class_init import InitializeClass

  17. from Products.CMFCore.interfaces import IFolderish

  18. from Products.Five.browser.metaconfigure import page

  19. try:
  20.     from AccessControl.security import protectClass, protectName
  21.     from AccessControl.security import CheckerPrivateId
  22.     protectClass, protectName, CheckerPrivateId  # pyflakes
  23. except ImportError:
  24.     from Products.Five.security import protectClass, protectName
  25.     from Products.Five.security import CheckerPrivateId

  26. TEMP_KEY = '__form_directive_values__'

  27. # Find out if we want to wrap forms
  28. from plone.directives.form.meta import DEFAULT_WRAP
  29. from plone.directives.form.form import wrap


  30. # Base classes

  31. class GrokkedDexterityForm(object):

  32.     # Emulate grokcore.view.View

  33.     def __init__(self, context, request):
  34.         super(GrokkedDexterityForm, self).__init__(context, request)

  35.         # Set the view __name__
  36.         self.__name__ = getattr(self, '__view_name__', None)

  37.         # Set up the view.static resource directory reference
  38.         if getattr(self, 'module_info', None) is not None:
  39.             self.static = zope.component.queryAdapter(
  40.                 self.request,
  41.                 zope.interface.Interface,
  42.                 name=self.module_info.package_dotted_name
  43.                 )
  44.         else:
  45.             self.static = None

  46.     def render(self):
  47.         # Render a grok-style template if we have one
  48.         if (
  49.             getattr(self, 'template') and
  50.             grokcore.view.interfaces.ITemplate.providedBy(self.template)
  51.         ):
  52.             return self._render_template()
  53.         else:
  54.             return super(GrokkedDexterityForm, self).render()
  55.     render.base_method = True

  56.     @property
  57.     def response(self):
  58.         return self.request.response

  59.     def _render_template(self):
  60.         return self.template.render(self)

  61.     def default_namespace(self):
  62.         namespace = {}
  63.         namespace['context'] = self.context
  64.         namespace['request'] = self.request
  65.         namespace['static'] = self.static
  66.         namespace['view'] = self
  67.         return namespace

  68.     def namespace(self):
  69.         return {}

  70.     def url(self, obj=None, name=None, data=None):
  71.         """Return string for the URL based on the obj and name. The data
  72.         argument is used to form a CGI query string.
  73.         """
  74.         if isinstance(obj, basestring):
  75.             if name is not None:
  76.                 raise TypeError(
  77.                     'url() takes either obj argument, obj, string arguments, '
  78.                     'or string argument')
  79.             name = obj
  80.             obj = None

  81.         if name is None and obj is None:
  82.             # create URL to view itself
  83.             obj = self
  84.         elif name is not None and obj is None:
  85.             # create URL to view on context
  86.             obj = self.context

  87.         if data is None:
  88.             data = {}
  89.         else:
  90.             if not isinstance(data, dict):
  91.                 raise TypeError('url() data argument must be a dict.')

  92.         return grokcore.view.util.url(self.request, obj, name, data=data)

  93.     def redirect(self, url):
  94.         return self.request.response.redirect(url)

  95.     # BBB: makes the form have the most important properties that were
  96.     # exposed by the wrapper view

  97.     @property
  98.     def form_instance(self):
  99.         return self

  100.     @property
  101.     def form(self):
  102.         return self.__class__


  103. class AddForm(GrokkedDexterityForm, add.DefaultAddForm):
  104.     """Base class for grokked add forms
  105.     """
  106.     martian.baseclass()

  107.     def __init__(self, context, request, ti=None):
  108.         super(AddForm, self).__init__(context, request)
  109.         if ti is not None:
  110.             self.ti = ti
  111.             self.portal_type = ti.getId()
  112.    
  113.     def __of__(self, context):
  114.         # compatibility with CMFCore which tries to wrap the add view
  115.         return self

  116.     def render(self):
  117.         if self._finishedAdd:
  118.             self.request.response.redirect(self.nextURL())
  119.             return ""
  120.         return super(AddForm, self).render()
  121.     render.base_method = True


  122. class EditForm(GrokkedDexterityForm, edit.DefaultEditForm):
  123.     """Base class for grokked edit forms
  124.     """
  125.     martian.baseclass()


  126. class DisplayForm(view.DefaultView, five.grok.View):
  127.     """Base class for grokked display forms
  128.     """
  129.     martian.baseclass()

  130.     def __init__(self, context, request):
  131.         view.DefaultView.__init__(self, context, request)
  132.         five.grok.View.__init__(self, context, request)

  133.     def render(self):
  134.         template = getattr(self, 'template', None)
  135.         if template is not None:
  136.             return self.template.render(self)
  137.         return zope.publisher.publish.mapply(self.render, (), self.request)
  138.     render.base_method = True


  139. class AddFormGrokker(martian.ClassGrokker):
  140.     martian.component(AddForm)

  141.     martian.directive(grokcore.view.layer, default=IDefaultBrowserLayer)
  142.     martian.directive(grokcore.component.name, default=None)
  143.     martian.directive(grokcore.security.require, name='permission',
  144.                       default='cmf.AddPortalContent')
  145.     martian.directive(wrap, default=None)

  146.     def grok(self, name, form, module_info, **kw):
  147.         # save the module info so that we can look for templates later
  148.         form.module_info = module_info
  149.         return super(AddFormGrokker, self).grok(name, form, module_info, **kw)

  150.     def execute(self, form, config, layer, name, permission, wrap):

  151.         if not name:
  152.             raise GrokError(u"No factory name specified for add form. "
  153.                             u"Use grok.name('my.factory').", form)

  154.         templates = form.module_info.getAnnotation('grok.templates', None)
  155.         if templates is not None:
  156.             config.action(
  157.                 discriminator=None,
  158.                 callable=self.checkTemplates,
  159.                 args=(templates, form.module_info, form)
  160.                 )

  161.         form.__view_name__ = name

  162.         # Unlike the other forms, we default to wrapping for backwards-
  163.         # compatibility with custom templates that assume wrapping.
  164.         if wrap is None:
  165.             wrap = True

  166.         if wrap:
  167.             new_class = layout.wrap_form(form, __wrapper_class=add.DefaultAddView)
  168.             new_class.__view_name__ = new_class.__name__ = name
  169.         else:
  170.             new_class = form

  171.         # Protect the class
  172.         config.action(
  173.             discriminator=('five:protectClass', new_class),
  174.             callable=protectClass,
  175.             args=(new_class, permission)
  176.             )

  177.         # Protect the __call__ attribute
  178.         config.action(
  179.             discriminator=('five:protectName', new_class, '__call__'),
  180.             callable=protectName,
  181.             args=(new_class, '__call__', permission)
  182.             )

  183.         # Make all other attributes private
  184.         for attr in dir(new_class):
  185.             if (not attr.startswith('_') and attr != '__call__'
  186.                 and ismethod(getattr(new_class, attr))):
  187.                 config.action(
  188.                     discriminator=('five:protectName', new_class, attr),
  189.                     callable=protectName,
  190.                     args=(new_class, attr, CheckerPrivateId)
  191.                     )

  192.         # Initialise the class
  193.         config.action(
  194.             discriminator=('five:initialize:class', new_class),
  195.             callable=InitializeClass,
  196.             args=(new_class,)
  197.             )

  198.         config.action(
  199.             discriminator=('dexterity:addView', IFolderish, name,
  200.                            IBrowserRequest, layer, IDexterityFTI),
  201.             callable=handler,
  202.             args=('registerAdapter',
  203.                   new_class, (IFolderish, layer, IDexterityFTI),
  204.                   zope.interface.Interface, name, config.info),
  205.             )

  206.         return True

  207.     def checkTemplates(self, templates, module_info, factory):

  208.         def has_render(factory):
  209.             render = getattr(factory, 'render', None)
  210.             base_method = getattr(render, 'base_method', False)
  211.             return render and not base_method

  212.         def has_no_render(factory):
  213.             # Unlike the view grokker, we are happy with the base class
  214.             # version
  215.             return getattr(factory, 'render', None) is None

  216.         templates.checkTemplates(module_info, factory, 'view',
  217.                                  has_render, has_no_render)


  218. class EditFormGrokker(martian.ClassGrokker):
  219.     martian.component(EditForm)

  220.     martian.directive(grokcore.component.context, default=None)
  221.     martian.directive(grokcore.view.layer, default=IDefaultBrowserLayer)
  222.     martian.directive(grokcore.component.name, default='edit')
  223.     martian.directive(grokcore.security.require, name='permission',
  224.                       default='cmf.ModifyPortalContent')
  225.     martian.directive(wrap, default=None)

  226.     def grok(self, name, form, module_info, **kw):
  227.         # save the module info so that we can look for templates later
  228.         form.module_info = module_info
  229.         return super(EditFormGrokker, self).grok(name, form, module_info, **kw)

  230.     def execute(self, form, config, context, layer, name, permission, wrap):

  231.         # Only grok if the context is an interface. We demand this so that the
  232.         # form is more re-usable in case of type customisation.
  233.         if not isinstance(context, zope.interface.interface.InterfaceClass):
  234.             return False

  235.         templates = form.module_info.getAnnotation('grok.templates', None)
  236.         if templates is not None:
  237.             config.action(
  238.                 discriminator=None,
  239.                 callable=self.checkTemplates,
  240.                 args=(templates, form.module_info, form)
  241.                 )

  242.         form.__view_name__ = name

  243.         if wrap is None:
  244.             wrap = DEFAULT_WRAP

  245.         # Only use the wrapper view if we are on Zope < 2.12
  246.         if wrap:
  247.             factory = layout.wrap_form(form)
  248.             factory.__view_name__ = name
  249.         else:
  250.             factory = form

  251.         page(
  252.                 config,
  253.                 name=name,
  254.                 permission=permission,
  255.                 for_=context,
  256.                 layer=layer,
  257.                 class_=factory
  258.             )

  259.         return True

  260.     def checkTemplates(self, templates, module_info, factory):

  261.         def has_render(factory):
  262.             render = getattr(factory, 'render', None)
  263.             base_method = getattr(render, 'base_method', False)
  264.             return render and not base_method

  265.         def has_no_render(factory):
  266.             # Unlike the view grokker, we are happy with the base class
  267.             # version
  268.             return getattr(factory, 'render', None) is None

  269.         templates.checkTemplates(module_info, factory, 'view',
  270.                                  has_render, has_no_render)

  271. __all__ = ('AddForm', 'EditForm', 'DisplayForm', )
复制代码



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|Plone技术资料 ( 湘ICP备14006519号-1 )

GMT+8, 2019-11-18 10:00 , Processed in 0.056963 second(s), 25 queries , Gzip On.

Powered by Plone! X3.4

© 2001-2019 Plone.org.

快速回复 返回顶部 返回列表