[SOLVED] Rendering an image of a node reference

Hey,

I’m confused, I have the following fusion template, it works like a charm but it will not render the image and i dont know why.

It renders the placeholder, but not the referenced image.

prototype(WG.BaseSite:Selector.CustomModAnsprechpartner) < prototype(Neos.Neos:ContentComponent) {

  cP = ${q(node).context({'invisibleContentShown': true}).property('contactPerson')}
  renderFrontend = ${site.context.inBackend ? false : true}

  renderer = afx`
    <!-- Frontend -->
    <div class="ap-item text-center">
       <picture @if.render={q(props.cP).property('image')}>
        <WG.BaseSite:Content.Image image={q(props.cP).property('image')} />
      </picture>
      <h3 class="ap-name h2">{q(props.cP).property('Name')}</h3>
      <p class="title">{q(props.cP).property('Position')}</p>
      <p class="contact">
        <a @if.render={q(props.cP).property('Phone')} class="phone" href={"tel:" + q(props.cP).property('Phone')}>T <span>{q(props.cP).property('Phone')}</span></a>
        <a @if.render={q(props.cP).property('Email')} class="email" href={"mailto:" + q(props.cP).property('Email')}>{q(props.cP).property('Email')}</a>
      </p>
    </div>
      `
}

The debug output of props.cP shows the following props:

properties => array(7)
    'uriPathSegment' (14) => 'test' (4)
    'Name' (4) => 'Test' (4)
    'Position' (8) => 'Test Position' (13)
    'Phone' (5) => '012345678' (9)
    'Email' (5) => 'test@test.de' (12)
    'title' (5) => 'test' (4)
    'image' (5) => Neos\Flow\Persistence\Doctrine\Proxies\__CG__\Neos\Media\Domain\Model\Imagepersistableproxy

If I try this:

cImage = ${q(node).context({'invisibleContentShown': true}).property('contactPerson').property('image')}

I get an error: Method “property” is not callable in untrusted context

This is the image template (what works fine in other modules)

prototype(WG.BaseSite:Content.Image) < prototype(Neos.Neos:ContentComponent) {

	lazy = ${q(node).prev().is()}

    src = Neos.Fusion:Case {
        image {
            condition = ${q(node).property('image') ? true : false}
            renderer = Sitegeist.Kaleidoscope:AssetImageSource {
                asset = ${q(node).property('image')}
            }
        }
        dummyImage {
            condition = ${site.context.inBackend}
            renderer = Sitegeist.Kaleidoscope:DummyImageSource {
                text = 'Image'
            }
        }
    }

    alternativeText = ${q(node).property('alternativeText')}

    renderer = afx`
        <Sitegeist.Kaleidoscope:Image
            class="container-image"
            loading="lazy"
            lazyWidth={200}
            imageSource={props.src}
            srcset="320w, 400w, 480w, 600w, 768w, 800w, 960w, 1024px, 1280w, 1440w, 1680w, 1920w"
            sizes="(min-width: 800px) 1000px, (min-width: 480px) 800px, (min-width: 320px) 440px, 100vw"
            alt={props.alternativeText}
            formats="webp, png"
            quality="80"
            />
	`

}

You should use a standalone image component instead of reusing a content component that accesses the node directly and ignores the prop you pass.

Hey,

I’m working with Finn, and we threw the reusable component out of the template and replaced it directly inline with Kaleidoscope.

prototype(WG.BaseSite:Selector.CustomModAnsprechpartner) < prototype(Neos.Neos:ContentComponent) {

  cP = ${q(node).context({'invisibleContentShown': true}).property('contactPerson')}
  cImage = ${q(props.cP).property('image')}
  renderFrontend = ${site.context.inBackend ? false : true}

  src = Neos.Fusion:Case {
    image {
      condition = ${q(props.cP).property('image') ? true : false}
      renderer = Sitegeist.Kaleidoscope:AssetImageSource {
        asset = ${q(props.cP).property('image')}
      }
    }
    dummyImage {
      condition = ${site.context.inBackend}
      renderer = Sitegeist.Kaleidoscope:DummyImageSource {
        text = 'Image'
      }
    }
  }

  renderer = afx`
    <div class="ap-item text-center">
      <picture @if.render={q(props.cP).property('image')}>
        <!-- <WG.BaseSite:Content.Image image={props.cImage} /> -->
        <Sitegeist.Kaleidoscope:Image
          loading="lazy"
          lazyWidth={200}
          imageSource={props.src}
          srcset="320w, 400w, 480w, 600w, 768w, 800w, 960w, 1024px, 1280w, 1440w, 1680w, 1920w"
          sizes="(min-width: 800px) 1000px, (min-width: 480px) 800px, (min-width: 320px) 440px, 100vw"
          formats="webp, png"
          quality="80"
        />
        <!-- <img src={props.cImage} alt={"Foto von " + q(props.cP).property('Name')} /> -->
      </picture>
      <!-- <Neos.Fusion:Debug>{props.cP}</Neos.Fusion:Debug> -->
      <h3 class="ap-name h2">{q(props.cP).property('Name')}</h3>
      <p class="title">{q(props.cP).property('Position')}</p>
      <p class="contact">
        <a @if.render={q(props.cP).property('Phone')} class="phone" href={"tel:" + q(props.cP).property('Phone')}>T <span>{q(props.cP).property('Phone')}</span></a>
        <a @if.render={q(props.cP).property('Email')} class="email" href={"mailto:" + q(props.cP).property('Email')}>{q(props.cP).property('Email')}</a>
      </p>
    </div>
  `
}

Unfortunately, this does not help. I get the placeholder in the backend, but the frontend just renders an empty picture tag. Same scenario as before.

I hope you can help us.

Props doesn’t work inside the prop src. You have to define that as @private property and then access it via private.src

1 Like

Hey, sorry for not responding to your really helpful answer.

I put everything in @private and it works.

@private {
  computedImage = Neos.Fusion:Value {
      value = ${q(props.cP).property('image')}
  }

  src = Neos.Fusion:Case {
    image {
      condition = ${private.computedImage ? true : false}
      renderer = Sitegeist.Kaleidoscope:AssetImageSource {
        asset = ${private.computedImage}
      }
    }
    dummyImage {
      condition = ${site.context.inBackend}
      renderer = Sitegeist.Kaleidoscope:DummyImageSource {
        text = 'Image'
      }
    }
  }
}

[…]

<Sitegeist.Kaleidoscope:Image
      loading="lazy"
      lazyWidth={200}
      imageSource={private.src}
      srcset="320w, 400w, 480w, 600w, 768w, 800w, 960w, 1024px, 1280w, 1440w, 1680w, 1920w"
      sizes="(min-width: 800px) 1000px, (min-width: 480px) 800px, (min-width: 320px) 440px, 100vw"
      formats="webp, png"
      quality="80"
    />
2 Likes