Motivation
Idea: Add support for json-render specs as output format next to markup and json. When outputting as json-render, it would be super-easy to wire up the output if any support json-render adapter (react, vue, solid, svelte, ...) to render custom elements.
Steps to reproduce
Proposed resolution
Remaining tasks
User interface changes
API changes
Data model changes
Issue fork custom_elements-3580092
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 #4
wotnakComment #5
fagoThank you!
This looks quite solid already. I added some comments to the MR, please check.
A couple of questions:
- ID generation. Can we shorten IDs to be just the number? And is it important they are consistent across multiple requests? I'm wondering whether there might be issue if content is fetched lazily and elements are added to a pre-existing rendered tree and numbers are overlapping? Do we need to ensure they are unique across multiple requests coming from the same browser/client-side instance?
- Why does this special-case drupal-markup in normalization? I noted it's not doing the special-casing of empty div/span wrappers, maybe it became necessary because of that?
> Empty div/span slot wrappers are omitted from explicit output.
It's a bit of a legacy, but custom-elements is adding the "div" tag also some-times when slotted html is passed in.
Comment #6
fagoComment #7
wotnakIDs are references scoped to a single json-render spec. They only need to be unique within that spec and are not intended to be stable across requests. This matches json-render nestedToFlat() implementation, which starts a new counter for each generated spec.
I shortened the IDs in 5dab7680, but I would not use just numbers to avoid issues with elements map being encoded in JSON as an array instead of an object.
Independently fetched specs can safely reuse IDs when rendered separately. Merging a fetched spec directly into an existing tree would require namespacing or re-keying the added elements to avoid collisions. We could potentially use UUIDs as keys to make them all unique but that would make all keys quite long.
The `drupal-markup` special case exists because json-render children/slots can contain only references to other elements, inline HTML is not supported. The normalizer wraps inline HTML from any slot in a `drupal-markup` element. When the source element is already `drupal-markup` and stores HTML in its default slot, the special case moves that HTML into the `markup` prop.
Comment #8
fagoThank you! That makes sense.
Changes look all good and solid now. Will do some manual testing and regression testing before merge!
Comment #10
fagook, ran a regression test on the full test-suite on our internal decoupled setup. all green :)
It works well together with lupus_ce_renderer also, if you switch over to it, you can use it together with json-render. nice!
For supporting in on the vue side this would need some work, but I let an agent do a first experiment:
https://github.com/drunomics/nuxtjs-drupal-ce/pull/534#pullrequestreview...
So all great, merged! Thank you!