use dojo.Dialog for entry forms; set up INote resource as first example (and start to clean-up retrieving views for resources)

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1352 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2006-09-19 21:16:26 +00:00
parent d5532f1c72
commit 980114d649
16 changed files with 341 additions and 44 deletions

View file

@ -18,6 +18,7 @@ with lower-level aspects like type or state management.
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown >>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
>>> site = placefulSetUp(True) >>> site = placefulSetUp(True)
>>> from zope import component
>>> from zope.app import zapi >>> from zope.app import zapi
>>> from zope.app.tests import ztapi >>> from zope.app.tests import ztapi
>>> from zope.interface import Interface >>> from zope.interface import Interface
@ -122,7 +123,7 @@ type manager.
>>> from cybertools.typology.interfaces import ITypeManager >>> from cybertools.typology.interfaces import ITypeManager
>>> from loops.interfaces import ILoopsObject >>> from loops.interfaces import ILoopsObject
>>> from loops.type import LoopsTypeManager >>> from loops.type import LoopsTypeManager, LoopsType
>>> ztapi.provideAdapter(ILoopsObject, ITypeManager, LoopsTypeManager) >>> ztapi.provideAdapter(ILoopsObject, ITypeManager, LoopsTypeManager)
>>> from loops.concept import ConceptTypeSourceList >>> from loops.concept import ConceptTypeSourceList
@ -545,6 +546,8 @@ and of a lot of other stuff needed for the rendering machine.
... with=(IBrowserRequest,)) ... with=(IBrowserRequest,))
>>> m112.target = doc1 >>> m112.target = doc1
>>> component.provideAdapter(LoopsType)
>>> view = NodeView(m112, TestRequest()) >>> view = NodeView(m112, TestRequest())
>>> view.renderTarget() >>> view.renderTarget()
u'' u''

View file

@ -42,6 +42,7 @@ from cybertools.browser.view import GenericView
from cybertools.relation.interfaces import IRelationRegistry from cybertools.relation.interfaces import IRelationRegistry
from cybertools.typology.interfaces import IType, ITypeManager from cybertools.typology.interfaces import IType, ITypeManager
from loops.interfaces import IView from loops.interfaces import IView
from loops.type import ITypeConcept
from loops import util from loops import util
from loops.util import _ from loops.util import _
@ -135,18 +136,39 @@ class BaseView(GenericView):
def value(self): def value(self):
return self.context return self.context
@Lazy
def type(self):
return IType(self.context)
@Lazy
def typeProvider(self):
type = self.type
if type is not None:
return type.typeProvider
@Lazy
def typeInterface(self):
provider = self.typeProvider
if provider is not None:
tc = ITypeConcept(provider)
return tc.typeInterface
@Lazy
def typeAdapter(self):
ifc = self.typeInterface
if ifc is not None:
return ifc(self.context)
@Lazy @Lazy
def typeTitle(self): def typeTitle(self):
type = IType(self.context) type = self.type
return type is not None and type.title or None return type is not None and type.title or None
@Lazy @Lazy
def typeUrl(self): def typeUrl(self):
type = IType(self.context) provider = self.typeProvider
if type is not None: if provider is not None:
provider = type.typeProvider return zapi.absoluteURL(provider, self.request)
if provider is not None:
return zapi.absoluteURL(provider, self.request)
return None return None
def viewIterator(self, objs): def viewIterator(self, objs):
@ -161,6 +183,12 @@ class BaseView(GenericView):
for t in ITypeManager(self.context).types]) for t in ITypeManager(self.context).types])
+ [('loops:*', 'Any')]) + [('loops:*', 'Any')])
def conceptTypesForSearch(self):
general = [('loops:concept:*', 'Any Concept'),]
return util.KeywordVocabulary(general + sorted([(t.tokenForSearch, t.title)
for t in ITypeManager(self.context).types
if 'concept' in t.qualifiers]))
@Lazy @Lazy
def uniqueId(self): def uniqueId(self):
return zapi.getUtility(IRelationRegistry).getUniqueIdForObject(self.context) return zapi.getUtility(IRelationRegistry).getUniqueIdForObject(self.context)

View file

@ -324,6 +324,15 @@
permission="zope.View" permission="zope.View"
/> />
<zope:adapter
name="note.html"
for="loops.interfaces.IResource
zope.publisher.interfaces.browser.IBrowserRequest"
provides="zope.interface.Interface"
factory="loops.browser.resource.NoteView"
permission="zope.View"
/>
<!-- media asset --> <!-- media asset -->
<!--<editform <!--<editform
@ -548,6 +557,15 @@
permission="zope.View" permission="zope.View"
/> />
<!-- forms (end-user view) -->
<page
name="create_object.html"
for="loops.interfaces.INode"
class="loops.browser.node.CreateObject"
permission="zope.ManageContent"
/>
<!-- inner HTML views --> <!-- inner HTML views -->
<page <page

70
browser/form_macros.pt Normal file
View file

@ -0,0 +1,70 @@
<metal:block define-macro="create">
<div>
<form method="get">
<input type="hidden" name="form.action" value="create"
tal:attributes="value view/form_action" />
<table cellpadding="3" class="form">
<tr>
<th colspan="4">
<span tal:replace="view/title"
i18n:translate="">Create Information Object</span>
</th>
</tr>
<tr tal:repeat="widget view/widgets">
<td class="label"
tal:define="hint widget/hint">
<label tal:attributes="for widget/name">
<span class="required" tal:condition="widget/required"
>*</span><span i18n:translate=""
tal:content="widget/label">label</span>
</label>
</td>
<td class="field" colspan="3"
tal:define="hint widget/hint">
<div class="widget" tal:content="structure widget">
<input type="text" />
</div>
<div class="error"
tal:condition="widget/error">
<span tal:replace="structure widget/error">error</span>
</div>
</td>
</tr>
<tr>
<td colspan="4" class="headline">Assign Concept(s)</td>
</tr>
<tr>
<td><label for="dlg.create.search.type">Type:</label></td>
<td>
<select name="dlg.create.search.type" id="dlg.create.search.type"
tal:attributes="onChange
string:setConceptTypeForComboBox(
'dlg.create.search.type', 'dlg.create.search.text')">
<tal:types repeat="type view/conceptTypesForSearch">
<option value="loops:*"
i18n:translate=""
tal:attributes="value type/token"
tal:content="type/title">Topic</option>
</tal:types>
</select>&nbsp;&nbsp;
</td>
<td><label for="dlg.create.search.text">Search text:</label></td>
<td>
<input dojoType="comboBox" mode="remote" autoComplete="False"
name="dlg.create.search.text" id="dlg.create.search.text"
tal:attributes="dataUrl
string:${context/@@absolute_url}/listConceptsForComboBox.js?searchString=%{searchString}&searchType=" />
</td>
</tr>
<tr>
<td colspan="4">
<input type="button" value="Cancel"
onclick="createObjectDlg.hide()">
<input type="submit" value="Save"
onclick="createObjectDlg.hide()">
</td>
</tr>
</table>
</form>
</div>
</metal:block>

View file

@ -84,3 +84,34 @@ div.image {
font-weight: bold; font-weight: bold;
} }
/* dojo stuff */
.dojoComboBox {
width: 200px;
}
.dojoDialog {
background: #eee;
border: 1px solid #999;
-moz-border-radius: 5px;
padding: 4px;
}
.dojoDialog th {
font-size: 120%;
padding: 0 5px 8px 5px;
}
.dojoDialog .headline {
font-weight: bold;
}
.dojoDialog input.text {
width: 100%;
margin-right: 10px;
}
.dojoDialog input.submit {
font-weight: bold;
}

View file

@ -13,9 +13,9 @@ function focusOpener() {
} }
} }
function listConceptsForComboBox() { /*function listConceptsForComboBox() {
return [['Zope', 'zope'], ] return [['Zope', 'zope'], ]
} }*/
function submitReplacing(targetId, formId, actionUrl) { function submitReplacing(targetId, formId, actionUrl) {
dojo.io.updateNode(targetId, { dojo.io.updateNode(targetId, {
@ -27,17 +27,21 @@ function submitReplacing(targetId, formId, actionUrl) {
} }
function inlineEdit(id, saveUrl) { function inlineEdit(id, saveUrl) {
var iconNode = dojo.byId("inlineedit_icon"); //dojo.require('dojo.widget.Editor');
iconNode.style.visibility = "hidden"; var iconNode = dojo.byId('inlineedit_icon');
var editor = dojo.widget.fromScript("Editor", iconNode.style.visibility = 'hidden';
{items: ["save", "|", "formatblock", "|", var editor = dojo.widget.fromScript('Editor',
"insertunorderedlist", "insertorderedlist", "|", {items: ['save', '|', 'formatblock', '|',
"bold", "italic", "|", "createLink", "insertimage"], 'insertunorderedlist', 'insertorderedlist', '|',
'bold', 'italic', '|', 'createLink', 'insertimage'],
saveUrl: saveUrl, saveUrl: saveUrl,
closeOnSave: true, closeOnSave: true,
onSave: function(){ htmlEditing: true,
onSave: function() {
this.disableToolbar(true); this.disableToolbar(true);
iconNode.style.visibility = "visible";} iconNode.style.visibility = 'visible';
//window.location.reload();
}
}, dojo.byId(id)); }, dojo.byId(id));
return false; return false;
} }
@ -50,3 +54,19 @@ function setConceptTypeForComboBox(typeId, cbId) {
dp.searchUrl = newUrl; dp.searchUrl = newUrl;
} }
var createObjectDlg = false;
function createObjectDialog() {
//createObjectDlg = dojo.widget.byId('createObject');
//createObjectDlg = false;
dojo.require('dojo.widget.Dialog');
dojo.require('dojo.widget.ComboBox');
if (!createObjectDlg) {
createObjectDlg = dojo.widget.fromScript('Dialog',
{bgColor: 'white', bgOpacity: 0.5, toggle: 'fade', toggleDuration: 250,
executeScripts: true,
href: 'create_object.html'
}, dojo.byId('createObject'));
}
createObjectDlg.show();
}

View file

@ -22,7 +22,7 @@ View class for Node objects.
$Id$ $Id$
""" """
from zope import component, interface from zope import component, interface, schema
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope.app import zapi from zope.app import zapi
from zope.app.annotation.interfaces import IAnnotations from zope.app.annotation.interfaces import IAnnotations
@ -34,6 +34,7 @@ from zope.app.pagetemplate import ViewPageTemplateFile
from zope.app.security.interfaces import IUnauthenticatedPrincipal from zope.app.security.interfaces import IUnauthenticatedPrincipal
from zope.dottedname.resolve import resolve from zope.dottedname.resolve import resolve
from zope.event import notify from zope.event import notify
from zope.formlib.form import Form, FormFields
from zope.formlib.namedtemplate import NamedTemplate from zope.formlib.namedtemplate import NamedTemplate
from zope.proxy import removeAllProxies from zope.proxy import removeAllProxies
from zope.security import canAccess, canWrite from zope.security import canAccess, canWrite
@ -50,6 +51,7 @@ from loops.interfaces import IConcept, IResource, IDocument, IMediaAsset, INode
from loops.interfaces import IViewConfiguratorSchema from loops.interfaces import IViewConfiguratorSchema
from loops.resource import MediaAsset from loops.resource import MediaAsset
from loops import util from loops import util
from loops.util import _
from loops.browser.common import BaseView from loops.browser.common import BaseView
from loops.browser.concept import ConceptView from loops.browser.concept import ConceptView
@ -70,16 +72,16 @@ class NodeView(BaseView):
resourceName='loops.css', media='all') resourceName='loops.css', media='all')
cm.register('js', 'loops.js', resourceName='loops.js') cm.register('js', 'loops.js', resourceName='loops.js')
cm.register('portlet_left', 'navigation', title='Navigation', cm.register('portlet_left', 'navigation', title='Navigation',
subMacro=self.template.macros['menu']) subMacro=self.template.macros['menu'])
if not IUnauthenticatedPrincipal.providedBy(self.request.principal): if not IUnauthenticatedPrincipal.providedBy(self.request.principal):
cm.register('portlet_right', 'clipboard', title='Clipboard', cm.register('portlet_right', 'clipboard', title='Clipboard',
subMacro=self.template.macros['clipboard']) subMacro=self.template.macros['clipboard'])
# this belongs to loops.organize; how to register portlets # this belongs to loops.organize; how to register portlets
# from sub- (other) packages? # from sub- (other) packages?
# see controller / configurator: use multiple configurators; # see controller / configurator: use multiple configurators;
# register additional configurators (adapters) from within package. # register additional configurators (adapters) from within package.
cm.register('portlet_right', 'worklist', title='Worklist', cm.register('portlet_right', 'actions', title='Actions',
subMacro=self.template.macros['worklist']) subMacro=self.template.macros['actions'])
@Lazy @Lazy
def view(self): def view(self):
@ -156,6 +158,7 @@ class NodeView(BaseView):
def renderTarget(self): def renderTarget(self):
target = self.target target = self.target
#targetAdapter = target.typeAdapter
return target is not None and target.render() or u'' return target is not None and target.render() or u''
@Lazy @Lazy
@ -164,9 +167,10 @@ class NodeView(BaseView):
@Lazy @Lazy
def bodyMacro(self): def bodyMacro(self):
# TODO: replace by: return self.target.macroName # TODO: replace by something like: return self.target.macroName
target = self.targetObject target = self.targetObject
if target is None or IDocument.providedBy(target): if (target is None or IDocument.providedBy(target)
or (IResource.providedBy(target) and target.contentType.startswith('text/'))):
return 'textbody' return 'textbody'
if IConcept.providedBy(target): if IConcept.providedBy(target):
return 'conceptbody' return 'conceptbody'
@ -295,6 +299,12 @@ class NodeView(BaseView):
cm.register('js-execute', jsCall, jsCall=jsCall) cm.register('js-execute', jsCall, jsCall=jsCall)
return 'return inlineEdit("%s", "%s/inline_save")' % (id, self.virtualTargetUrl) return 'return inlineEdit("%s", "%s/inline_save")' % (id, self.virtualTargetUrl)
def registerDojoDialog(self):
self.registerDojo()
cm = self.controller.macros
jsCall = 'dojo.require("dojo.widget.Dialog")'
cm.register('js-execute', jsCall, jsCall=jsCall)
# inner HTML views # inner HTML views
@ -314,10 +324,43 @@ class InlineEdit(NodeView):
def save(self): def save(self):
target = self.virtualTargetObject target = self.virtualTargetObject
target.data = self.request.form['editorContent'] data = self.request.form['editorContent']
if type(data) != unicode:
try:
data = data.decode('ISO-8859-15') # IE hack
except UnicodeDecodeError:
print 'loops.browser.node.InlineEdit.save():', data
return
# data = data.decode('UTF-8')
target.data = data
notify(ObjectModifiedEvent(target, Attributes(IResource, 'data'))) notify(ObjectModifiedEvent(target, Attributes(IResource, 'data')))
class CreateObject(NodeView, Form):
template = ViewPageTemplateFile('form_macros.pt')
@property
def macro(self): return self.template.macros['create']
form_fields = FormFields(
schema.TextLine(__name__='title', title=_(u'Title')),
schema.Text(__name__='body', title=_(u'Body Text')),
schema.TextLine(__name__='linkUrl', title=_(u'Link'), required=False),
)
title = _(u'Enter Note')
form_action = 'create_note'
def __init__(self, context, request):
super(CreateObject, self).__init__(context, request)
self.setUpWidgets()
self.widgets['body'].height = 3
def __call__(self):
return innerHtml(self)
# special (named) views for nodes # special (named) views for nodes
class SpecialNodeView(NodeView): class SpecialNodeView(NodeView):

View file

@ -194,12 +194,20 @@
<!-- portlets --> <!-- portlets -->
<metal:actions define-macro="clipboard"> <metal:actions define-macro="clipboard">
<div class="menu-2">loops Development</div> <div class="menu-2">loops Development</div>
</metal:actions> </metal:actions>
<metal:actions define-macro="worklist"> <metal:actions define-macro="actions">
<div class="menu-2">Create Resource...</div> <div class="menu-2"
tal:define="dummy view/registerDojo">
<a href="#"
onclick="createObjectDialog(); return false;">
Create Resource...
</a>
<span id="createObject">
</span>
</div>
</metal:actions> </metal:actions>

View file

@ -23,6 +23,7 @@ $Id$
""" """
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope import component
from zope.app import zapi from zope.app import zapi
from zope.app.catalog.interfaces import ICatalog from zope.app.catalog.interfaces import ICatalog
from zope.app.dublincore.interfaces import ICMFDublinCore from zope.app.dublincore.interfaces import ICMFDublinCore
@ -39,6 +40,7 @@ from loops.interfaces import IBaseResource, IDocument, IMediaAsset
from loops.browser.common import EditForm, BaseView from loops.browser.common import EditForm, BaseView
from loops.browser.concept import ConceptRelationView, ConceptConfigureView from loops.browser.concept import ConceptRelationView, ConceptConfigureView
from loops.browser.node import NodeView from loops.browser.node import NodeView
from loops.interfaces import ITypeConcept
renderingFactories = { renderingFactories = {
'text/plain': 'zope.source.plaintext', 'text/plain': 'zope.source.plaintext',
@ -60,7 +62,8 @@ class ResourceEditForm(EditForm):
fields = FormFields(IBaseResource) fields = FormFields(IBaseResource)
typeInterface = self.typeInterface typeInterface = self.typeInterface
if typeInterface is not None: if typeInterface is not None:
fields = FormFields(fields, typeInterface) omit = [f for f in typeInterface if f in IBaseResource]
fields = FormFields(fields.omit(*omit), typeInterface)
return fields return fields
@ -94,6 +97,20 @@ class ResourceView(BaseView):
subMacro=self.template.macros['related'], subMacro=self.template.macros['related'],
position=0, info=self) position=0, info=self)
@Lazy
def view(self):
context = self.context
tp = IType(context).typeProvider
if tp:
viewName = ITypeConcept(tp).viewName
if viewName:
return component.queryMultiAdapter((context, self.request),
name=viewName)
if context.contentType.startswith('text/'):
# TODO: This should be controlled by resourceType
return DocumentView(context, self.request)
return self
def show(self): def show(self):
data = self.context.data data = self.context.data
response = self.request.response response = self.request.response
@ -173,6 +190,9 @@ class DocumentView(ResourceView):
def macro(self): def macro(self):
return ResourceView.template.macros['render'] return ResourceView.template.macros['render']
@Lazy
def view(self): return self
def render(self): def render(self):
""" Return the rendered content (data) of the context object. """ Return the rendered content (data) of the context object.
""" """
@ -189,3 +209,16 @@ class DocumentView(ResourceView):
return (self.inlineEditingActive return (self.inlineEditingActive
and self.context.contentType == 'text/html' and self.context.contentType == 'text/html'
and canWrite(self.context, 'data')) and canWrite(self.context, 'data'))
class NoteView(DocumentView):
@property
def macro(self):
return ResourceView.template.macros['render_note']
@property
def linkUrl(self):
ad = self.typeAdapter
return ad and ad.linkUrl or ''

View file

@ -17,6 +17,16 @@
</metal:block> </metal:block>
<metal:block define-macro="render_note">
<metal:render use-macro="item/template/macros/render" />
<div class="content-1" id="1.link">
<a href="."
tal:attributes="href item/linkUrl"
tal:condition="item/linkUrl">more...</a>
</div>
</metal:block>
<metal:block define-macro="image"> <metal:block define-macro="image">
<div tal:attributes="ondblclick python: item.openEditWindow('edit.html')"> <div tal:attributes="ondblclick python: item.openEditWindow('edit.html')">
<h3 tal:content="item/title">Title</h3> <h3 tal:content="item/title">Title</h3>

View file

@ -319,6 +319,14 @@
set_schema="loops.interfaces.IFile" /> set_schema="loops.interfaces.IFile" />
</class> </class>
<adapter factory="loops.resource.NoteAdapter" trusted="True" />
<class class="loops.resource.NoteAdapter">
<require permission="zope.View"
interface="loops.interfaces.INote" />
<require permission="zope.ManageContent"
set_schema="loops.interfaces.INote" />
</class>
<adapter factory="loops.setup.SetupManager" /> <adapter factory="loops.setup.SetupManager" />
<adapter factory="loops.external.NodesLoader" /> <adapter factory="loops.external.NodesLoader" />

View file

@ -532,7 +532,13 @@ class ITypeConcept(Interface):
source="loops.TypeInterfaceSource", source="loops.TypeInterfaceSource",
required=False) required=False)
# viewName = schema.TextLine() viewName = schema.TextLine(
title=_(u'View name'),
description=_(u'Name of a special view be used for presenting '
'objects of this type.'),
default=u'',
required=False)
# storage = schema.Choice() # storage = schema.Choice()
@ -554,13 +560,24 @@ class IImage(IResourceAdapter):
""" """
class ITextDocument(IResourceAdapter): class ITextDocument(IResourceAdapter, IDocumentSchema):
""" A resource containing some sort of plain text that may be rendered and """ A resource containing some sort of plain text that may be rendered and
edited without necessarily involving a special external application edited without necessarily involving a special external application
(like e.g. OpenOffice); typical content types are text/html, text/xml, (like e.g. OpenOffice); typical content types are text/html, text/xml,
text/restructured, etc. text/restructured, etc.
""" """
class INote(ITextDocument):
""" Typically a short piece of text; in addition a note may contain
a URL linking it to more information.
"""
linkUrl = schema.TextLine(
title=_(u'Link URL'),
description=_(u'An (optional) link associated with this note'),
default=u'',
required=False)
# view configurator stuff # view configurator stuff

View file

@ -32,8 +32,7 @@ from zope.security.proxy import removeSecurityProxy
from cybertools.organize.interfaces import IPerson as IBasePerson from cybertools.organize.interfaces import IPerson as IBasePerson
from loops.organize.util import getPrincipalFolder, authPluginId from loops.organize.util import getPrincipalFolder, authPluginId
from loops.util import _
_ = MessageFactory('zope')
ANNOTATION_KEY = 'loops.organize.person' ANNOTATION_KEY = 'loops.organize.person'

View file

@ -45,7 +45,7 @@ from cybertools.relation.interfaces import IRelatable
from cybertools.typology.interfaces import ITypeManager from cybertools.typology.interfaces import ITypeManager
from interfaces import IBaseResource, IResource from interfaces import IBaseResource, IResource
from interfaces import IFile from interfaces import IFile, INote
from interfaces import IDocument, IDocumentSchema, IDocumentView from interfaces import IDocument, IDocumentSchema, IDocumentView
from interfaces import IMediaAsset, IMediaAssetView from interfaces import IMediaAsset, IMediaAssetView
from interfaces import IResourceManager, IResourceManagerContained from interfaces import IResourceManager, IResourceManagerContained
@ -196,6 +196,16 @@ class FileAdapter(ResourceAdapterBase):
implements(IFile) implements(IFile)
class NoteAdapter(ResourceAdapterBase):
""" A type adapter for providing note functionality for resources.
"""
implements(INote)
_schemas = list(INote) + list(IBaseResource)
#contentType = u'text/restructured'
class DocumentWriteFileAdapter(object): class DocumentWriteFileAdapter(object):
implements(IWriteFile) implements(IWriteFile)

View file

@ -63,12 +63,6 @@ class Search(BaseView):
self.maxRowNum = n self.maxRowNum = n
return n return n
def conceptTypesForSearch(self):
general = [('loops:concept:*', 'Any Concept'),]
return util.KeywordVocabulary(general + sorted([(t.tokenForSearch, t.title)
for t in ITypeManager(self.context).types
if 'concept' in t.qualifiers]))
def initDojo(self): def initDojo(self):
self.registerDojo() self.registerDojo()
cm = self.controller.macros cm = self.controller.macros

11
type.py
View file

@ -33,7 +33,7 @@ from cybertools.typology.type import BaseType, TypeManager
from cybertools.typology.interfaces import ITypeManager from cybertools.typology.interfaces import ITypeManager
from loops.interfaces import ILoopsObject, IConcept, IResource from loops.interfaces import ILoopsObject, IConcept, IResource
from loops.interfaces import ITypeConcept from loops.interfaces import ITypeConcept
from loops.interfaces import IResourceAdapter, IFile, IImage, ITextDocument from loops.interfaces import IResourceAdapter, IFile, IImage, ITextDocument, INote
from loops.concept import Concept from loops.concept import Concept
from loops.resource import Resource, Document, MediaAsset from loops.resource import Resource, Document, MediaAsset
from loops.common import AdapterBase from loops.common import AdapterBase
@ -43,7 +43,7 @@ class LoopsType(BaseType):
adapts(ILoopsObject) adapts(ILoopsObject)
factoryMapping = dict(concept=Concept, resource=Resource) factoryMapping = dict(concept=Concept, resource=Resource, document=Document)
containerMapping = dict(concept='concepts', resource='resources') containerMapping = dict(concept='concepts', resource='resources')
@Lazy @Lazy
@ -83,6 +83,11 @@ class LoopsType(BaseType):
@Lazy @Lazy
def factory(self): def factory(self):
ti = self.typeInterface
#if ti is not None:
# fn = getattr(ti, 'factoryName', None)
# if fn:
# return self.factoryMapping.get(fn, Concept)
return self.factoryMapping.get(self.qualifiers[0], Concept) return self.factoryMapping.get(self.qualifiers[0], Concept)
@Lazy @Lazy
@ -241,7 +246,7 @@ class TypeInterfaceSourceList(object):
implements(schema.interfaces.IIterableSource) implements(schema.interfaces.IIterableSource)
typeInterfaces = (ITypeConcept, IFile, ITextDocument) typeInterfaces = (ITypeConcept, IFile, ITextDocument, INote)
def __init__(self, context): def __init__(self, context):
self.context = context self.context = context