2013-08-27 26 views
3

我正在運行Plone 4.3並試圖創建一個自定義portlet。該portlet非常簡單,應該允許用戶上傳圖像並提供一些可以在圖像下顯示的描述性文本。Plone portlet使用plone.namedfield.field.NamedImage

這裏是我到目前爲止的代碼:

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> 
+0

沒有明確的答案立刻浮現在腦海,但我可以看到的問題是什麼。問題是圖像字段是在portlet中定義的,但是模板代碼試圖從上下文中獲取它,所以從內容項中獲取它。此內容項目沒有myimage字段,因此tal:condition爲false,並且src屬性也會失敗。您可以先將「context/myimage」更改爲「view/image」,然後查看您是否可以從這裏開始工作。 – maurits

+0

請參閱GitHub上的imageportlet包,以解決此問題 –

+0

@MikkoOhtamaa我注意到您正在portlet代碼中實現IImageScaleTraversable接口。你有一個如何在模板中使用這個縮放功能的例子嗎? – manicminer

回答

0

我們也正是你想要的。 https://github.com/4teamwork/ftw.subsite/tree/master/ftw/subsite/portlets 這是一個挑逗門戶,不幸的是沒有在一個包中。但您可以根據自己的需求調整代碼。

我們定義在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渲染器,你必須定義一個獲取圖像的方法(遍歷)。

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

相關問題