Plone: ​​get portrait from getPersonalPortrait () scales with images @@ or otherwise

I would like to change the custom portrait image from Plone-Membertool in custom view. I thought it was possible over plone.app.imaging

with the following snippet of the page template:

<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

is defined in the helper class as follows (and passed in the view class as "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

      

If I applied now @@images

in this user/img

, I get the following AttributeError:

  ...
  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

      

It mtool.getPersonalPortrait(id)

doesn't seem to return Image-Element where plone.app.image

can be applied to it. But if I use this construct in the template just to display the unmodified image, it works fine:

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

      

As the next, I tried to use the absolut-url for the custom portrait to get it @@images

working. First in the helper class:

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

      

And then in the page template:

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

      

Then I get 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')

      

Even if the URL http://localhost:8080/Plone/defaultUser.png

shows the correct image (there are others, by default, which do not change).

I haven't found any documentation of what type of object is getPersonalPortrait()

returned and what methods can be used on it. And how can I resize the custom portraits to some specific needs of the custom view (compare the width and height in python according to some rules to calculate the correct resizing).

It would be great to get some pointers to manipulate the custom portrait in the view class in python.

+3


source to share


2 answers


Here is Plone AddOn called ftw.avatar

, which extends the default portrait functionality for Plone with two main features.

First, it replaces the default Plone avatar with a Google-like one. It generates an image using the first letter of the name and name.

Second, it adds a size parameter to the portrait of the portrait

Example 1: This reduces the portrait image to 26 x 26 pixels: http://plone/portal_memberdata/portraits/maethu?size=26

This results in:enter image description here

Example 2: This reduces the portrait image to 200 x 200 pixels: http://plone/portal_memberdata/portraits/maethu?size=200

This results in:enter image description here



Implementation: It overrides the default portrait with the following look: 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)

      

Corresponding 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>

      

+2


source


No, viewing @@ images for content, portrait is handled very (and low-level) differently.



Just take a look at the scale_image function from the module Products.PlonePAS

. You can use this feature or learn to use the PIL library directly.

0


source







All Articles