3

我正在运行 Plone 4.3 并且一直在尝试创建自定义 portlet。portlet 很简单,应该允许用户上传图像并提供一些可以显示在图像下方的描述性文本。

这是我到目前为止的代码:

from zope.interface import implements
from zope.formlib import form
from zope import schema
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from plone.app.portlets.portlets import base
from plone.memoize.instance import memoize
from plone.namedfile.field import NamedImage
from plone.directives import form
from z3c.form import field
from plone.app.portlets.browser import z3cformhelper

class IMyImagePortlet(form.Schema):

    myimagetitle = schema.TextLine(
        title=u"Image title",
        description=u"Enter the image title",
        default=u"",
        required=True)

    myimagedescription = schema.TextLine(
        title=u"Image text",
        description=u"Enter the text which appears below the image",
        default=u"",
        required=True)

    myimage = NamedImage(
        title=u"My image",
        description=u"Upload an image",
        required=True)

class Assignment(base.Assignment):
    implements(IMyImagePortlet)

    header = u"My Image"
    myimagetitle = u""
    myimagedescription = u""
    myimage = u""

    def __init__(self, myimagetitle=None, myimagedescription=None, myimage=None):
        self.myimagetitle = myimagetitle
        self.myimagedescription = myimagedescription
        self.myimage = myimage

    @property
    def title(self):
        """This property is used to give the title of the portlet in the
        "manage portlets" screen.
        """
        return u"My image"

class Renderer(base.Renderer):

    _template = ViewPageTemplateFile('templates/myimage_portlet.pt')

    def __init__(self, *args):
        base.Renderer.__init__(self, *args)

    @memoize
    def myimagetitle(self):
        return self.data.myimgaetitle

    @memoize
    def myimagedescription(self):
         return self.data.myimagedescription

    @memoize
    def myimage(self):
        return self.data.myimage

    def render(self):
        return self._template()

class AddForm(z3cformhelper.AddForm):
    fields = field.Fields(IMyImagePortlet)

    label = u"Edit image"
    description = u"A portlet which can display image with text"

    def create(self, data):
        return Assignment(**data)

class EditForm(z3cformhelper.EditForm):
    fields = field.Fields(IMyImagePortlet)

    label = u"Edit image"
    description = u"A portlet which can display image with text"

这似乎按预期工作,并允许我添加一个带有标题、图像和图像描述的新 portlet。但是,我一直在阅读文档,但找不到很多创建带有图像上传字段的 portlet 的示例,因此可能有更好的方法来执行此操作。

我的问题是我似乎无法在模板中渲染图像。我一直在参考https://developer.plone.org/reference_manuals/external/plone.app.dexterity/advanced/files-and-images.html上的文档,并在我的模板中有以下内容,但图像是不显示:

<div tal:define="picture nocall:context/myimage"
     tal:condition="nocall:picture">
    <img tal:attributes="src string:${context/absolute_url}/@@download/myimage/${picture/filename};
                     height picture/_height | nothing;
                     width picture/_width | nothing;"
    />
</div>
4

1 回答 1

0

我们做了你想要的。 https://github.com/4teamwork/ftw.subsite/tree/master/ftw/subsite/portlets 这是一个预告portlet,不幸的是不在一个包中。但是您可以根据需要调整代码。

我们在 image.py 中定义了一个浏览器视图:

from Acquisition import aq_inner
from zope.publisher.browser import BrowserView


class ImageView(BrowserView):
    """View the image field of the image portlet. We steal header details
    from zope.app.file.browser.file and adapt it to use the dublin
    core implementation that the Image object here has."""

    def __call__(self):
        context = aq_inner(self.context)
        image = context.image
        self.request.response.setHeader('Content-Type', image.contentType)
        self.request.response.write(image.data)

向 zcml 注册(重要的是图像视图是for您的 portlet 分配):

<browser:page
    for=".yourportlet.Assignment"
    name="image"
    class=".image.ImageView"
    permission="zope.Public"
 />

在您的portlet Renderer 中,您必须定义一个获取图像(遍历)的方法。

from plone.app.portlets.portlets import base


class MyPortletRenderer(base.Renderer)

    def image_tag(self):
        state = getMultiAdapter((self.context, self.request),
                                name="plone_portal_state")
        portal = state.portal()
        assignment_url = \
            portal.unrestrictedTraverse(
            self.data.assignment_context_path).absolute_url()

        return "<img src='%s/%s/@@image' alt=''/>" % (
            assignment_url,
            self.data.__name__)

现在您可以在您的 portlet 中使用该图像:

<tal:image content="structure view/image_tag />

我不知道是否有更简单的解决方案。命名可能会更好:-) 但它有效并且已经过测试https://github.com/4teamwork/ftw.subsite/blob/master/ftw/subsite/tests/test_subsiteportlet.py

于 2013-08-27T20:08:08.687 回答