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

Command icon 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

fago created an issue. See original summary.

wotnak made their first commit to this issue’s fork.

wotnak’s picture

Status: Active » Needs review
fago’s picture

Thank 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.

fago’s picture

Status: Needs review » Needs work
wotnak’s picture

Status: Needs work » Needs review

IDs 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.

fago’s picture

Thank you! That makes sense.

Changes look all good and solid now. Will do some manual testing and regression testing before merge!

  • fago committed 2492d7bd on 3.x authored by wotnak
    feat: #3580092 Add support for json-render output format
    
    By: wotnak
    
fago’s picture

Status: Needs review » Fixed

ok, 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!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.