Problem/Motivation
#3452512: Add component instance edit form to contextual panel lifted relevant parts of #4's https://www.drupal.org/project/jsx into this module.
While /themes/engines/semi_coupled/README.md exists in the XB module, now that #3454094: Milestone 0.1.0: Experience Builder Demo is done, we need expanded docs:
- an explicit
/docs/Redux-integrated Field Widgets.md, for better discoverability - an accompanying
Redux-integrated Field Widgetsissue queue component - Retitling the
/CODEOWNERSentry accordingly:
[semi-coupled theme engine] @bnjmnm @hooroomoo @effulgentsia /src/Theme/XBThemeNegotiator.php /themes/engines/semi_coupled/ /templates/form/ /ui/src/components/form/
Et cetera.
User interface changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #51 | semi-coupled-journey-2.png | 1.55 MB | bnjmnm |
| #43 | SEMI-COUPLED-JOURNEY.png | 1.84 MB | bnjmnm |
Issue fork experience_builder-3446434
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
larowlanComment #3
pdureau commentedI am copy pasting my slack message here, because I belive it is a better place to have such dicussion.
Compiling Twig to JSX sounds like a complicated and risky task. The models don't fit, for example:
Also, we will meet the issues mentioned in Slack:
attributesor any object implementingRenderableInterface?{% if x %} <div ...>{% else %} <div ...>{% endif %}</div>?Why not embracing the current "back to hypermedia" trend and keep the rendering server side? We already have a proposal about HTMX replacing the AJAX system, and we can start from this or any similar technology.
While keeping the goal of live editing with immediate previews, it will solve the dual (server/browser) implementation issue, with simpler codebase and better performance.
Comment #4
wim leersFirst: thanks for opening this issue! 😄
Do you know about https://www.drupal.org/project/jsx?
@bnjmnm has built a working PoC for this, with Drupal-defined (Form API-defined) field widgets being rendered — unmodified! — in React. See https://git.drupalcode.org/project/experience_builder/-/commits/eb-form-....
IIRC there also was a demo of the JSX theme engine rendering Twig and React components interspersed — a tree of both React components and Twig templates, with no restrictions on which is where.
Assigning to him to respond here :) Would be a shame to duplicate work.
Comment #5
pdureau commentedAnother solution for dual rendering (server side / client side) would be to compile the renderer service + template engine into WebAssembly and to run the exact same code server side (wasm loaded by PHP) and client side (wasm loaded by the browser JS engine).
I already have a working implementation to show if you are interested.
Comment #6
wim leersInteresting, @pdureau, I'd definitely love to see that! I defer to @jessebaker, @bnjmnm, @effulgentsia and @lauriii to decide whether that's a direction we should pursue.
Comment #7
pdureau commentedToo bad we are not meeting in Brussels today ;)
I did a demo yesterday to some people from #experience-builder channel. Here are my notes.
Comment #8
wim leers@pdureau fortunately got to meet a few days later :)
Comment #9
wim leersThis is not something we're working on in the short term; @bnjmnm is working on more urgent things, so unassigning and updating issue status.
We'll revisit this at a later time.
If in the mean time anybody starts experimenting: see #4, and talk to @bnjmnm. 🙏
Comment #10
wim leers#3452512: Add component instance edit form to contextual panel lifted relevant parts of #4's https://www.drupal.org/project/jsx into this module.
AFAICT that means this is now irrelevant.
While
/themes/engines/semi_coupled/README.mdexists in the XB module, I think now the time has come to expand this to:/docs/Redux-integrated Field Widgets.md, for better discoverabilityRedux-integrated Field Widgetsissue queue component/CODEOWNERSentry accordingly:Thoughts, @effulgentsia?
Comment #12
wim leersDiscussed with @effulgentsia. He's +1 to the overall proposal. He does think the current title is too narrow though. I'll think about that some more while I get an MR up :)
P.S.: conceptual sibling issue: #3450496: Clarify the "shape matching" bits: namespaces, `CODEOWNERS` and as issue queue component.
Comment #13
effulgentsia commentedThe title I'm thinking of is maybe something like "Redux-integrated XB-cohesive Field Widgets". Maybe there's a better term to use than "XB-cohesive" but the concept is that we want the field widgets rendered as React components not only for the Redux integration, but also to be able to style them and/or add JS behaviors to them in a way that makes the props edit form look and feel cohesive with the rest of the XB app. While it might be possible to achieve that with Drupal's traditional JS/CSS/library system, I think it's easier to achieve it via the same React toolchain (JSX, CSS modules) as the rest of the app. Maybe this is moot though if the Redux integration alone sufficiently justifies and clarifies the need to render the widgets as first-class React components.
Comment #14
wim leers#13: thanks! That makes sense.
Perhaps we need two components?
React-integrated Render APIorReact-app-as-a-themeRedux-integrated Field Widgets, which uses 1.Comment #16
wim leersI'll first bring clarity to the status quo:
[semi-coupled theme engine] @bnjmnm @hooroomoo @effulgentsiais already inCODEOWNERS, so I'll start with that name — while we bikeshed the precise name (see #13 + #14.1)Redux-integrated Field Widgets(see #14.2)Comment #18
wim leersThanks to these 2 commits:
The
experience_builder.modulefile is now roughly half as large as it used to be — from 583 lines to 317 lines. If I apply the same pattern to the 3 hook implementations for theShape matchingfunctionality, it'll go down to 224 lines. Each of the 3 include files then is 100–200 LoC.Regardless of the size of each individual file, the more important objective is that this makes it much easier to convey what all these hooks are for:
*.incfile@seepointing to the issue queue component@seepointing to the docsComment #19
wim leersSince #18, I've:
/docs/redux-integrated-field-widgets.md/docs/semi-coupled-theme-engine.md(based on/themes/engines/semi_coupled/README.md!)/docs/data-model.md/CODEOWNERSI still need to get tests back to passing, but only a single test is failing.
@bnjmnm is the person best positioned to complete the first two points.
This also really needs @bnjmnm's +1 for overall direction. But at least this MR now makes it clear how I think this should evolve, to better allow onboarding/participating/understanding of this critical piece of Experience Builder!
So assigning to @bnjmnm for review 😊
Comment #21
wim leers@bnjmnm had a hunch: maybe
experience_builder_module_implements_alter()not living in the*.modulefile made a difference in preprocess hook execution order? Moved back to the*.modulefile temporarily: it did not make the test pass.I had one more hunch: just move the preprocess hook back to the
*.modulefile temporarily: it did not make the test pass.I don't know what tiny detail is causing this to fail tests, but it sure as hell is massively distracting. So…
require_once+@todoit is: https://git.drupalcode.org/project/experience_builder/-/merge_requests/3... — we can figure out that part later.Comment #22
longwaveI figured out the breakage, I don't think hook_hook_info is intended for this situation and require_once is fine.
Comment #23
longwaveSemi-Coupled is a strange term to me; this is bikeshedding but should this just simply be called the "Twig JSX" theme engine, given those are the two things it supports? I even wonder if one day it's worth spinning out to its own module as it might be useful outside of XB for other projects that want to use React in Drupal.
Comment #24
bnjmnmI'm sure there's more work to be done on the Semi Coupled docs, but this is a good point to get other eyes on it then I can address points of confusion and other feedback.
Comment #25
wim leersGlad to see this moving forward swiftly! 😊
Comment #26
longwaveI discussed the approach so far of the new theme engine and widget implementations with @bnjmnm. While neither of us are entirely happy with the current implementation of the theme engine, it's certainly good enough for now in order to unlock the ability to build forms in Drupal and present them inside React. The technical details can be cleaned up and/or improved later, I don't think anything that's been done so far has painted us into a corner in any way. I think it's possible that we may not even need a separate theme engine here and could decorate various theme-related services in order to extend them for XB to consume, but for now we have bigger problems to try and solve.
The widget implementations are tricky: the goal is to find a generic solution to map any Drupal widget into a set of React component props, and back again, ideally without requiring custom code on the React side - we both agree that the solution should lean into the server side where possible for mapping data back and forth. This will help contrib and custom code developers avoid having to write any React to integrate with XB.
Comment #27
brianperryReviewed and commented on the in progress docs MR.
Comment #28
wim leers@longwave in #26: thank you for summarizing your high-level perspective after digging into this together with @bnjmnm. That's very helpful, and already helps make it easier for additional contributors to get a sense of where this is at and where it's going :)
@brianperry Thanks for reviewing these docs at this early stage, you asked a number of good questions that should make these docs more easily digestible for the next person! 😄👍
@bnjmnm This is definitely on the right track! 👏 I think there's sufficient feedback from @longwave, @brianperry and I now that it's worth you continue this and push it across the finish line. Based on @longwave in #26, it sounds like the two of you discussed the Redux parts and have some clarity/perspective on how that should evolve. Now let's make sure that is captured in the docs too 🙏
Comment #29
wim leers(I've told Ben this previously in a meeting, and I failed to record this in public. 🙈 Rectifying that now!)
I also expect these docs to outline that we will add support for:
\Drupal\datetime_range\Plugin\Field\FieldType\DateRangeItem)\Drupal\datetime\Plugin\Field\FieldWidget\DateTimeDefaultWidgetfor\Drupal\datetime\Plugin\Field\FieldType\DateTimeItem)MediaLibraryWidgetand its hardcodeddata-media-fileattribute added byexperience_builder_preprocess_media_library_item__widget()and hence requiring AJAX)processedfield property of\Drupal\text\Plugin\Field\FieldType\TextLongItem)… perhaps more in the future.
If there's a solution that @bnjmnm already has in his head, then I'd like a high-level explanation for it in this MR. When there's an issue link, I'd like to see that in the
docs/*.mdfile (just like we did fordocs/data-model.md— you can find the missing/uncertain bits by looking for the warning sign emoji: ⚠)Comment #30
bnjmnmThere might be glaring issues I failed to notice due to documenting-fatigue but I think this is a good point to officially NR it. It's a huge step in the right direction, so perhaps the main goal here could be making sure nothing is flat-out wrong. We can iterate on the quality later (and as the functionality evolves)
Comment #31
balintbrewsHappy to review this.
Comment #32
balintbrewsI reviewed the docs, improved punctuation and language, added a couple of links, and extended the
hyperscriptifyexample code snippet. I think the content has the right level of details and is easy to follow. I hope that's helpful! 🙂Reassigning for reviewing backend changes.
Comment #33
balintbrewsComment #34
wim leersI've seen:
And AFAICT they're all pointing to the same thing? That's confusing, especially for somebody not deeply familiar with React/JSX. Let's use one term consistently 🙏
Comment #35
wim leersI've addressed most of my own feedback.
Most important changes:
I think the only thing that remains is for @bnjmnm to review (and hopefully approve) the MR — it's totally possible I introduced factual errors, especially WRT #34 and in the last bullet above.
Actually, the updates to
semi-coupled-theme-engine.mdfor #34 are incomplete (I didn't want to push this too much in the wrong direction 😬😅). But the updates toredux-integrated-field-widgets.mdare complete, and should only need review/approval/corrections.Comment #37
wim leersAlready created the issue queue components 👍
Comment #38
bnjmnmComment #39
wim leersComment #40
wim leersHopefully the combination of:
… will allow you to leave this in a place with little additional of your time, but where you also feel better about the state of it than before 🤞
Comment #41
bnjmnmComment #42
wim leersNot all of my feedback from yesterday has been addressed yet — reflecting in issue metadata — whoops!
Comment #43
bnjmnmGood News I think this image helps make sense of some of the more confusing bits
Bad-ish News (more work.. but better code) Seeing it mapped out like this made it clear there are some additional changes I should probably make to make the DX less confusing.
Comment #44
wim leers@bnjmnm that image! 🤩 👏
Observations/questions:
$variables(first column) to the-xbxb.html.twigfile? (second column) I think this will also make it clear that it's possible that not every variable is necessarily consumed.data-drupal-scriptifiedthere? That only happens on the client side, and AFAICT this image is illustrating what happens on the server side?console.log-style output? That'd show more.<drupal-html-fragment>s for those parts of the render tree that do not have a React mapping(Reminds me of https://wimleers.com/talk/drupal-8-render-pipeline by the way :D)
Comment #46
wim leers@bnjmnm already leaped ahead in #45 and created a new MR assuming #3478287: Introduce the `xb_stark` theme that uses the Semi-Coupled theme engine, removes the need for taking over the Twig theme engine for the whole site would land any moment. Good call! 😄👏
That now did land, so I believe that we can now prominently see the light at the end of this Alice-in-Wonderland-like tunnel 😁
Comment #48
wim leersComment #49
bnjmnmStill working on editing the image from #43 it's a chungus Photoshop file.
Comment #50
bnjmnmComment #51
bnjmnmIt's probably not all there yet, but this is where i leave off today. The PSD file is available for anyone to edit a copy, too.
Comment #52
bnjmnmComment #53
bnjmnmIn #3485692: Create extendibility proof of concept that also serves as documentation-by-example (extensions) I've added a test module that provides a barebones implementation of the Semi Coupled theme engine . I think we're running into a usefulness plateau with attempting to explain it all in a single document, and routing some of that documentation to the test module might prove more helpful.
I also added #3485645: Create readme for hyperscriptify library to create a Readme for Hyperscriptify so that explanation lives within the package that provides the functionality. We can certainly link to it etc but I think having it with the package can help demonstrate that the functionality it provides is not reliant on XB or Drupal.
Comment #54
effulgentsia commentedDiscussed this with @longwave, and one big next step here besides general review is to create tests that surface the difference cases where there isn't a 1:1 map between field values, prop values, and widget values. @longwave offered to start on that.
Comment #55
bnjmnmCan we make those separate issues that are referenced here? Aside from this being a large review already, there are major changes to the .module file that require quite a bit of manual steps to reroll.
Comment #56
longwaveOpened #3487284: [META] Add explicit end-to-end test coverage for using all core field widgets including multiple cardinalities in the "Page Data" (content entity) form to spin out the field widget discovery to a separate issue.
Comment #57
longwaveLet's get this refactoring + docs update in here and work on expanding the knowledge about field widgets in the followup issue.
A question about valid HTML but otherwise this looks good to me.
Comment #58
bnjmnmComment #59
effulgentsia commentedThis looks really good and I'm ready to merge it, but it needs a reroll. Hopefully the last one :)
Comment #60
effulgentsia commentedActually, looks like it didn't need a reroll, just merging from 0.x, but now tests are failing.
Comment #63
lauriiiThe MR was missing few use statements which led into the CI failures. The fix was simple enough so I went ahead and merged this with the fixes.