provide a special topic view for books that shows informative lists of children and text resources
This commit is contained in:
parent
8b4be98993
commit
8300cbf59b
10 changed files with 115 additions and 300 deletions
|
@ -40,6 +40,7 @@ from zope.traversing.browser import absoluteURL
|
|||
from cybertools.browser.action import actions
|
||||
from cybertools.meta.interfaces import IOptions
|
||||
from cybertools.typology.interfaces import IType
|
||||
from cybertools.util.html import extractFirstPart
|
||||
from cybertools.xedit.browser import ExternalEditorView, fromUnicode
|
||||
from loops.browser.action import DialogAction, TargetAction
|
||||
from loops.browser.common import EditForm, BaseView
|
||||
|
@ -252,6 +253,12 @@ class ResourceView(BaseView):
|
|||
#return util.toUnicode(wp.render(self.request))
|
||||
return super(ResourceView, self).renderText(text, contentType)
|
||||
|
||||
def renderShortText(self):
|
||||
return self.renderDescription() or self.createShortText(self.render())
|
||||
|
||||
def createShortText(self, text=None):
|
||||
return extractFirstPart(text or self.render())
|
||||
|
||||
def download(self):
|
||||
""" Force download, e.g. of a PDF file """
|
||||
return self.show(True)
|
||||
|
|
|
@ -355,7 +355,7 @@ Books, Sections, and Pages
|
|||
>>> importPath = os.path.join(os.path.dirname(__file__), 'book')
|
||||
>>> importData(loopsRoot, importPath, 'loops_book_de.dmp')
|
||||
|
||||
>>> from loops.compound.book.browser import PageLayout
|
||||
>>> from loops.compound.book.browser import BookView, SectionView, TopicView
|
||||
|
||||
|
||||
Fin de partie
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 2012 Helmut Merz helmutm@cy55.de
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
"""
|
||||
Implementation of book and book components
|
||||
"""
|
||||
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
from zope.interface import implements
|
||||
from zope.traversing.api import getName
|
||||
|
||||
from loops.compound.base import Compound
|
||||
from loops.compound.book.interfaces import IPage
|
||||
from loops.type import TypeInterfaceSourceList
|
||||
|
||||
|
||||
TypeInterfaceSourceList.typeInterfaces += (IPage,)
|
||||
|
||||
|
||||
class Page(Compound):
|
||||
|
||||
implements(IPage)
|
||||
|
||||
compoundPredicateNames = ['ispartof', 'standard']
|
||||
|
||||
@Lazy
|
||||
def documentType(self):
|
||||
return self.context.getConceptManager()['documenttype']
|
||||
|
||||
def getParts(self):
|
||||
result = {}
|
||||
for r in super(Page, self).getParts():
|
||||
for parent in r.getParents():
|
||||
if parent.conceptType == self.documentType:
|
||||
item = result.setdefault(getName(parent), [])
|
||||
item.append(r)
|
||||
return result
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2012 Helmut Merz helmutm@cy55.de
|
||||
# Copyright (c) 2013 Helmut Merz helmutm@cy55.de
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -45,10 +45,22 @@ class Base(object):
|
|||
def book_macros(self):
|
||||
return book_template.macros
|
||||
|
||||
@Lazy
|
||||
def documentTypeType(self):
|
||||
return self.conceptManager['documenttype']
|
||||
|
||||
@Lazy
|
||||
def sectionType(self):
|
||||
return self.conceptManager['section']
|
||||
|
||||
@Lazy
|
||||
def isPartOfPredicate(self):
|
||||
return self.conceptManager['ispartof']
|
||||
|
||||
@Lazy
|
||||
def showNavigation(self):
|
||||
return self.typeOptions.show_navigation
|
||||
|
||||
@Lazy
|
||||
def breadcrumbsParent(self):
|
||||
for p in self.context.getParents([self.isPartOfPredicate]):
|
||||
|
@ -82,34 +94,8 @@ class Base(object):
|
|||
if self.editable:
|
||||
return 'index.html'
|
||||
|
||||
|
||||
class BookOverview(Base, ConceptView):
|
||||
|
||||
@Lazy
|
||||
def macro(self):
|
||||
return book_template.macros['book']
|
||||
|
||||
|
||||
class SectionView(Base, ConceptView):
|
||||
|
||||
@Lazy
|
||||
def macro(self):
|
||||
return book_template.macros['section']
|
||||
|
||||
@Lazy
|
||||
def documentTypeType(self):
|
||||
return self.conceptManager['documenttype']
|
||||
|
||||
@Lazy
|
||||
def showNavigation(self):
|
||||
return self.typeOptions.show_navigation
|
||||
|
||||
@Lazy
|
||||
def sectionType(self):
|
||||
return self.conceptManager['section']
|
||||
|
||||
def getResources(self):
|
||||
relViews = super(SectionView, self).getResources()
|
||||
relViews = super(Base, self).getResources()
|
||||
return relViews
|
||||
|
||||
@Lazy
|
||||
|
@ -144,64 +130,23 @@ class SectionView(Base, ConceptView):
|
|||
yield c
|
||||
|
||||
|
||||
# layout parts - probably obsolete:
|
||||
class BookView(Base, ConceptView):
|
||||
|
||||
class PageLayout(Base, standard.Layout):
|
||||
|
||||
def getParts(self):
|
||||
parts = ['headline', 'keyquestions', 'quote', 'maintext',
|
||||
'story', 'tip', 'usecase']
|
||||
return self.getPartViews(parts)
|
||||
@Lazy
|
||||
def macro(self):
|
||||
return book_template.macros['book']
|
||||
|
||||
|
||||
class PagePart(object):
|
||||
class SectionView(Base, ConceptView):
|
||||
|
||||
template = book_template
|
||||
templateName = 'compound.book'
|
||||
macroName = 'text'
|
||||
partName = None # define in subclass
|
||||
gridPattern = ['span-4']
|
||||
|
||||
def getResources(self):
|
||||
result = []
|
||||
res = self.adapted.getParts().get(self.partName) or []
|
||||
for idx, r in enumerate(res):
|
||||
result.append(standard.ResourceView(
|
||||
r, self.request, parent=self, idx=idx))
|
||||
return result
|
||||
@Lazy
|
||||
def macro(self):
|
||||
return book_template.macros['section']
|
||||
|
||||
|
||||
class Headline(PagePart, standard.Header2):
|
||||
class TopicView(Base, ConceptView):
|
||||
|
||||
macroName = 'headline'
|
||||
@Lazy
|
||||
def macro(self):
|
||||
return book_template.macros['topic']
|
||||
|
||||
|
||||
class MainText(PagePart, standard.BasePart):
|
||||
|
||||
partName = 'maintext'
|
||||
|
||||
|
||||
class KeyQuestions(PagePart, standard.BasePart):
|
||||
|
||||
partName = 'keyquestions'
|
||||
|
||||
|
||||
class Story(PagePart, standard.BasePart):
|
||||
|
||||
partName = 'story'
|
||||
|
||||
|
||||
class Tip(PagePart, standard.BasePart):
|
||||
|
||||
partName = 'tip'
|
||||
|
||||
|
||||
class UseCase(PagePart, standard.BasePart):
|
||||
|
||||
partName = 'usecase'
|
||||
|
||||
|
||||
class Quote(PagePart, standard.BasePart):
|
||||
|
||||
partName = 'quote'
|
||||
gridPattern = ['span-2 last']
|
||||
|
|
|
@ -3,18 +3,6 @@
|
|||
xmlns:browser="http://namespaces.zope.org/browser"
|
||||
i18n_domain="loops">
|
||||
|
||||
<!-- type adapters -->
|
||||
|
||||
<zope:adapter factory="loops.compound.book.base.Page"
|
||||
provides="loops.compound.book.interfaces.IPage"
|
||||
trusted="True" />
|
||||
<zope:class class="loops.compound.book.base.Page">
|
||||
<require permission="zope.View"
|
||||
interface="loops.compound.book.interfaces.IPage" />
|
||||
<require permission="zope.ManageContent"
|
||||
set_schema="loops.compound.book.interfaces.IPage" />
|
||||
</zope:class>
|
||||
|
||||
<!-- Views -->
|
||||
|
||||
<zope:adapter
|
||||
|
@ -22,7 +10,7 @@
|
|||
for="loops.interfaces.IConcept
|
||||
loops.browser.skin.Lobo"
|
||||
provides="zope.interface.Interface"
|
||||
factory="loops.compound.book.browser.BookOverview"
|
||||
factory="loops.compound.book.browser.BookView"
|
||||
permission="zope.View" />
|
||||
|
||||
<zope:adapter
|
||||
|
@ -34,69 +22,11 @@
|
|||
permission="zope.View" />
|
||||
|
||||
<zope:adapter
|
||||
name="page_layout"
|
||||
name="book_topic_view"
|
||||
for="loops.interfaces.IConcept
|
||||
loops.browser.skin.Lobo"
|
||||
provides="zope.interface.Interface"
|
||||
factory="loops.compound.book.browser.PageLayout"
|
||||
permission="zope.View" />
|
||||
|
||||
<!-- parts -->
|
||||
|
||||
<zope:adapter
|
||||
name="lobo_headline"
|
||||
for="loops.compound.book.interfaces.IPage
|
||||
loops.browser.skin.Lobo"
|
||||
provides="zope.interface.Interface"
|
||||
factory="loops.compound.book.browser.Headline"
|
||||
permission="zope.View" />
|
||||
|
||||
<zope:adapter
|
||||
name="lobo_keyquestions"
|
||||
for="loops.compound.book.interfaces.IPage
|
||||
loops.browser.skin.Lobo"
|
||||
provides="zope.interface.Interface"
|
||||
factory="loops.compound.book.browser.KeyQuestions"
|
||||
permission="zope.View" />
|
||||
|
||||
<zope:adapter
|
||||
name="lobo_maintext"
|
||||
for="loops.compound.book.interfaces.IPage
|
||||
loops.browser.skin.Lobo"
|
||||
provides="zope.interface.Interface"
|
||||
factory="loops.compound.book.browser.MainText"
|
||||
permission="zope.View" />
|
||||
|
||||
<zope:adapter
|
||||
name="lobo_story"
|
||||
for="loops.compound.book.interfaces.IPage
|
||||
loops.browser.skin.Lobo"
|
||||
provides="zope.interface.Interface"
|
||||
factory="loops.compound.book.browser.Story"
|
||||
permission="zope.View" />
|
||||
|
||||
<zope:adapter
|
||||
name="lobo_tip"
|
||||
for="loops.compound.book.interfaces.IPage
|
||||
loops.browser.skin.Lobo"
|
||||
provides="zope.interface.Interface"
|
||||
factory="loops.compound.book.browser.Tip"
|
||||
permission="zope.View" />
|
||||
|
||||
<zope:adapter
|
||||
name="lobo_usecase"
|
||||
for="loops.compound.book.interfaces.IPage
|
||||
loops.browser.skin.Lobo"
|
||||
provides="zope.interface.Interface"
|
||||
factory="loops.compound.book.browser.UseCase"
|
||||
permission="zope.View" />
|
||||
|
||||
<zope:adapter
|
||||
name="lobo_quote"
|
||||
for="loops.compound.book.interfaces.IPage
|
||||
loops.browser.skin.Lobo"
|
||||
provides="zope.interface.Interface"
|
||||
factory="loops.compound.book.browser.Quote"
|
||||
factory="loops.compound.book.browser.TopicView"
|
||||
permission="zope.View" />
|
||||
|
||||
</configure>
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 2012 Helmut Merz helmutm@cy55.de
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
"""
|
||||
Books, sections, pages...
|
||||
"""
|
||||
|
||||
from zope.interface import Interface, Attribute
|
||||
from zope import interface, component, schema
|
||||
|
||||
from loops.compound.interfaces import ICompound
|
||||
from loops.util import _
|
||||
|
||||
|
||||
class IPage(ICompound):
|
||||
|
||||
pass
|
|
@ -4,11 +4,11 @@ type(u'documenttype', u'Dokumentenart', options=u'qualifier:assign',
|
|||
# book types
|
||||
type(u'book', u'Buch', viewName=u'book_overview', typeInterface=u'',
|
||||
options=u'action.portlet:create_subtype,edit_concept')
|
||||
#type(u'page', u'Seite', viewName=u'page_layout',
|
||||
# typeInterface=u'loops.compound.book.interfaces.IPage',
|
||||
# options=u'action.portlet:edit_concept')
|
||||
type(u'section', u'Kapitel', viewName=u'section_view', typeInterface=u'',
|
||||
options=u'action.portlet:create_subtype,edit_concept')
|
||||
#type(u'topic', u'Thema', viewName=u'book_topic_view',
|
||||
# typeInterface=u'loops.knowledge.interfaces.ITopic',
|
||||
# options=u'action.portlet:create_topic,edit_topic')
|
||||
|
||||
concept(u'system', u'System', u'domain')
|
||||
|
||||
|
@ -30,4 +30,3 @@ concept(u'usecase', u'Fallbeispiel', u'documenttype')
|
|||
# book structure
|
||||
child(u'book', u'section', u'issubtype', usePredicate=u'ispartof')
|
||||
child(u'section', u'section', u'issubtype', usePredicate=u'ispartof')
|
||||
#child(u'section', u'page', u'issubtype', usePredicate=u'ispartof')
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
|
||||
<metal:children define-macro="children">
|
||||
<div tal:repeat="related item/children">
|
||||
<div tal:repeat="related item/children"
|
||||
tal:define="level python:level + 1"
|
||||
tal:attributes="class string:content-$level">
|
||||
<h3>
|
||||
<a tal:attributes="href python:view.getUrlForTarget(related)"
|
||||
tal:content="related/title" /></h3>
|
||||
|
@ -37,71 +39,81 @@
|
|||
</metal:navigation>
|
||||
<metal:info use-macro="view/concept_macros/concepttitle" />
|
||||
<metal:info use-macro="item/book_macros/children" />
|
||||
<div tal:repeat="related item/textResources">
|
||||
<div class="span-4">
|
||||
<div tal:attributes="class python:
|
||||
item.getCssClassForResource(related)"
|
||||
tal:content="structure related/render" />
|
||||
</div>
|
||||
<div class="span-2 last" style="padding-top: 0.4em">
|
||||
<div class="object-actions" style="padding-top: 0"
|
||||
tal:define="url python:view.getUrlForTarget(related.context)"
|
||||
tal:condition="related/editable">
|
||||
<a i18n:translate="" i18n:attributes="title"
|
||||
title="Edit"
|
||||
tal:define="targetUid python:view.getUidForObject(related.context);
|
||||
url
|
||||
string:$url/edit_object.html?version=this&targetUid=$targetUid"
|
||||
tal:attributes="href url;
|
||||
onclick string:objectDialog('edit', '$url');;
|
||||
return false">
|
||||
<img tal:attributes="src
|
||||
string:$resourceBase/cybertools.icons/vcard_edit.png" /></a>
|
||||
<a i18n:translate="" i18n:attributes="title"
|
||||
title="Edit with external editor."
|
||||
xxtal:condition="related/xeditable"
|
||||
tal:condition="nothing"
|
||||
tal:attributes="href string:$url/external_edit?version=this">
|
||||
<img tal:attributes="src
|
||||
string:$resourceBase/cybertools.icons/application_edit.png" /></a>
|
||||
<metal:text define-macro="textresources">
|
||||
<div tal:repeat="related item/textResources">
|
||||
<div class="span-4">
|
||||
<div tal:attributes="class python:
|
||||
item.getCssClassForResource(related)"
|
||||
tal:content="structure related/render" />
|
||||
</div>
|
||||
<div tal:repeat="parent python:item.getParentsForResource(related)">
|
||||
<a tal:content="parent/title"
|
||||
tal:attributes="href python:view.getUrlForTarget(parent)" />
|
||||
</div>
|
||||
<div tal:repeat="image python:
|
||||
item.images[repeat['related'].index() + 1]">
|
||||
<a dojoType="dojox.image.Lightbox" group="mediasset"
|
||||
i18n:attributes="title"
|
||||
tal:attributes="href image/fullImageUrl;
|
||||
title image/title">
|
||||
<img tal:attributes="src image/src;
|
||||
alt image/title" /></a>
|
||||
<div class="span-2 last" style="padding-top: 0.4em">
|
||||
<div class="object-actions" style="padding-top: 0"
|
||||
tal:define="url python:view.getUrlForTarget(related.context)"
|
||||
tal:condition="related/editable">
|
||||
<a i18n:translate="" i18n:attributes="title"
|
||||
title="Edit"
|
||||
tal:define="targetUid python:view.getUidForObject(related.context);
|
||||
url
|
||||
string:$url/edit_object.html?version=this&targetUid=$targetUid"
|
||||
tal:attributes="href url;
|
||||
onclick string:objectDialog('edit', '$url');;
|
||||
return false">
|
||||
<img tal:attributes="src
|
||||
string:$resourceBase/cybertools.icons/vcard_edit.png" /></a>
|
||||
<a i18n:translate="" i18n:attributes="title"
|
||||
title="Edit with external editor."
|
||||
xxtal:condition="related/xeditable"
|
||||
tal:condition="nothing"
|
||||
tal:attributes="href string:$url/external_edit?version=this">
|
||||
<img tal:attributes="src
|
||||
string:$resourceBase/cybertools.icons/application_edit.png" /></a>
|
||||
</div>
|
||||
<div tal:repeat="parent python:item.getParentsForResource(related)">
|
||||
<a tal:content="parent/title"
|
||||
tal:attributes="href python:view.getUrlForTarget(parent)" />
|
||||
</div>
|
||||
<div tal:repeat="image python:
|
||||
item.images[repeat['related'].index() + 1]">
|
||||
<a dojoType="dojox.image.Lightbox" group="mediasset"
|
||||
i18n:attributes="title"
|
||||
tal:attributes="href image/fullImageUrl;
|
||||
title image/title">
|
||||
<img tal:attributes="src image/src;
|
||||
alt image/title" /></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</metal:text>
|
||||
<br style="clear: both" />
|
||||
<metal:navigation use-macro="item/book_macros/navigation" />
|
||||
<br />
|
||||
</metal:section>
|
||||
|
||||
|
||||
<!-- layout part macros - obsolete? -->
|
||||
|
||||
<metal:part define-macro="headline">
|
||||
<div tal:define="cell part/getView">
|
||||
<metal:headline use-macro="item/macros/headline" />
|
||||
</div>
|
||||
</metal:part>
|
||||
|
||||
<metal:part define-macro="text">
|
||||
<tal:cell repeat="cell part/getResources">
|
||||
<div tal:attributes="class cell/cssClass">
|
||||
<h3 tal:content="cell/title" />
|
||||
<span tal:content="structure cell/view/render" />
|
||||
<metal:topic define-macro="topic">
|
||||
<metal:info use-macro="view/concept_macros/concepttitle" />
|
||||
<h2 i18n:translate=""
|
||||
tal:condition="python: list(item.children())">Children</h2>
|
||||
<metal:children use-macro="item/book_macros/children" />
|
||||
<h2 i18n:translate=""
|
||||
tal:condition="item/textResources">Text Elements</h2>
|
||||
<div>
|
||||
<div tal:repeat="related item/textResources"
|
||||
tal:define="level python:level + 1"
|
||||
tal:attributes="class string:content-$level">
|
||||
<h3>
|
||||
<a tal:attributes="href python:view.getUrlForTarget(related.context)"
|
||||
tal:content="related/title" />
|
||||
</h3>
|
||||
<div>
|
||||
<div tal:replace="structure related/renderShortText" />
|
||||
<p>
|
||||
<a i18n:translate=""
|
||||
tal:attributes="href python:view.getUrlForTarget(related.context)">
|
||||
more...</a></p>
|
||||
</div>
|
||||
</tal:cell>
|
||||
</metal:part>
|
||||
</div>
|
||||
</metal:topic>
|
||||
|
||||
|
||||
</html>
|
||||
|
|
Binary file not shown.
|
@ -3,7 +3,7 @@ msgstr ""
|
|||
|
||||
"Project-Id-Version: 0.13.0\n"
|
||||
"POT-Creation-Date: 2007-05-22 12:00 CET\n"
|
||||
"PO-Revision-Date: 2013-03-21 12:00 CET\n"
|
||||
"PO-Revision-Date: 2013-04-01 12:00 CET\n"
|
||||
"Last-Translator: Helmut Merz <helmutm@cy55.de>\n"
|
||||
"Language-Team: loops developers <helmutm@cy55.de>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -537,6 +537,9 @@ msgstr "Unterbegriffe"
|
|||
msgid "Resources"
|
||||
msgstr "Ressourcen"
|
||||
|
||||
msgid "Text Elements"
|
||||
msgstr "Texte"
|
||||
|
||||
msgid "Title"
|
||||
msgstr "Titel"
|
||||
|
||||
|
@ -702,6 +705,9 @@ msgstr "Zugeordnete Begriffe"
|
|||
msgid "more..."
|
||||
msgstr "Mehr..."
|
||||
|
||||
msgid "More..."
|
||||
msgstr "Mehr..."
|
||||
|
||||
msgid "Versioning"
|
||||
msgstr "Versionierung"
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue