[Zope-CVS] CVS: Products/PageDesign - IClipboardSource.py:1.1.2.1 IClipboardTarget.py:1.1.2.1 IIndexedSlot.py:1.1.2.1 IPageElement.py:1.1.2.1 ISlot.py:1.1.2.1 ISlotProvider.py:1.1.2.1 Slot.py:1.1.2.1 SlotElementClipboardSource.py:1.1.2.1 SlotElementClipboardTarget.py:1.1.2.1 SlotElementTraverser.py:1.1.2.1 SlotNameCollector.py:1.1.2.1 SlotProvider.py:1.1.2.1 newnotes.txt:1.1.2.1

Shane Hathaway shane@cvs.zope.org
Sat, 3 Aug 2002 15:58:03 -0400


Update of /cvs-repository/Products/PageDesign
In directory cvs.zope.org:/tmp/cvs-serv6555

Added Files:
      Tag: page-redesign-branch
	IClipboardSource.py IClipboardTarget.py IIndexedSlot.py 
	IPageElement.py ISlot.py ISlotProvider.py Slot.py 
	SlotElementClipboardSource.py SlotElementClipboardTarget.py 
	SlotElementTraverser.py SlotNameCollector.py SlotProvider.py 
	newnotes.txt 
Log Message:
Oops, CVS didn't like the way I did the last checkin.  This corrects the
branch but not the trunk.


=== Added File Products/PageDesign/IClipboardSource.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.
# 
##############################################################################


from Interface import Interface

class IClipboardSource(Interface):

    def cut():
        """Removes this item from its container and returns the element."""

    #def copy():
    #    """Belongs here too but I don't need it yet. ;-)"""



=== Added File Products/PageDesign/IClipboardTarget.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.
# 
##############################################################################


from Interface import Interface

class IClipboardTarget(Interface):

    def paste(elements):
        """Adds the given elements to the container."""



=== Added File Products/PageDesign/IIndexedSlot.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.
# 
##############################################################################


from ISlot import ISlot

class IIndexedSlot(ISlot):

    def getElementCount():
        """
        """

    def getElement(index):
        """
        """

    def insertBefore(before_element, elements):
        """
        """

    def remove(element):
        """Removes an element and returns the element removed.
        """


=== Added File Products/PageDesign/IPageElement.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.
# 
##############################################################################

from Interface import Interface

class IPageElement (Interface):

    def render(design, editable, index):
        """Returns a string.
        """

    def getTitle():
        """Returns the title of this element.
        """

    def getEditURL():
        """Returns the URL for editing this element.

        Returns None or a blank string if it is not editable.
        """


=== Added File Products/PageDesign/ISlot.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.
# 
##############################################################################


from Interface import Interface


class ISlot (Interface):

    def single():
        """Renders as a single-element slot."""

    def multiple():
        """Renders as a multiple-element slot."""



=== Added File Products/PageDesign/ISlotProvider.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.
# 
##############################################################################

from Interface import Interface

class ISlotProvider (Interface):
    """The aq_parent should be the page design object."""

    def __getitem__(name):
        """Returns an object that implements ISlot.

        The slot might be created on the fly and not stored.
        """

    def _makeSlot(name):
        """Creates a slot if it doesn't exist.

        Returns the slot object.
        """

    def _isEditable():
        """
        """

    def _getLayeredProvider():
        """
        """


=== Added File Products/PageDesign/Slot.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.
# 
##############################################################################


from Persistence import Persistent
import Acquisition
from Acquisition import aq_inner, aq_parent
from OFS.Traversable import Traversable

from IIndexedSlot import IIndexedSlot
from IPageElement import IPageElement
from SlotElementClipboardTarget \
     import SlotElementClipboardTarget, SlotElementClipboardLastTarget


class Slot (Persistent, Acquisition.Explicit, Traversable):
    """Slot in a page design.
    """

    __implements__ = IIndexedSlot

    # Traversal helpers.
    elementSources = SlotElementTraverser('elementSources',
                                          SlotElementClipboardSource)
    elementTargets = SlotElementTraverser('elementTargets',
                                          SlotElementClipboardTarget)
    lastElementTarget = SlotElementClipboardLastTarget


    def __init__(self, id):
        self.id = id
        self.contents = ()


    def getId(self):
        return self.id


    def single(self):
        """Renders as a single-element slot."""
        allow_add = (not self.contents)
        res = self.renderToList(allow_add)
        if not res:
            layered_provider = aq_parent(aq_inner(self))._getLayeredProvider()
            if layered_provider is not None:
                # A higher layer is using the design holding this slot
                # as a template.
                # Since the slot is empty, let the higher layer supply it.
                return layered_provider[self.id].single()
        return ''.join(res)
            

    def multiple(self):
        """Renders as a multiple-element slot."""
        res = self.renderToList(1)
        layered_provider = aq_parent(aq_inner(self))._getLayeredProvider()
        if layered_provider is not None:
            # A higher layer is using the design holding this slot
            # as a template.
            # Allow the higher layer to supply text before and after.
            before = layered_provider[self.id + '_before'].multiple()
            after = layered_provider[self.id + '_after'].multiple()
            res = before + res + after
        return res


    def renderToList(self, allow_add):
        """Renders the items to a list."""
        sp = self.aq_parent
        design = sp.aq_parent
        editable = sp._isEditable()
        res = []
        phys_path = '/'.join(self.getPhysicalPath())

        for index in range(len(self.contents)):
            e = self.contents[index].__of__(self)
            if editable and allow_add:
                path = '%s/elementTargets/%d' % (phys_path, index)
                res.append(self.target_html % {
                    'slot_name': self.id,
                    'slot_index': index,
                    'path': path,
                    })

            text = e.render(design=design, editable=editable, index=index)
            if editable:
                path = '%s/elementSources/%d' % (phys_path, index)
                text = self.element_html % {
                    'title': e.getTitle(),
                    'path': path,
                    'edit_url': e.getEditURL(),
                    'text': text,
                    }
            res.append(text)

        if editable and allow_add:
            path = '%s/lastElementTarget' % phys_path
            res.append(self.target_html % {
                'slot_name': self.id,
                'slot_index': -1,
                'path': path,
                })

        return res


    def getElementCount(self):
        return len(self.contents)

    def getElement(self, index):
        return self.contents[index]

    def insertBefore(self, before_element, elements):
        # Verify none of the elements are already inserted.
        # An element can only be in one place at a time.
        for e in elements:
            if not IPageElement.isImplementedBy(e):
                raise ValueError, 'Not a page element'
            if e in self.contents:
                raise ValueError, 'Already inserted'
        if before_element is None:
            # append.
            self.contents = self.contents + tuple(elements)
        else:
            index = list(self.contents).index(before_element)
            self.contents = (self.contents[:index] + tuple(elements)
                             + self.contents[index:])

    def remove(self, element):
        lst = list(self.contents)
        lst.remove(element)
        self.contents = tuple(lst)



=== Added File Products/PageDesign/SlotElementClipboardSource.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.
# 
##############################################################################


import Acquisition
from Acquisition import aq_base, aq_inner, aq_parent
from IClipboardSource import IClipboardSource
from IIndexedSlot import IIndexedSlot


class SlotElementClipboardSource (Acquisition.Explicit):

    __implements__ = IClipboardSource

    def __init__(self, index):
        index = int(index)
        slot = aq_parent(aq_inner(self))
        assert IIndexedSlot.isImplementedBy(slot)
        self.element = slot.getElement(index)

    def cut(self):
        slot = aq_parent(aq_inner(self))
        assert IIndexedSlot.isImplementedBy(slot)
        element = aq_base(self.element)
        slot.remove(element)
        return element



=== Added File Products/PageDesign/SlotElementClipboardTarget.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.
# 
##############################################################################

import Acquisition
from Acquisition import aq_base, aq_inner, aq_parent
from IClipboardTarget import IClipboardTarget


class SlotElementClipboardTarget (Acquisition.Explicit):

    __implements__ = IClipboardTarget

    def __init__(self, index):
        index = int(index)
        slot = aq_parent(aq_inner(self))
        self.before_element = slot.getElement(index)

    def paste(self, elements):
        slot = aq_parent(aq_inner(self))
        slot.insertBefore(aq_base(self.before_element), elements)


class SlotElementClipboardLastTarget (Acquisition.Explicit):

    __implements__ = IClipboardTarget

    def paste(self, elements):
        slot = aq_parent(aq_inner(self))
        slot.insertBefore(None, elements)



=== Added File Products/PageDesign/SlotElementTraverser.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.
# 
##############################################################################

from OFS.Traversable import Traversable


class SlotElementTraverser (Acquisition.Explicit, Traversable):

    def __init__(self, id, item_factory):
        self.id = id
        self.item_factory = item_factory

    def getId(self):
        return self.id

    def __getitem__(self, name):
        return self.item_factory(name).__of__(self)



=== Added File Products/PageDesign/SlotNameCollector.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.
# 
##############################################################################


import Acquisition
from AccessControl import ClassSecurityInfo


class MockSlot:

    __implements__ = ISlot

    def single(self):
        return ''

    def multiple(self):
        return ()

mock_slot = MockSlot()


class SlotNameCollector (Acquisition.Explicit):

    __implements__ = ISlotProvider

    security = ClassSecurityInfo()
    security.setDefaultAccess('allow')

    def __init__(self):
        self._names = {}

    def __getitem__(self, name):
        self._names[name] = 1
        return mock_slot

    def _makeSlot(self, name):
        return self[name]

    def _getNames(self):
        return self._names

    def _isEditable(self):
        return 0

    def _getLayeredProvider():
        return None



=== Added File Products/PageDesign/SlotProvider.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.
# 
##############################################################################

import Acquisition
from AccessControl import ClassSecurityInfo
from OFS.Traversable import Traversable


class SlotProvider (Acquisition.Explicit, Traversable):

    __implements__ = ISlotProvider

    security = ClassSecurityInfo()
    security.setDefaultAccess('allow')

    id = 'slots'

    def __init__(self, editable=0, layered_provider=None):
        self._editable = editable
        self._layered_provider = layered_provider

    def getId(self):
        return self.id

    def _makeSlot(self, name):
        self.__getitem__(name, 1)

    def __getitem__(self, name, add=0):
        slots = self.aq_parent._slots
        slot = slots.get(name)
        if slot is None:
            slot = Slot()
            if add:
                slots[name] = slot
        return slot.__of__(self)

    def _isEditable(self):
        return self._editable

    def _getLayeredProvider():
        return self._layered_provider



=== Added File Products/PageDesign/newnotes.txt ===


element id:
  /folder/design/slots/top/elementSources/0
  /folder/palette/foo

target id:
  /folder/design/slots/bottom/elementTargets/2
  /folder/design/slots/bottom/elementTargets/3  (last)



Palettes let you add either references to existing items or new items
  (storing a reference to the local item).


You can use a page design as a page template macro:

  metal:use-macro="here/design/macro"

"macro" returns a tuple (generated on the fly) with pre-rendered content.


The bar above each page element contains:

Title
Pencil (for external editor)
Move up
Move down
Close (X)

Show the "+" sign for empty slots so it works in NS4.



Verify ahead of time:

- Does Konqueror support external JS?


Change UI:

- Don't make outlines when floating over an item.



Default palette lets you browse the tree?



Management Tabs:

  Design
  Local page elements
  (Folder stuff)