Closed (fixed)
Project:
Experience Builder
Version:
0.x-dev
Component:
Page builder
Priority:
Critical
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
24 Jan 2025 at 08:18 UTC
Updated:
18 Mar 2025 at 10:44 UTC
Jump to comment: Most recent, Most recent file

Comments
Comment #5
bnjmnmThis works fine on a fresh install
hook_installneeds to run to create the placeholder image and associated media entity.Comment #6
lauriiiI had just re-installed before submitting this issue. Re-installed again and still seeing the same error message.
Comment #7
larowlanCan you put a breakpoint in the install hook and advise where it exits?
Comment #8
lauriiiHow does the default image support work? Do extensions shipping components with default images have to provide an install hook to use an image by default?
Comment #9
lauriiiThe file
/sites/default/files/600x400.pngexists if I visit it manually 🤔 The media item that was added looks correct.I'm a bit confused about the whole underlying change. I'm not sure that it's the right behavior that we're adding the default images to the media library. The image property is not supposed to be tightly coupled with media library and we may want to add support for image uploads in future too: #3472192: Redux support for ImageWidget: `[image] String value found, but an object is required`.
Comment #10
bnjmnmIt is working fine for me with what the install hook provides.
To narrow down what might be different it's probably worth checking admin/content/media to see if the media entity created via the install hook actually got created, and if so, is it accessing the image properly
There are two steps in the process that can be checked.
First Step
First, the image in
experience_builder/images/600x400.pngis added as a managed file and copied to the root ofpublic://Questions:
Is the file being copied?
Where is it being copied to?
Second Step
A media entity is created referencing the managed file created in the prior step.
The "Default placeholder image" entity pictured below should exist and the preview should actually provide an image .

Questions:
Does this media entity exist?
Is it previewing a valid image/path?
If everything checks out above, please share path of
public:://on the site that is failing on this.The sdc has the preview image path configured as
- src: /sites/default/files/600x400.pngwhich seems like it's making some assumptions regarding the stream path so I'd like to rule that out if there's nothing earlier in the chain failing.Comment #11
lauriiiMedia item exists and preview fine in the media UI:

File exists:

Comment #12
lauriiiI was able to narrow done potential reason for this; I have the image multiple times in the /files directory because I've re-installed XB multiple times. This means that the file in the file entity has a suffix _4 and cannot be found with
\Drupal\Core\Entity\EntityStorageInterface::loadByProperties.Comment #13
lauriiiDeleted the file, tried re-installing but now I have the file existing in the file entities but the media entity doesn't exist. 🤷♂️
Comment #14
larowlanAll of this is temporary code until we can delete ::findTargetForProps which is what #3467954: META: Evolve XB UI's data model to allow non-SDC components' inputs, DynamicPropSource support, etc. and its children are for.
I think in the meantime using FileExists:Replace will smooth the issue Lauri experienced
Comment #16
larowlanOpened an MR to replace the file if it exists, that should smooth things until we get a chance to work on #3467954: META: Evolve XB UI's data model to allow non-SDC components' inputs, DynamicPropSource support, etc.
Comment #17
lauriiiStill running into the same problem from #13 that the media entity doesn't get created when I first install XB on a fresh install. I uninstalled XB and installed once more and now the image component is working. This allows me to UAT #3471978: Make the Media Library dialog look like the admin theme without materially affecting anything outside of the dialog (possibly use an iframe for CSS isolation) but keeping this open because I bet that others will run into this problem.
Comment #18
lauriiiFWIW, I'm getting this error even when selecting existing images from the media library:
Comment #19
larowlanI'm very keen to keep going on #3467954: META: Evolve XB UI's data model to allow non-SDC components' inputs, DynamicPropSource support, etc. so we can kill off ::findTargetForProps which is where this issue is coming from - but it sounds like we need to do something else in the meantime as a band-aid
Comment #20
wim leers#14++
#19++
I'd prefer to have @larowlan to focus hard on getting that stuff on track because we have to get it on track anyway.
Let's not put a band-aid on a band-aid 😅🙏
I'd like to make it @larowlan's top priority in the next 2 weeks to keep pushing forward on #3467954: META: Evolve XB UI's data model to allow non-SDC components' inputs, DynamicPropSource support, etc. and all its child issues/blockers to solve this at the root.
Comment #21
wim leers#3491978: Implement saving block settings forms introduced this, by the way.
Comment #22
effulgentsia commentedComment #23
bnjmnmre #20
That issue seems like the right priority, When that work is done, would it still be necessary for every prop-example image to become a media entity? It's fine with our dev-collection of components, but as more custom components start happening I could see that causing issues, such as someone deleting that placeholder image would make the component un-addable. It might be helpful to have a placeholder image generating controller, similar to placehold.it, where the URL determines width, height, color, content, then the required
srcfor preview won't be at risk of deletion and repos don't need to have as many image files just to placehold stuff.Again, the data model work seems like the priority to me, but if the above seems worthwhile this issue could be the home for it as it would make the band-aid unnecessary.
Comment #24
larowlanI hit this on a fresh install and can confirm the file is created, but the media entity is not, which would indicate the media type doesn't exist when experience_builder.install is running - likely because we're now installing modules in bulk #3416522: Add the ability to install multiple modules and only do a single container rebuild to ModuleInstaller (I'm running 11.x HEAD)
Comment #25
longwaveI hit this on a reinstall in the same way as #12. As per #23 I don't think we can rely on files existing at specific paths; perhaps in the images case at least we should be more lenient, if we can't find the underlying file then should we really be throwing an error message?
@larowlan for now I think we should only consider compatibility with 11.1, we have a few months and #3492722: Update XB to require Drupal 11.2 to solve compatibility with 11.2.
Comment #26
wim leersI wonder if everyone who is hitting this is testing using
11.xHEAD? 🤔#25: — if we don't, then the SDC subsystem itself will. At least generally speaking, I suspect that in this case, you're implying "just generate
<img src="http://example.com/cat.jpg" alt="a cat">and let the browser then fall back to showing the text alternative?#23: thanks, @bnjmnm — much appreciated! And is a very intriguing idea, with a lot of potential indeed 🤔
Related: #3468944: Update XB's `image` SDC to comply with best practices, and document those best practices.
What you wrote actually ties in nicely with my alternative idea, in case #20 doesn't work out:
Both A and B can be solved by the same infrastructure: if the XB
Componentconfig entity could contain (and export/import like any config) the default image, then it'd be guaranteed to work. In case A ("SDC-provided"), the initial assignment happens automatically (upon creating theComponentconfig entity), in case B ("site builder-provided") it'd happen manually (requires editing a createdComponentconfig entity).After that initial step, the config entity would carry a dependency on the
MediaTypeconfig entity, theMediacontent entity UUID, and the base64-encoded image data. Upon saving thisComponentconfig entity, that'd result in theMediaentity with that UUID being recreated if it doesn't already exist.Which is exactly what we already PoC'd many months ago, and which last surfaced in September:
— yours truly at #3473336-8: The UI only handles resolved props values, hence complex widgets do not show the current value in props form (e.g. image with Media Library Widget)
Comment #27
lauriiiI don't really understand how we've ended up forming an assumption that the default images need to be added to the media library? That doesn't really seem like the expected user experience. Let's say, I'm using Acquia DAM for managing our media assets, and I download a community component which comes with a default image. I certainly wouldn't expect the default image to appear in the DAM. 🤔
Comment #28
longwaveYeah I don't think an SDC-provided default should end up in the media library; it's not part of the site's media and you would never want to really select it nor should you have the ability to change it directly, it's just a fallback.
But a site-builder specified default probably *should* end up in the media library as described in #26, if it's configured by editing the Component config entity?
Comment #29
wim leers@lauriii FYI we previously discussed SDCs providing default images in the context of #3462705: [META] Missing features in SDC needed for XB months ago.
Note that an SDC currently cannot provide a valid default image, because an image URI must be either:
http://URIhttps://URIhttp://URI… plus it must NOT be some random image hosting service: it MUST be powered by the current site's domain or a DAM service it integrates with.
All of the above is necessary for such a value to actually work when put into
<img src="<default value here>">!IOW: the sole example of this in the XB codebase itself is in need of an overhaul:
👆 that is a default value not provided by the SDC (hence #3462705: [META] Missing features in SDC needed for XB), nor is it absolute, nor is it guaranteed to be root-relative.
This default value only works thanks to
experience_builder_install(). Except when it doesn't. Which is what is being reported here! 😅Comment #30
wim leersDiscussed this with @longwave and @effulgentsia. We didn't get to a resolution.
Here's the scenario that currently forces us to import/create the SDC/"code component"-specified default image as a
Fileentity (if using the image field type for the "image" prop shape), aMediaentity (if the media library is installed) or a DAM (if such a module is installed):profile_pic+bio.Comment #31
wim leersSounds like @larowlan also has been thinking about this:
— @larowlan, January 14, 2025, #3493943-7: SDC+JS Component Sources: split default values into `resolved` and `source`
I'm not sure how he imagines making the SDC-provided default image into a resolveable URL though.
But this is exactly why I wrote #20: it all is connected. And the more small pieces of #3467954: META: Evolve XB UI's data model to allow non-SDC components' inputs, DynamicPropSource support, etc. are solved, the easier it becomes to reason about this. (#3499554: Move client-side assumptions about prop form data shape into a series of prop-specific transforms just landed!)
Comment #32
wim leersRelated: #3494545: [later phase] SDC must be able to specify minimum dimensions for a prop receiving an image — many image-consuming SDCs would likely not provide their own default images, but would rather instead have generic images generated that show the maximum resolution?
Comment #33
larowlanThe root of the issue here is that we map the image property to an entity reference field of type media, but set a default value that is a hard-coded URL - suggesting that in fact this could/should be a URI field. But we want to use the media library to edit the values. So we're in a state where the component has a default value that doesn't match the data shape (field type) we've specified. We work around this with ::findTargetForProps but this is a temporary workaround (And commented as such).
In HEAD we try to reconcile this by at least ensuring that a media entity exists with the given default image URL - but as discussed in this issue, that isn't working in all cases.
We're trying to resolve this on multiple fronts.
- #3499550: Support server-side massaging and validating of ComponentInputsForm values
- #3493943: SDC+JS Component Sources: split default values into `resolved` and `source`
However those are both very tricky. I'll have a think about what we can do in the meantime
Comment #34
larowlanCame here to post a reference to #3468944: Update XB's `image` SDC to comply with best practices, and document those best practices and then realised Wim already had 😀
Comment #35
larowlanI think we also have a disconnect in our components API with what we store in the config entity
Here's what's in the components api for the default value for the image component - this is taken from the example in the component.yml file.
But here's whats in the config entity:
And this is because
\Drupal\experience_builder\Plugin\ExperienceBuilder\ComponentSource\GeneratedFieldExplicitInputUxComponentSourceBase::getClientSideInfospecial cases the a prop with $ref'json-schema-definitions://experience_builder.module/image'And I also think that reveals a possible solution for us here as follows:
\Drupal\experience_builder\Plugin\ExperienceBuilder\ComponentSource\GeneratedFieldExplicitInputUxComponentSourceBase::getPropsForComponentPluginwhich is called fromupdateConfigEntityandcreateConfigEntity.'json-schema-definitions://experience_builder.module/image'in\Drupal\experience_builder\Plugin\ExperienceBuilder\ComponentSource\GeneratedFieldExplicitInputUxComponentSourceBase::getClientSideInfo\Drupal\Core\Config\ConfigEvents::IMPORT_MISSING_CONTENTgets fired on a config import\Drupal\Core\Config\ConfigEvents::IMPORT_MISSING_CONTENTto take care of creating the missing media entity in a deployment based on these settingsfindTargetForPropstooi.e. tl;dr move the special casing of
'json-schema-definitions://experience_builder.module/image'from out of\Drupal\experience_builder\Plugin\ExperienceBuilder\ComponentSource\GeneratedFieldExplicitInputUxComponentSourceBase::getClientSideInfoand into\Drupal\experience_builder\Plugin\ExperienceBuilder\ComponentSource\GeneratedFieldExplicitInputUxComponentSourceBase::getPropsForComponentPluginand also have it replace the code inexperience_builder_install- but in a way that supports config deployments.If this seems like a reasonable idea I can do a spike on it.
Most of this seems to have todo's in the code so it might be time to pay down these debts
Comment #36
lauriiiIs there really not a solution that wouldn't involve importing images to media library? As I already pointed out in #27, I don't think adding default images from components to the media library is part of the ideal experience.
#29 is pointing out that the limitation is that the image URI must be either:
Could we not then allow the default value to remain either:
Then we would transform the component-relative URI to a root-relative URI before it actually gets rendered.
Where does this requirement come from? Why can we not allow images coming from image hosting services?
Comment #37
lauriiiI think that's right, at least in the site where the component was built. I would imagine that #3500017: Defining props for code components would be using media / image upload for uploading default images and therefore they would end up in the media library. I think in the case of a config deployment, it would make sense to create the media or file entity.
However, in future we may allow exports and imports of a component. In this scenario, it might not make sense anymore to add the image to the media library because the image may not have anything to do with the site where it gets imported.
It looks like https://wordpress.org/patterns/ is using remote URLs for the images so that the component can be simply copy pasted.
Comment #38
longwaveIn #27 @lauriii states that the default image should not end up in the site's media library. It's not even guaranteed that media library will be used for media storage in the Acquia DAM case.
Instead of trying to store the default image as a media entity I'm wondering if it would be worthwhile having a custom image controller that renders default images for any component. This image can still be stored as base64 in the config entity but it otherwise doesn't need to exist on disk or as a content entity. If the prop value is empty, then we output the URL that points to this custom controller.
Optional images are still awkward though. If optional images have a default example, what do you use to tell the difference between the user wanting no image at all and the default image to be shown?
edit: crosspost with @lauriii!
Comment #39
wim leersYep, agreed with #33.
I'd prefer to have @larowlan continue on #3499550: Support server-side massaging and validating of ComponentInputsForm values (reviewed in-depth today) and other #3467954: META: Evolve XB UI's data model to allow non-SDC components' inputs, DynamicPropSource support, etc. child issues, because it'll make the correct solution here clearer.
The code @larowlan is quoting in #35 is being touched upon by #3493941: Maintain a per-component set of prop expressions/sources — which is yet another child issue of #3467954.
Will follow through in-depth here tomorrow, with hopefully #3467954 committed and #3499550 close. 🤞
P.S.: Quoting
\Drupal\experience_builder\Plugin\ExperienceBuilder\ComponentSource\GeneratedFieldExplicitInputUxComponentSourceBase::getClientSideInfo()(which was moved multiple times but dates back to the very early XB days):This was discussed at length with @longwave, @effulgentsia, @lauriii and others in a call earlier today, in which @lauriii mentioned that XB would need to use a custom
MediaLibraryWidgetanyway, which would likely make this easier to solve. He was going to write a comment about that and related aspects. He hasn't yet, but I assume he still will.Comment #40
lauriiiDiscussed this at length with @longwave, @wim leers, and @effulgentsia. We essentially identified four scenarios that we need to support and whether we'd expect the default images to appear in the media library:
In order to accomplish this, we'll add support for scenario 1. by using the JSON Schema default annotation.. This would essentially allow specifying a default image which would not show up in the form, but would be loaded as the default value in the field.
Scenario 4. is a future consideration because we don't have the option to export code components outside of regular config currently. We can fallback to the behavior from scenario 3. until then.
In future, we may consider adding support for JSON Schema examples values for images. This would require being able to display a non-media library in the field widget. This depends on finishing designs for the media widget.
Comment #41
larowlanIn #3499550: Support server-side massaging and validating of ComponentInputsForm values I've managed to do away with
::findTargetForPropsonce the user selects something from the media libraryHowever I've had to retain it for the use-case when the user adds a new image component because the default value is invalid
This reinforces my comment above
I think until we have a way to reconcile those two we're at an impasse. Either we're storing a media reference OR we're storing a URL.
And perhaps that points to us needing a custom field type - a compound field that is an ER with additional columns/properties for src/alt/width/height.
On client projects we've successfully built compound fields that extend from ER and make use of the media library - but it requires the Media library form element to build a custom widget for it.
Comment #42
wim leers#40:
defaultvsexamplesto indicate that thedefaultshould be used for generating thedefault_markupwithout putting it in the Media Library is nice, but it's not a full solution.Note that SDC does itself not support/use
defaulteither — see #3462705-19: [META] Missing features in SDC needed for XB and #3462705-26: [META] Missing features in SDC needed for XB.But we in XB can support it anyway, by changing
GeneratedFieldExplicitInputUxComponentSourceBase::getClientSideInfo()— easy enough!Except … what @larowlan wrote in #41 means we likely can't. Because before we can "just use the SDC-specified
default), we MUST apply a transformation, because even in the best case scenario where the SDC includes an image for which a publicly accessible URL can be generated, it still must be generated. So perhaps specifying it asdefault: https://example.com/path/to/sdc/cat.jpgwould be the way to specify in the*.component.ymlthat thecat.jpgimage file included in the single directory should be loaded.(And no, a root-relative URL doesn't work either, because Drupal could be installed in a subdirectory, and there's multiple possible file system locations for modules/themes to be installed.)
#41: I think @lauriii's #40 didn't explain in sufficient detail how he imagined it'd work. See the first sentence of my response to #40.1. To expand on that: @lauriii wrote
But I think he meant "the SDC
defaultwould not show up in the Media Library widget" and "would be loaded as the default value in thedefault_markup" aka component preview.IOW: regardless of whether the image is optional or required, the image specified as
default(and with the transformations needed as mentioned above) would NOT be stored in the component tree and hence would also never need to live in the Media Library.That means
does not need to be true … anymore! 😅
Doing that does create a new challenge: we may end up storing an instance of the
sdc.experience_builder.imageComponentin thetreewithout any correspondinginputs🫣ValidComponentTreeConstraintValidatorrequires each component instance intreeto have a corresponding entry ininputs. But we can relax that a bit:could be modified to also allow the inputs for the component instance to be absent if for every of the required SDC props, a
defaultis specified.This may require adjusting both the semantics and implementations of
GeneratedFieldExplicitInputUxComponentSourceBase::requiresExplicitInput(), or might require an additional method.I do not like any of this though; it makes the entire XB data model harder to reason about.
Comment #43
lauriiiThank you @wim leers for expanding #40! I tried to make a quick comment at the eleventh hour to avoid blocking folks.
FYI, this would be probably temporary because once we have support for image examples, we'd want to enforce in this scenario that required images have been uploaded. This is actually nice because it allows showing a default image while still requiring the content creator to select an image. Pointing this out because I'm trying to avoid us taking a difficult path for a temporary solution.
Comment #44
wim leersI was thinking about exactly this and hoping that you'd not say this.
Because it introduces a major new consequence that everything in XB was carefully designed to avoid.
(We faced a similar challenge with https://drupal.org/project/quickedit btw.)
Comment #45
lauriiiYou're right, we've designed the UX to avoid exactly that 🤦♂️ We should avoid reversing that because it will have major consequences on the UX.
Let's simplify this and work for now with the assumption that default cannot be used for required images, that way the field can be left empty in which case it falls back to the default image. I think that's an acceptable state until we've figured out support fo image examples, which would allow marking images as required.
Comment #46
wim leersComment #47
wim leersDiving into the deep end of this. 🤿
Step 1: where does the current default value come from?
The default value that appears on the client side for the
sdc.experience_builder.imageComponentis:It is provided by
GeneratedFieldExplicitInputUxComponentSourceBase::getClientSideInfo(), which does this:The special casing of
type: string, format: date-timeis irrelevant here. This issue is solely about$ref: json-schema-definitions://experience_builder.module/image.image.component.yml.$default_value = $this->getDefaultStaticPropSource($prop_name)->evaluate(NULL);like everything else? (Excepttype: string, format: date-time?Step 2: why can't we evaluate the
Component'sStaticPropSourcethat uses the stored default value?The relevant logic was last touched in a significant way in #3463999: Auto-create/update Component config entities for all discovered SDCs that meet XB's minimum criteria. It was moved to a different class a few times since (first due to adding support for blocks, then for "code components"). It's now at
GeneratedFieldExplicitInputUxComponentSourceBase::getPropsForComponentPlugin()and contains:That
is why there's no default value!
And the reason for that is that there's:
Fileentity for the SDC's example value (when the Media Library module is not installed and hence using theimagefield type)Mediaentity for the SDC's example value (when the Media Library module is installed and hence using an entity reference field pointing to image media, seemedia_library_storage_prop_shape_alter(), but note that ever since #3474226: Make Media Library a dependency XB is requiring the Media Library module to be installed for simplicity sake)… to use as the default value!
⚠️ Note that it's impossible for an SDC to specify a working image URL, except to external services. Reliance on an external service is unacceptable.
hook_install()to ensure it exists) in https://git.drupalcode.org/project/experience_builder/-/commit/0603b8636...Next step: allow the default used in the preview to be different from the default used in
::getDefaultStaticPropSource().Comment #48
wim leers— https://git.drupalcode.org/issue/experience_builder-3501902/-/commit/129...
Thanks @longwave for continuing what I started! 😄🙏
To do:
ApiPreviewControllerneeds to detect that for the image componentresolved ===[], and populate it with the same default value that::getClientSideInfo()generated to generate the preview in the first place.Then it'll work!
(And then it'll need refinement, and ideally #3493943: SDC+JS Component Sources: split default values into `resolved` and `source` would happen first.)
Comment #49
wim leersScreenshot of where I left things when I passed it on to @longwave:
Comment #50
wim leersStill needs refining, but it's now partially working, after pairing with @longwave on it: https://git.drupalcode.org/issue/experience_builder-3501902/-/commit/d92...
But as you can see, the Media Library does not yet open, although I do see the expected AJAX response:
🤔
To be continued tomorrow.
Comment #51
wim leersKeeping issue summary relevant. The current MR should do only one thing, but there's a second part to this…
Comment #53
longwave@Wim you forgot to add the new FallbackPropSource file so I rewrote it from memory :D
Also fixed up the
#disabledcode as it wasn't quite right. Time to actually open an MR here!edit: also rebased following #3499550: Support server-side massaging and validating of ComponentInputsForm values
Comment #55
longwaveGiven the MR fixes the issue described in the title, can we push solving the problem of handling/remapping default image URLs to a followup? The image component is no longer completely broken, just it relies on the hack in
experience_builder_install()to get the default image file to the right place.Comment #56
wim leers#53 😱🙈🤣
gitnoobAnd you got it character-by-character identical except for one line :O#55: Not opposed to that, but it does mean that the literal originally reported issue does not get fixed. How about we just do 2 MRs for this single issue? And just merge this first MR … first? Avoids issue queue overhead.
The issue title has been lacking precision since the start, which adds to the confusion. I'll think of a better title with a fresh head in the morning.
Comment #57
wim leersI was thinking about this some more last night.
When and why do we need this
FallbackPropSource? We need it for:preview purposes, never storage purposes
never for booleans, integers, or numbers
never for any string
formatother than one of theuri+uri-reference+iri+iri-referenceones: https://json-schema.org/understanding-json-schema/reference/type#format… and even then, only when they must be resolvable/fetchable, to make certain tags work:
<img>,<video>…So AFAICT these special needs do not apply to anything else. The most common "resolvable URL" case is links (
<a href="<SDC PROP HERE">link text</a>), but there it doesn't apply either, because the URL does not have a visible impact: a dummy URL would do just fine for preview purposes!Although, come to think of it: a "call to action" component would want to have a required link, without wanting that link to ever be saved? So, perhaps there is a difference in preview impact (image/video URLs vs link URLs), but the saving impact is the same: nobody wants links pointing to
https://example.com/campaign, right? :DGiven all that, I think that
UrlPreviewPropSourcewould be a better name, that is much narrower and hence better captures both the need and when it is appropriate.Comment #58
wim leersI believe I see a solution for
in ~100 LoC (nutshell: require example values to start with
https://example.com, add new method toComponentSourceto rewrite such example values to resolvable URLs):The only thing that's still missing: updating
\Drupal\experience_builder\ComponentMetadataRequirementsChecker::check()to requireexamplesvalues fortype: string, format: uri|iri|uri-reference|iri-referenceto start withhttps://example.com.See the second branch:
600x400.pngsample image: https://git.drupalcode.org/issue/experience_builder-3501902/-/commit/bf1...P.S.: this also paves the path for examples for images to become optional if min/max dimensions are specified, then we could auto-generate a relevant sample image. See #3494545: [later phase] SDC must be able to specify minimum dimensions for a prop receiving an image.
Comment #59
longwave#57 makes sense! Great insight to limit this to URLs - but so that it works for links as well as images - and the
https://example.com/prefix is also a fantastic idea.I think we could just work on this in a single MR now? I don't see the point in keeping two separate ones if we are going to solve both problems here.
Comment #60
wim leersWFM! :D Go ahead and merge as far as I'm concerned :) But … I think it'd be better/simpler to first get tests to pass on the current MR? 😇 That keeps the focus on the most important thing?
Just walked @lauriii through what I did in #58 (at the end of a meeting about something else). He VERY much does not like the
https://example.comprefix 😅 He agrees with the overall approach, but just explicitly doesn't like that prefix.I respectfully disagree, but given @lauriii has a much stronger front-end development past than I do, I defer to him 😊
Done: https://git.drupalcode.org/issue/experience_builder-3501902/-/commit/457...
Comment #61
longwaveStarted going too far with this and almost tried to solve #3493943: SDC+JS Component Sources: split default values into `resolved` and `source` as well, but that wasn't as easy as I first thought (I should have learned by now) so I rolled back those changes and concentrated on only the image problem here.
Will merge in the second branch now.
Comment #62
longwaveReworked as discussed with @wim.leers, @effulgentsia, @f.mazeikis - the leading slash is not even required so any example file is relative to the SDC itself. If the file exists then the full path to it is given (e.g. for an image src), if the file doesn't exist then it is treated as relative to the root of the site. Added test cases for both these, with and without leading slashes.
Comment #63
wim leers#62 is actually what @lauriii expressed on the meeting I had with him as his ideal.
Comment #64
wim leers+1'd your idea for a separate interface, that has LOTS of nice consequences — see my MR comments 😊
Comment #65
lauriii@wim leers asked me to test this with more permutations to get a sense where we are:
I'm getting this error when I try to place "Container" element from demo design system. It has an optional image without an example.
AssertionError: assert(\is_array($this->value)) in assert() (line 78 of /var/www/html/web/modules/contrib/experience_builder/src/PropSource/FallbackPropSource.php).Placing the "Hero" component which has an optional image with an example value works but the media library doesn't open when I click "Add media". If I change other props than the image, the default image is lost.
Comment #66
longwave@lauriii The issue with the demo Hero should be fixed, I can't reproduce locally. However the problem with the demo Container is that it specifies an image without an example:
but Experience Builder's
imageschema says thesrcproperty is required:This causes a validation error because when you first add the component the image doesn't have a src. If an example was specified (as in the XB image component) then we use that as the fallback, but there is nothing to fall back to here either.
Other than this, the tests should be passing now and all of Wim's feedback should be implemented.
Comment #67
larowlanThis looks good to me, I manually tested it and confirmed it is working as expected.
I also tried to remove ::findTargetForProps and confirmed we cannot do that without #3493943: SDC+JS Component Sources: split default values into `resolved` and `source`
Comment #68
wim leers#66: That problem with the demo
containerSDC missing an examplesrcin itsjson-schema-definitions://experience_builder.module/imagepoints to a bug we haven't really seen before, because the onlytype: objectXB supports is that image shape.The problem:
\Drupal\experience_builder\ComponentMetadataRequirementsChecker::check()only checks for the presence of anexamples[0], but it does not verify that it actually complies with the JSON Schema!👉 New issue created, with detailed plan: #3507641: Allow components containing non-required images and no examples to be placed.
Comment #70
wim leersLooks great!
All I did was:
Will merge after green CI 👍
Comment #72
wim leersComment #74
wim leersFollow-up to tighten things, after this and a related issue landed: #3507749: Clarify default 'resolved' vs 'source' value logic in GeneratedFieldExplicitInputUxComponentSourceBase::getClientSideInfo().
Comment #75
lauriiiLooks like the bug which I reported in #65 where the default image is lost when changing props is still happening: #3508077: Default image for SDC with optional image is lost after changing value for another SDC prop.
Comment #76
wim leers#75: I explained in #68 that it's out of scope here, and opened #3507641: Allow components containing non-required images and no examples to be placed for it.
Comment #77
nagwani commented