[Zope3-checkins] CVS: Zope3/src/zope/app/presentation - pagefolder.py:1.1 pagefolder.zcml:1.1 zpt.py:1.1 zpt.zcml:1.1 configure.zcml:1.3 presentation.py:1.3 tests.py:NONE

Stephan Richter srichter at cosmos.phy.tufts.edu
Thu Mar 11 05:19:07 EST 2004


Update of /cvs-repository/Zope3/src/zope/app/presentation
In directory cvs.zope.org:/tmp/cvs-serv8352/src/zope/app/presentation

Modified Files:
	configure.zcml presentation.py 
Added Files:
	pagefolder.py pagefolder.zcml zpt.py zpt.zcml 
Removed Files:
	tests.py 
Log Message:


Moved Page Folder and it Page Templates into zope.app.presentation.




=== Added File Zope3/src/zope/app/presentation/pagefolder.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Page Folders

Page folders support easy creation and registration of page views
using folders of templates.

$Id: pagefolder.py,v 1.1 2004/03/11 10:18:36 srichter Exp $
"""
from zope.interface import Interface, implements
from zope.schema import BytesLine, Bool, Field
from zope.app.component.interfacefield import InterfaceField
from zope.app.security.permission import PermissionField

from zope.app.container.btree import BTreeContainer
from zope.fssync.server.entryadapter import ObjectEntryAdapter, AttrMapping
from zope.app.interfaces.services.registration import ActiveStatus
from zope.app.interfaces.services.registration import IRegistrationManager
from zope.app.interfaces.services.registration \
     import IRegistrationManagerContainer
from zope.app.interfaces.services.registration import RegisteredStatus
from zope.app.interfaces.services.registration import UnregisteredStatus
from zope.app.interfaces.services.registration import IRegisterable
from zope.app.container.constraints import ItemTypePrecondition
from zope.app.presentation import PageRegistration
from zope.app.services.registration import RegistrationManagerContainer
from zope.app.container.constraints import ContainerTypesConstraint
from zpt import IZPTTemplate
from zope.app.traversing import getPath
from zope.proxy import removeAllProxies
from zope.publisher.interfaces.browser import IBrowserRequest

from zope.app.container.interfaces import IContainer
from zope.app.interfaces.file import IDirectoryFactory
from zope.fssync.server.interfaces import IObjectDirectory
from zope.app.interfaces.services.registration import \
       IRegistrationManagerContainer

class IPageFolderInfo(Interface):
    """Default registration information for page folders

    This information is used to configure the pages in the folder.
    """

    required = InterfaceField(
        title = u"For interface",
        description = u"The interface of the objects being viewed",
        required = True,
        )

    factoryName = BytesLine(
        title=u"The dotted name of a factory for creating the view",
        required = False,
        )

    layer = BytesLine(
        title = u"Layer",
        description = u"The skin layer the view is registered for",
        required = False,
        min_length = 1,
        default = "default",
        )

    permission = PermissionField(
        title=u"Permission",
        description=u"The permission required to use the view",
        required = True,
        )

    apply = Bool(
        title=u"Apply changes to existing pages",
        required = True,
        )

class IPageFolder(IPageFolderInfo, IContainer, IRegistrationManagerContainer):

    def applyDefaults(self):
        """Apply the default configuration to the already-registered pages. 
        """

    def __setitem__(name, template):
        """Add a template to the folder
        """

    __setitem__.precondition = ItemTypePrecondition(IZPTTemplate)
    
    __parent__ = Field(
        constraint = ContainerTypesConstraint(IRegistrationManagerContainer))


class PageFolder(RegistrationManagerContainer, BTreeContainer):

    implements(IPageFolder)

    requestType = IBrowserRequest
    layer = "default"
    description = ''
    title = ''
    factoryName = None
    attribute = None
    template = None
    apply = True

    ########################################################
    # The logic for managing registrations is handled by the
    # decorator class below.
    ########################################################


    def __setitem__(self, name, object):
        if (IRegistrationManager.providedBy(object) or
            IZPTTemplate.providedBy(object)):
            super(PageFolder, self).__setitem__(name, object)
        else:
            raise TypeError("Can only add templates", object)


        # If a template is added, we need to configure it too.
        if IZPTTemplate.providedBy(object):
            template = self[name]
            template = getPath(template)
            registration = PageRegistration(
                required=self.required,
                name=name,
                permission=self.permission,
                factoryName=self.factoryName,
                template=template,
                layer=self.layer,
                )

            registrations = self.getRegistrationManager()
            id = registrations.addRegistration(registration)
            registration = registrations[id]
            registration.status = ActiveStatus

    def applyDefaults(self):
        """Apply the default configuration to the already-registered pages.
        """

        rm = self.getRegistrationManager()
        for name in rm:
            registration = rm[name]
            status = registration.status
            if status == ActiveStatus:
                registration.status = RegisteredStatus
            registration.status = UnregisteredStatus

            # Cheat and set required and layer even though they're
            # read-only.  This is ok since the registration is now not
            # registered.

            registration.required = removeAllProxies(self.required)
            registration.factoryName = self.factoryName
            registration.layer = self.layer
            registration.permission = self.permission

            # Now restore the registration status

            registration.status = status


_attrNames = (
    'factoryName',
    'required',
    'layer',
    'permission',
    )

class PageFolderAdapter(ObjectEntryAdapter):
    """ObjectFile adapter for PageFolder objects."""

    implements(IObjectDirectory)

    def contents(self):
        return self.context.items()

    def extra(self):
        return AttrMapping(self.context, _attrNames)


class PageFolderFactory:

    implements(IDirectoryFactory)

    def __init__(self, context):
        self.context = context

    def __call__(self, name):
        return PageFolder()


# XXX Backward compatibility. This is needed to support old pickles.
ViewPackage = PageFolder
import sys
sys.modules['zope.app.services.viewpackage'
            ] = sys.modules['zope.app.presentation.pagefolder']


=== Added File Zope3/src/zope/app/presentation/pagefolder.zcml ===
<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:event="http://namespaces.zope.org/event"
    xmlns:fssync="http://namespaces.zope.org/fssync"
    >

<!-- Page Folder -->

<content class=".pagefolder.PageFolder">
  <factory
    id = "zope.app.presentation.pagefolder.PageFolder"
    title = "View Folder"
    />
  <require
      permission="zope.View"
      interface="zope.app.container.interfaces.IReadContainer" />
  <require
      permission="zope.ManageServices"
      interface="zope.app.container.interfaces.IWriteContainer
                 .pagefolder.IPageFolderInfo"
      set_schema=".pagefolder.IPageFolderInfo"
      attributes="getRegistrationManager applyDefaults" 
      />
  <implements
      interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
</content>

<adapter
  for=".pagefolder.IPageFolder"
  provides="zope.app.interfaces.file.IFileFactory"
  factory=".zpt.ZPTFactory"
  permission="zope.ManageServices"
  />

<adapter 
  for="zope.app.interfaces.services.folder.ISiteManagementFolder"
  provides="zope.app.interfaces.file.IDirectoryFactory"
  factory=".pagefolder.PageFolderFactory"
  permission="zope.ManageContent"
  />

<fssync:adapter
    class=".pagefolder.PageFolder"
    factory=".pagefolder.PageFolderAdapter"
    />

</configure>


=== Added File Zope3/src/zope/app/presentation/zpt.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: zpt.py,v 1.1 2004/03/11 10:18:36 srichter Exp $
"""
import re

from zope.security.proxy import ProxyFactory
from persistent import Persistent
from zope.interface import Interface, implements
from zope.schema import Text, BytesLine, Bool

from zope.app.container.contained import Contained
from zope.app.interfaces.services.registration import IRegisterable
from zope.app.index.interfaces.text import ISearchableText
from zope.fssync.server.entryadapter import ObjectEntryAdapter, AttrMapping
from zope.fssync.server.interfaces import IObjectFile
from zope.app.interfaces.file import IReadFile, IWriteFile, IFileFactory
from zope.app.pagetemplate.engine import AppPT
from zope.pagetemplate.pagetemplate import PageTemplate

class IZPTInfo(Interface):
    """ZPT Template configuration information
    """

    contentType = BytesLine(
        title=u'Content type of generated output',
        required=True,
        default='text/html'
        )

    source = Text(
        title=u"Source",
        description=u"""The source of the page template.""",
        required=True)

    expand = Bool(
        title=u"Expand macros",
        )

class IZPTTemplate(IZPTInfo, IRegisterable):
    """ZPT Templates for use in views"""

    def render(context, request, *args, **kw):
        """Render the page template.

        The context argument is bound to the top-level 'context'
        variable.  The request argument is bound to the top-level
        'request' variable. The positional arguments are bound to the
        'args' variable and the keyword arguments are bound to the
        'options' variable.

        """

class ZPTTemplate(AppPT, PageTemplate, Persistent, Contained):

    implements(IZPTTemplate)

    contentType = 'text/html'
    expand = False
    usage = u''

    source = property(
        # get
        lambda self: self.read(),
        # set
        lambda self, text: self.pt_edit(text.encode('utf-8'), self.contentType)
        )

    def pt_getContext(self, view, **_kw):
        # instance is a View component
        namespace = super(ZPTTemplate, self).pt_getContext(**_kw)
        namespace['view'] = view
        namespace['request'] = view.request
        namespace['context'] = view.context
        return namespace

    def render(self, view, *args, **keywords):

        if args:
            args = ProxyFactory(args)

        if self.usage:
            if "template_usage" not in keywords:
                kw = {'template_usage': self.usage}
                kw.update(keywords)
                keywords = kw

        kw = ProxyFactory(keywords)

        namespace = self.pt_getContext(view, args=args, options=kw)

        return self.pt_render(namespace)

# Adapter for ISearchableText

tag = re.compile(r"<[^>]+>")
class SearchableText:

    implements(ISearchableText)
    __used_for__ = IZPTTemplate

    def __init__(self, page):
        self.page = page

    def getSearchableText(self):
        text = self.page.source
        if isinstance(text, str):
            text = unicode(self.page.source, 'utf-8')
        # else:
        #   text was already Unicode, which happens, but unclear how it
        #   gets converted to Unicode since the ZPTPage stores UTF-8 as
        #   an 8-bit string.

        if self.page.contentType.startswith('text/html'):
            text = tag.sub('', text)

        return [text]

# Adapters for file-system emulation

class ReadFile:

    implements(IReadFile)

    def __init__(self, context):
        self.context = context

    def read(self):
        return self.context.source

    def size(self):
        return len(self.context.source)


class WriteFile:

    implements(IWriteFile)

    def __init__(self, context):
        self.context = context

    def write(self, data):
        self.context.source = data


class ZPTFactory:

    implements(IFileFactory)

    def __init__(self, context):
        self.context = context

    def __call__(self, name, content_type, data):
        r = ZPTTemplate()
        r.source = data
        return r


class ZPTPageAdapter(ObjectEntryAdapter):
    """ObjectFile adapter for ZPTTemplate objects."""

    implements(IObjectFile)

    def getBody(self):
        return self.context.source

    def setBody(self, data):
        # Convert the data to Unicode, since that's what ZPTTemplate
        # wants; it's normally read from a file so it'll be bytes.
        # XXX This will die if it's not ASCII.  Guess encoding???
        self.context.source = unicode(data)

    def extra(self):
        return AttrMapping(self.context, ('contentType', 'expand'))


=== Added File Zope3/src/zope/app/presentation/zpt.zcml ===
<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:event="http://namespaces.zope.org/event"
    xmlns:fssync="http://namespaces.zope.org/fssync"
    >

<!-- Page Templates  -->

<content class=".zpt.ZPTTemplate">
  <factory
      title="ZPT Template"
      description="Page Template"
      />
  <require
      permission="zope.View"
      attributes="__call__"
      />
  <require
      permission="zope.ManageServices"
      interface=".zpt.IZPTTemplate"
      set_schema=".zpt.IZPTTemplate"
      />
  <implements
      interface="zope.app.interfaces.annotation.IAttributeAnnotatable"
      />
</content>

<adapter
  for=".zpt.IZPTTemplate"
  provides="zope.app.interfaces.file.IReadFile"
  factory=".zpt.ReadFile"
  permission="zope.ManageServices"
  />

<adapter
  for=".zpt.IZPTTemplate"
  provides="zope.app.interfaces.file.IWriteFile"
  factory=".zpt.WriteFile"
  permission="zope.ManageServices"
  />

<!-- Filesystem synchronization support -->
<fssync:adapter
    class=".zpt.ZPTTemplate"
    factory=".zpt.ZPTPageAdapter"
    />

</configure>


=== Zope3/src/zope/app/presentation/configure.zcml 1.2 => 1.3 ===
--- Zope3/src/zope/app/presentation/configure.zcml:1.2	Tue Mar  9 08:36:33 2004
+++ Zope3/src/zope/app/presentation/configure.zcml	Thu Mar 11 05:18:36 2004
@@ -43,6 +43,9 @@
              alias="zope.app.services.presentation"
              />
 
+<include file="pagefolder.zcml" />
+<include file="zpt.zcml" />
+
 <include package=".browser" />
 
 </configure>


=== Zope3/src/zope/app/presentation/presentation.py 1.2 => 1.3 ===
--- Zope3/src/zope/app/presentation/presentation.py:1.2	Tue Mar  9 11:34:31 2004
+++ Zope3/src/zope/app/presentation/presentation.py	Thu Mar 11 05:18:36 2004
@@ -15,12 +15,12 @@
 
 $Id$
 """
-
+import persistent.dict
 from zope.app import zapi
 from zope.app.i18n import ZopeMessageIDFactory as _
 from zope.component.presentation import IDefaultViewName
 from zope.security.checker import NamesChecker, ProxyFactory
-import persistent.dict
+
 import zope.app.component.interfacefield
 import zope.app.component.nextservice
 import zope.app.container.contained
@@ -30,7 +30,6 @@
 import zope.app.services.field
 import zope.app.interfaces.services.interface
 import zope.app.adapter
-import zope.app.services.zpt
 import zope.component.interfaces
 import zope.configuration.exceptions
 import zope.interface

=== Removed File Zope3/src/zope/app/presentation/tests.py ===




More information about the Zope3-Checkins mailing list