Get Image Source from Sitegeist

I’m still struggling to understand contexts and node navigation…
How do I read the src Attribute / Property of another Image Node? In particular using Sitegeist

We have a standard Image Component that uses the Sitegeist example of one of your video guides:

prototype(Test.Site: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
        }
    }
    alternativeText = ${q(node).property('alternativeText')}
    imageClass = ${q(node).property('imageClass') ? imageClass : 'w-100 h-100'}

    renderer = afx`
        <Sitegeist.Lazybones:Image
            class={props.imageClass}
            lazy={true}
            lazyWidth={200}
            imageSource={props.src}
            srcset="320w, 400w, 480w, 600w, 640w, 720w, 768w, 800w, 960w, 1024px, 1280w, 1440w, 1600w, 1680w, 1920w, 2560w"
            sizes={props.sizes}
            alt={props.alternativeText}
            />
	`

}

In another Component we want to build cards using those images. But later we want to use the Image itself plus a Background Image.
I would like to be able to use props.cardImage.src

prototype(Test.Site:Content.Card) < prototype(Neos.Neos:ContentComponent) {

  cardDescription = Neos.Neos:Editable {
    property = 'cardDescription'
  }

  cardTitle = Neos.Neos:Editable {
    property = 'cardTitle'
  }

  cardImage = Test.Site:Content.Image {
    @context.node = ${q(node).find('cardImage').get(0)}
  }

  cardFilter = ''

  renderAsImage = ${site.context.inBackend ? true : false}

  renderer = afx`
  
    <div class={"col content__filter--entry content__filter--" + props.cardFilter}>
      <div class="card my-2 content__box--white">
        <div @if.render={!props.renderAsImage} class="w-100 content__box__image--square" style={"background-image:url(" + props.cardImage.src + ")"} >
          <a class="hidden stretched-link" href="#"></a>
          <div class="d-none" title="cardSlideText"></div>
        </div>
        <div @if.render={props.renderAsImage}>
          {props.cardImage}
        </div>
        <div class="card-body">
          <h4 class="card-title">{props.cardTitle}</h4>
          <p class="card-text">{props.cardDescription}</p>
        </div>
      </div>
    </div>
  `
}

I also tried something like:

cardImageSource = Neos.Neos:ImageUri {
    @context.node = ${cardImage}
}

to no success.

With only the documentation I can’t seem to understand the logic behind all this…

By writing:

you assign the rendered image to the fusionProperty cardImage which afterwards contains a string with an img-tag.

The point of Sitegeist.Kaleidoscope and Sitegeist.Lazybones is that they create an object that can be passed around configured and eventually converted to a src or a srcset.

Maybe this helps to clarify this:

prototype(Vendor.Site:Example) < prototype(Neos.Fusion:Component) {
	
            # create a meta image object for passing around and converting to html later
	imageSource = 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
        }
    }
    
    
    renderer = Neos.Fusion:Join {
    	
    	# rendered img-tag
    	renderedImage = afx`
	        <Sitegeist.Lazybones:Image
		        imageSource={props.imageSource}

	            srcset="320w, 400w, 480w, 600w, 640w, 720w, 768w, 800w, 960w, 1024px, 1280w, 1440w, 1600w, 1680w, 1920w, 2560w"
                sizes="50vw" 
	            />
		`
		
		# default src attribute
		source = ${props.imageSource.src()}

		# 200x200 src attribute
		srcWithDimension = ${props.imageSource.setDimensions(200,200).src()}

		# srcset
		anExampleSourceset= ${props.imageSource.srcset("320w, 400w, 480w")}
    	
   	}
}
1 Like

Thank you for the fast reply.

I now understand, that I previously assigned the rendered image. Which is fine when I just want to output it as HTML.

Your example looks like exactly what I need, but I unfortunately still don’t see, how I can access the source attribute.

this looks like what I need. But how do I access that source attribute?
Because assigning the Vendor.Site:Example I, as previously, I get the fully joined string

Sorry for my confusion…

You do not access the source attribute. The imageSource is an object that is able to generate a src for you once needed.

renderer = Neos.Fusion:Join {
    source = ${props.imageSource.src()
}

In this example the src is added to the result directly but you can use this in other ways aswell

renderer = afx`
    <div style={"backgound-image: url(" + props.imageSource.src() + ");"}
`

Regards, Martin

1 Like

Thank you Martin.
Now I think I understand.

I now solved it using 2 different Components. One that renders only the source and one that uses that components source to render the full Image

prototype(Example.Site:Content.Image) < prototype(Example.Site:Content.ImageSource) {

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

    alternativeText = ${q(node).property('alternativeText')}
    imageClass = ${q(node).property('imageClass') ? imageClass : 'w-100 h-100'}

    renderer = afx`
        <Sitegeist.Lazybones:Image
            class={props.imageClass}
            lazy={true}
            lazyWidth={200}
            imageSource={props.imageSource}
            srcset="320w, 400w, 480w, 600w, 640w, 720w, 768w, 800w, 960w, 1024px, 1280w, 1440w, 1600w, 1680w, 1920w, 2560w"
            sizes={props.sizes}
            alt={props.alternativeText}
            />
	`
}
prototype(Example.Site:Content.ImageSource) < prototype(Neos.Neos:ContentComponent) {
    imageSource = 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
        }
    }

    renderer = Neos.Fusion:Join {
        source = ${props.imageSource.src()}
    }
}

That seems to be the cleanest solution I could come up with.

My card can then do:

  cardImage = Example.Site:Content.Image {
    @context.node = ${q(node).find('cardImage').get(0)}
  }

  cardImageSource = Example.Site:Content.ImageSource {
    @context.node = ${q(node).find('cardImage').get(0)}
  }

and have both values.

Thank you Martin for your time and patience!