Skip to content

Commit

Permalink
Add supermodel xml based configuration support for theme fragment tiles
Browse files Browse the repository at this point in the history
  • Loading branch information
datakurre committed Aug 25, 2015
1 parent 726eab8 commit d073229
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/collective/themefragments/configure.zcml
Expand Up @@ -29,6 +29,42 @@
zcml:condition="installed plone.tiles"
/>

<view
for=".tiles.FragmentTile"
factory=".tiles.FragmentTileAbsoluteURL"
type="zope.publisher.interfaces.http.IHTTPRequest"
permission="zope.Public"
provides="zope.traversing.browser.interfaces.IAbsoluteURL"
zcml:condition="installed plone.tiles"
/>

<adapter
for=".tiles.FragmentTile"
provides="plone.tiles.interfaces.ITileDataManager"
factory=".tiles.FragmentTileDataManager"
zcml:condition="installed plone.tiles"
/>

<adapter
for="zope.annotation.interfaces.IAnnotatable
zope.publisher.interfaces.browser.IDefaultBrowserLayer
plone.tiles.interfaces.ITileType"
provides="plone.app.tiles.interfaces.ITileAddView"
factory=".tiles.FragmentTileAddView"
name="collective.themefragments.fragment"
zcml:condition="installed plone.app.tiles"
/>

<adapter
for="zope.annotation.interfaces.IAnnotatable
zope.publisher.interfaces.browser.IDefaultBrowserLayer
plone.tiles.interfaces.ITileType"
provides="plone.app.tiles.interfaces.ITileEditView"
factory=".tiles.FragmentTileEditView"
name="collective.themefragments.fragment"
zcml:condition="installed plone.app.tiles"
/>

<!-- Profile -->
<genericsetup:registerProfile
name="default"
Expand All @@ -39,4 +75,5 @@
i18n:attributes="title description"
zcml:condition="installed plone.app.mosaic"
/>

</configure>
102 changes: 102 additions & 0 deletions src/collective/themefragments/tiles.py
Expand Up @@ -6,9 +6,20 @@
from plone.app.theming.interfaces import THEME_RESOURCE_NAME
from plone.app.theming.utils import getCurrentTheme
from plone.app.theming.utils import isThemeEnabled
from plone.app.tiles.browser.add import DefaultAddForm
from plone.app.tiles.browser.add import DefaultAddView
from plone.app.tiles.browser.edit import DefaultEditForm
from plone.app.tiles.browser.edit import DefaultEditView
from plone.memoize.view import memoize
from plone.resource.utils import queryResourceDirectory
from plone.supermodel import model
from plone.supermodel.parser import parse
from plone.tiles import Tile
from plone.tiles.absoluteurl import TransientTileAbsoluteURL
from plone.tiles.data import encode
from plone.tiles.data import decode
from plone.tiles.data import TransientTileDataManager
from plone.tiles.interfaces import ITileDataManager
from zope import schema
from zope.globalrequest import getRequest
from zope.i18nmessageid import MessageFactory
Expand Down Expand Up @@ -60,6 +71,34 @@ def themeFragments(context):
)


def getFragmentSchemata(name):
request = getRequest()
filename = (u'{0:s}.xml'.format(name)).encode('utf-8', 'ignore')

if not isThemeEnabled(request):
return SimpleVocabulary([])

currentTheme = getCurrentTheme()
if currentTheme is None:
return SimpleVocabulary([])

themeDirectory = queryResourceDirectory(THEME_RESOURCE_NAME, currentTheme)
if themeDirectory is None:
return SimpleVocabulary([])

if not themeDirectory.isDirectory(FRAGMENTS_DIRECTORY):
return SimpleVocabulary([])

if not themeDirectory[FRAGMENTS_DIRECTORY].isFile(filename):
return ()

handle = themeDirectory[FRAGMENTS_DIRECTORY].openFile(filename)
schemata = parse(handle).schemata.values()
for schema_ in schemata:
schema_.__name__ = schema_.__name__.encode('utf-8', 'ignore')
return schemata


class IFragmentTile(model.Schema):
fragment = schema.Choice(
title=_(u'Theme fragment'),
Expand All @@ -83,3 +122,66 @@ def update(self):
def __call__(self):
self.update()
return u'<html><body>{0:s}</body></html>'.format(self.index())


class FragmentTileAddForm(DefaultAddForm):
"""Fragment tile add form"""

@property
@memoize
def additionalSchemata(self):
fragment = self.request.form.get('fragment')
if fragment:
return getFragmentSchemata(fragment)
else:
return ()


class FragmentTileEditForm(DefaultEditForm):
"""Fragment tile edit form"""

@property
@memoize
def additionalSchemata(self):
fragment = self.request.form.get('fragment')
if fragment:
return getFragmentSchemata(fragment)
else:
return ()


class FragmentTileAddView(DefaultAddView):
form = FragmentTileAddForm


class FragmentTileEditView(DefaultEditView):
form = FragmentTileEditForm


class FragmentTileDataManager(TransientTileDataManager):
def get(self):
data = super(FragmentTileDataManager, self).get()
if data and self.key not in self.annotations and 'fragment' in data:
fragment = data['fragment']
for schema_ in getFragmentSchemata(fragment):
try:
print self.tile.request.form
data.update(decode(self.tile.request.form,
schema_, missing=True))
except (ValueError, UnicodeDecodeError,):
pass
return data


class FragmentTileAbsoluteURL(TransientTileAbsoluteURL):
def __str__(self):
url = super(FragmentTileAbsoluteURL, self).__str__()
data = ITileDataManager(self.context).get()
if data and 'fragment' in data:
fragment = data['fragment']
for schema_ in getFragmentSchemata(fragment):
if '?' in url:
url += '&' + encode(data, schema_)
else:
url += '?' + encode(data, schema_)
return url

3 comments on commit d073229

@datakurre
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@espenmn This adds support for supermodel XML based transient configuration for theme fragment tile. Just create a supermodel XML schema using Dexterity schema editor, export the XML and save it as foobar.xml next to foobar.pt. If the schema does not include any required fields, you may need to edit tile after adding to see the schema based fields. In template those field should be available as request/form/yourfieldname -variables.

@djay
Copy link
Member

@djay djay commented on d073229 Aug 26, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@datakurre
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds possible.

Please sign in to comment.