When we create views REST Exports (json) to be consumed by external systems the src URLs of images inside text fields are relative (i.e. src="/sites/all/...) and the images get broken. Therefore the consuming systems will need to preprocess the SRCs inside text fields which it involves regular expression replacement. There is no easy way to do this within drupal other than actually creating a serializer module as described in https://www.drupal.org/node/2754515.

The solution could be an option that asks for absolute/relative urls inside text fields
or a workaround would be to apply a filter to a text format and use that format all throughout the site if the contents are served to external systems by means of JSON. (i.e. https://www.drupal.org/project/rel_to_abs)

For more reason why this change is needed please look at similar issue and fix #88183: Relative URLs in feeds should be converted to absolute ones

Comments

GiorgosK created an issue. See original summary.

wim leers’s picture

Title: rest export views (json) should output absolute paths » REST views (json) should output absolute paths
Status: Active » Postponed (maintainer needs more info)
Issue tags: +Needs issue summary update

Thanks for reporting an issue!

Can you expand the issue summary to list reasons why we should do this?

giorgosk’s picture

Issue summary: View changes
wim leers’s picture

Status: Postponed (maintainer needs more info) » Active
Issue tags: -Needs issue summary update

Thanks!

giorgosk’s picture

Issue summary: View changes
dawehner’s picture

This issue is a bit tricky as well. Just imagine if you GET some value and POST it afterwards ... suddenly the value stored in the DB would be changed when we rewrite absolute paths.

giorgosk’s picture

@dawehner if the rewriting is on the fly based on some conditions I don't understand how it can be tricky
in the solution I have in my head the text/field in DB will not be overwritten

Its exactly the same problem that existed for FEEDS and it was solved a while ago #88183: Relative URLs in feeds should be converted to absolute ones and there is a solution already in D8 core ... so for this problem/solution could follow the same path (or maybe I misunderstood this other problem/solution)

cburschka’s picture

I think the problem dawehner mentions is that REST on entities isn't read-only - reading a resource via GET and then writing the same data back via POST should be (effectively) idempotent. The feeds didn't suffer the same difficulty because they're a rendered presentation, rather than a copy of the raw data.

However, this isn't about an entity and rather about a view. REST Views are a read-only presentation (it goes through field formatters, and there's no endpoint to write back to anyway), so that shouldn't be an issue.

Then again, this is solvable in contrib, and I'm not sure it takes a serializer; merely an extra field formatter that extends the StringFormatter / TextDefaultFormatter classes to add its processing step...

dawehner’s picture

@cburschka
Thank you for summarizing my thoughts!

Are you sure about the read-only aspect of REST views? In many applications people will fetch a list of things, but then update a single item of this collection.

On top of that I'm wondering whether the problem of absolute paths does also exist of single item resources.

cburschka’s picture

Are you sure about the read-only aspect of REST views? In many applications people will fetch a list of things, but then update a single item of this collection.

Oh, I was thinking of the data_field row type, which generates a non-reversible presentation.

I just realized the original question may indeed be about the data_entity row type, though - that would explain why a field formatter wouldn't help.

wim leers’s picture

Title: REST views (json) should output absolute paths » REST views (json) should output absolute image URLs

First, let's fix the title.

wim leers’s picture

Status: Active » Closed (works as designed)
Related issues: +#88183: Relative URLs in feeds should be converted to absolute ones

Agreed with @dawehner's concerns, which were further clarified by @cburschkain #8.

#88183: Relative URLs in feeds should be converted to absolute ones is not the same problem. Feeds are to be parsed by generic clients (feed readers on the web, my phone, your desktop, and so on). And in the end, RSS feeds are just repackaged HTML.

On top of their concerns, I can add several more:

  1. same content and API available via multiple domains
  2. files are often served from a separate domain, that is more often prone to changes (e.g. changing a CDN provider), that's why there is even an explicit setting for it: $settings['file_public_base_url']
  3. there is no spec for API responses, but there is one for RSS responses — quoting from the IS from that issue: The RSS specification specifies that all links should be absolute.

Therefore I think it's fair to say this is working as designed.

Szultino’s picture

Solution to show absolute images path with rest api views:

1. add a new view, configure it, but do not add image field to output
2. add relationship, named "FieldTitle (field_[ImageFieldName]:target_id)"
3. add new field, named: URI
FIELD SETTINGS:
- at the top, choose at the realitionship to the filed_ImageFieldName
- check "Display the file download URI"

samaphp’s picture

Worked for me #13

Nice workaround .. Thank you @szultino

giorgosk’s picture

Perhaps this module can be a workaround (have not tried it)
https://www.drupal.org/project/rest_absolute_urls

capysara’s picture

Thanks @Szultino! That workaround was excellent for images (I'm on D9).

I needed to get full urls on a link field, too, but I couldn't get absolute urls without including the href markup, which I didn't want for my export. I ended up using this module and it worked for both image and link fields.

In case this is helpful to others, my link field allows both internal and external links, so I used the following twig in my rewrite results (using the views_base_url module):

{% if 'http' in field_link|render|render %}
{{ field_link }}
{% else %}
{{ base_url }}{{ field_link }}
{% endif %}
ruslan piskarov’s picture

Thank you @Szultino. #13 the best solution.

afagioli’s picture

#13 comes to handy. Thanks

Muatez Ashraf’s picture

@Ruslan Piskarov
@afagioli
@capysara
Can you help me? I am facing the same problem and I was able to add the URI attribute to the return object from API but it does have a value how I can add an image in the new URL Field

Muatez Ashraf’s picture

amitajgaonkar’s picture

#13 works, Nice workaround

nick.morahan’s picture

9.3.3 broke this for me and image URIs started displaying relatively. So I rewrote the field results in the rest view with custom text - domain name and uri token - and forced the fields to render absolutely. Doubt this will help everyone and expect there is a better solution, but got me over the hump and my front-facing sites have images again.

supertony’s picture

@nick.moahan yep, the awesome solution from #13 broke for me too after upgrading from 9.2.20 to 9.4.3. For the time being I've modified a file at docroot/core/modules/file/src/Plugin/Field/FieldFormatter/FileUriFormatter.php.

Before:
$value = $this->fileUrlGenerator->generateString($value);

After:
$value = $this->fileUrlGenerator->generateAbsoluteString($value);

Prior to 9.3.0 the viewValue function in this file, looked like this:

  protected function viewValue(FieldItemInterface $item) {
    $value = $item->value;
    if ($this->getSetting('file_download_path')) {
      // @todo Wrap in file_url_transform_relative(). This is currently
      // impossible. See BaseFieldFileFormatterBase::viewElements(). Fix in
      // https://www.drupal.org/node/2646744.
      $value = file_create_url($value);
    }
    return $value;
  }

You can read about file_create_url being deprecated here https://www.drupal.org/node/2940031, which was introduced in version: 9.3.0.

This is still a temporary workaround and I think the next solution is to create a custom file formatter that's selectable from the view.

Hope this helps!

nicholass’s picture

I read through this thread and still need help. I have a typical Body(Ckeditor WYSWIG field that has images and text links) and need the REST export of that content to have absolute URLs.

This looked like a perfect fit but couldn't get it to work drupal.org/project/rest_absolute_urls I have a feeling it stopped working in 9.x

I think #13 applies only I think to individual fields, not WYSWIG fields.

I don't really want to use a text format with drupal.org/project/rel_to_abs because then my pages will be absolute URLs, when I only want them converted to absolute in REST exports.

Maybe if in only the view REST Export I could override the text format?

Szultino’s picture

#24:
If you want to convert rel to abs in fullhtml without use outer module, in views in the field settings choose "Override the output of this field with custom text", and write this kind of twig code:

{{ field_FIELDNAME|replace({'"/files/': '"https://DOMIAN/files/'})|raw }}

The "raw" command at the end makes some errors (for example with media output), but I'm searching the perfect solutions...

angrytoast’s picture

Updating with a related issue link to a change that provides an absolute URL option at the image URL field formatter level. This may be a viable solution?
https://www.drupal.org/project/drupal/issues/2811043