Plone:从getPersonalPortrait()获取Portrait,使用@@ images或其他缩放

时间:2014-11-30 03:30:32

标签: python image plone

我想在自定义视图中修改Plone-Membertool中用户肖像的图像大小。我认为使用以下页面模板片段plone.app.imaging可以实现这一点:

<img tal:define="scales user/img/@@images;
                 image python: scales.scale('image', width=75, height=100);"
     tal:condition="image"
     tal:attributes="src image/url;
         width image/width;
         height image/height"/>

user/img在helper-class中定义如下(并在视图类中作为'user'传递):

mtool = api.portal.get_tool(name='portal_membership')
uid = user.id
fullname = user.getProperty('fullname')
...
dct = {
          'id': uid,
          'img': mtool.getPersonalPortrait(id=uid),
          'fullname': fullname,
          ...
}
return dct

如果我现在在@@images申请user/img,我会收到以下属性错误:

  ...
  Module zope.tales.tales, line 696, in evaluate
  URL: /opt/workspace/my-plone-buildout/src/myproduct.content/myproduct/content/browser/templates/user_list.pt
  Line 42, Column 4
  Expression: <PathExpr standard:u'user/img/@@images'>
  Names:
    ...
  Module Products.PageTemplates.Expressions, line 94, in trustedBoboAwareZopeTraverse
  Module OFS.Traversable, line 300, in unrestrictedTraverse
  __traceback_info__: ([], '@@images')
AttributeError: @@images

似乎mtool.getPersonalPortrait(id)不会返回可在其上应用plone.app.image的图像元素。但是如果我在模板中使用这个构造只是为了显示未更改的图像,它可以正常工作:

<img src="#" tal:replace="structure user/img" />

接下来,我尝试将absolut-url用于用户的肖像以获得@@images工作。首先是助手级:

...
dct = {
...
          'img': mtool.getPersonalPortrait(id=uid),
          'imgurl': mtool.getPersonalPortrait(id=uid).absolute_url(),
...

然后在页面模板中:

<img tal:define="scales user/imgurl/@@images;
                 image python: scales.scale('image', width=75, height=100);"
                 ...

然后我得到一个LocationError:

...
Expression: <PathExpr standard:u'user/imgurl/@@images'>
...

  Module Products.CMFPlone.patches.security, line 12, in traverse
  Module zope.traversing.namespace, line 329, in traverse

LocationError: ('http://localhost:8080/Plone/defaultUser.png', 'images')

即使网址http://localhost:8080/Plone/defaultUser.png显示正确的图片(还有其他图片,然后是默认图片,也不会更改)。

我没有找到任何文档,什么类型的对象getPersonalPortrait()返回以及可以在其上使用哪些方法。以及如何在自定义视图中调整此用户肖像的大小以适应某些特定需求(根据某些规则比较python中的宽度和高度以计算正确的调整大小)。

在python的view-class中获取操作用户肖像的一些指针会很棒。

2 个答案:

答案 0 :(得分:2)

有Plone AddOn名为ftw.avatar,它通过两个主要功能扩展了Plone的默认肖像功能。

首先,它取代了像头像一样的谷歌的默认Plone头像。它使用firstname和lastname的第一个字母生成图像。

其次,它会向纵向网址添加尺寸参数

示例1:这会将肖像图像缩放为26 x 26像素的头像: http://plone/portal_memberdata/portraits/maethu?size=26 这导致:enter image description here

示例2:这会将肖像图像缩放为200 x 200像素的头像: http://plone/portal_memberdata/portraits/maethu?size=200 这导致:enter image description here

<强>实施 它通过以下视图覆盖默认纵向: https://github.com/4teamwork/ftw.avatar/blob/750fbc52f8c2fd6cca538525f72141982008b719/ftw/avatar/browser/portrait.py

from Products.Five.browser import BrowserView
from plone.scale.scale import scaleImage
from plone.scale.storage import AnnotationStorage
from webdav.common import rfc1123_date
from zope.annotation import IAttributeAnnotatable
from zope.interface import alsoProvides


class PortraitScalingView(BrowserView):

    def __call__(self):
        form = self.request.form
        size = form.get('size', form.get('s', None))
        if size is None:
            # return original - no scaling required
            return self.context.index_html(self.request, self.request.RESPONSE)
        else:
            size = int(size)

        if not IAttributeAnnotatable.providedBy(self.context):
            alsoProvides(self.context, IAttributeAnnotatable)

        storage = AnnotationStorage(self.context, self.context.modified)
        scale = storage.scale(self.scale_factory,
                              width=size,
                              height=size)

        response = self.request.RESPONSE
        response.setHeader('Last-Modified', rfc1123_date(scale['modified']))
        response.setHeader('Content-Type', scale['mimetype'])
        response.setHeader('Content-Length', len(scale['data']))
        response.setHeader('Accept-Ranges', 'bytes')
        return scale['data']

    def scale_factory(self, **parameters):
        return scaleImage(self.context.data, **parameters)

对应的zcml:

<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:browser="http://namespaces.zope.org/browser"
    i18n_domain="ftw.avatar">

    <browser:page
        for="plone.app.linkintegrity.interfaces.IOFSImage"
        name="index_html"
        class=".portrait.PortraitScalingView"
        permission="zope2.View"
        />

    <browser:defaultView
        for="plone.app.linkintegrity.interfaces.IOFSImage"
        name="index_html"
        />

</configure>

答案 1 :(得分:0)

不,@@ images视图用于内容,肖像以非常(和低级别)的方式管理。

只需查看Products.PlonePAS模块中的scale_image function即可。您可以使用该功能或​​直接学习如何使用PIL库。