Volto - Workaround for broken user portrait

I'm looking for a workaround or fix for this issue. I need to return the user portrait in a view.
Currently the user portrait is broken.
This is related to the plone restapi @users endpoint which returns the path to the user portrait.
Unfortunately the path portal_memberdata/portraits/{userid} is not implemented in Volto and does not return a image.

I'm looking for pointers on how I would retrieve and return the actual image.

Here's the actual bug:

No idea if this could be of any help, but in a standard template I use this

 'portrait': membership_tool.getPersonalPortrait(member.getProperty('id')).absolute_url(),

Give this a try: GitHub - eea/volto-middleware-vh: A Volto middleware for any Plone backend view or resource, it was meant to make it possible to "bridge" Plone views (for example the RSS view) through the Volto Express http server. Note: it doesn't do anything by default, you have to configure the memberdata path. See its readme.

@espenmn this looks like something for classic Plone not Volto. The problem is that Volto is being given a path/route that it cannot account for (portal_memberdata/portraits/{userid}). The result is a broken portrait. The portrait works fine in classic Plone but not Volto.

Thanks @tiberiuichim this looks like the trick! It provides the machinery for me to create a proxy that will pull the data from backend/portal_memberdata/portraits/{userid} and serve it as
frontend/portal_memberdata/portraits/{userid}

Will try this later and report the result :crossed_fingers:.

Notice that on the EEA projects we never use the Volto project to do any actual Volto coding or configuration, we use Volto addons exclusively for that. Usually it doesn't make a difference, but I think, with this addon, because its config executes before your project configuration, it makes a difference. You can just copy its entire code (it's just one file) in your project and control its execution order from there. Another option would be to use env var to configure it, RAZZLE_VIRTUAL_HOSTED_PATHS, check its source code.

So this in my src/config.js of my Volto project won't work?
(It isn't working at the moment)

export default function applyConfig(config) {
  // Add here your project's configuration here by modifying 
  // `config` accordingly
  config.views.contentTypesViews.committee = Committee;
//  config.views.contentTypesViews.committee_listing = CommitteeListing;
  config.settings = {
    ...config.settings,
    virtualHostedPaths: ['/portal_memberdata/portraits/**']
  };
  
  return config;
}

It won't work, because the addon loader code executes before the project (the logic is: addons customize Volto, the Volto project loads last and allows "fixing". You could import the addon loader from your project and execute it again, from the project, I think that might work as well.

import applyVHConfig from '@eeacms/volto-middleware-vh'

export default function applyConfig(config) {
...
    config = applyVHConfig(config);
    return config;
}

Looking at the code... it seems to assume that the api is either on port 80 or 443.
My api runs on a different port on a different server. I will need to to reconfigure my buildout cors settings and wire up nginx so that the api can listen on port 443 or 80.

I think this is a reasonable assumption for production but in development the port is 8080... In my case, my api is running remotely on a non-standard port. It would be good to have a way to define the default port.

Indeed, that's a bug.

Add a new issue, and we will have a look at fixing this so that it reads
the ports from the configuration.

1 Like

Issue submitted

Going down the "rabbit-hole" it appears that the middleware still guesses ports 80 or 443.
I'm assuming this because the related issue is still open.

Luckily, I know enough to get around it :slight_smile:

Perhaps my need for the user portrait in a profile is an edge case.