Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interactivity API: Server Directive Processing #5953

Closed
wants to merge 59 commits into from

Conversation

luisherranz
Copy link
Member

@luisherranz luisherranz commented Jan 26, 2024

Trac ticket: https://core.trac.wordpress.org/ticket/60356


This PR backports the Server Directive Processing of the new Interactivity API for WordPress.

The Interactivity API enables WordPress developers to create dynamic and interactive web experiences with ease using a set of special HTML attributes called directives. Please refer to the Interactivity API proposal for further details.

This API processes the interactivity directives embedded within HTML content and transforms the markup in the server, seamlessly merging the server-rendered markup with the client-side interactivity to guarantee that:

  • Users view the correct HTML before the JavaScript loads.
  • There are no layout shifts when the JavaScript finally loads.

API

wp_interactivity_state( $store_namespace, $state )

Sets or gets the initial state of an interactivity store.

This state is used during the server directive processing and then is serialized and sent to the client as part of the interactivity data to be recovered during the hydration of the client interactivity stores.

Once the user starts interacting with the page, the actions contained in the stores will update this state, and the Interactivity API runtime will transform the markup accordingly.

// Sets the initial state for the 'myPlugin' namespace.
wp_interactivity_state( 'myPlugin', array( 'counter' => 0 ) );

// Gets the current state for the 'myPlugin' namespace.
$state = wp_interactivity_state( 'myPlugin' );

wp_interactivity_config( $store_namespace, $config )

Sets or gets configuration for an interactivity store.

This configuration is also serialized to the client, but it's static information about the page/site (it's not reactive).

// Sets configuration for the  'myPlugin' namespace.
wp_interactivity_config( 'myPlugin', array( 'setting' => true ) );

// Gets the current configuration for the 'myPlugin' namespace.
$config = wp_interactivity_config( 'myPlugin' );

wp_interactivity_process_directives( $html )

Processes directives within HTML content, updating the markup where necessary.

$html_content = '<div data-wp-bind--text="myPlugin::state.message"></div>';

// Process directives in HTML content.
wp_interactivity_state( 'myPlugin', array( 'message' => 'hello world!' ) );
$processed_html = wp_interactivity_process_directives( $html_content );

// output: <div data-wp-bind--text="myPlugin::state.message">hello world!</div>

Filter: wp_interactivity_process_directives_of_interactive_blocks

This function hooks into WordPress's block rendering pipeline, identifying the outermost interactive block in a hierarchy and marking it for directive processing after rendering. Subsequent nested blocks are ignored during this pass because their output is included in the root block's render. Once the root block's HTML is processed, the markup is transformed and ready to be sent to the client.

Feedback

Please share your thoughts, potential use cases, or any other input that could help us refine and enhance this feature. Use the Trac ticket or this pull request for discussions.

Thank you! 🙏

Remaining tasks

The code here is ready for initial reviews, but I'd like to finish a few tasks before considering it complete:

I'll work on them and report my progress here.


Follow-ups

This list of tasks is not as high priority and can be done in follow-ups:

Copy link

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • The Plugin and Theme Directories cannot be accessed within Playground.
  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

Copy link
Member

@sirreal sirreal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiline comments seem to be misaligned, I collected those in this review.

src/wp-includes/interactivity-api/interactivity-api.php Outdated Show resolved Hide resolved
src/wp-includes/interactivity-api/interactivity-api.php Outdated Show resolved Hide resolved
src/wp-includes/interactivity-api/interactivity-api.php Outdated Show resolved Hide resolved
Copy link
Member

@sirreal sirreal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few minor suggestions but this looks good in general.

@luisherranz
Copy link
Member Author

Thanks for the review @sirreal! I've addressed the feedback 🙂

@luisherranz
Copy link
Member Author

luisherranz commented Jan 31, 2024

I've removed the temporary module registration that was included in trunk until this patch was committed.

I've also opened a PR that adds the data-wp-each processor on Gutenberg. I'll sync the changes here once it's merged:

EDIT: @DAreRodz opened another PR with the data-wp-router-region processor:

Copy link
Member

@westonruter westonruter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Actually, I suggest consistently using hyphens instead of underscores for CSS class names and style handles.

@luisherranz
Copy link
Member Author

Nit: Actually, I suggest consistently using hyphens instead of underscores for CSS class names and style handles.

Sorry, I read the other way around 🤦‍♂️


Ok, this should be ready now!

Copy link
Member

@westonruter westonruter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

Copy link
Member

@westonruter westonruter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple additional nits on method naming.

@gziolo
Copy link
Member

gziolo commented Feb 8, 2024

Committed with https://core.trac.wordpress.org/changeset/57563. Thank you everyone for all help to make that happen 🎉

@gziolo gziolo closed this Feb 8, 2024
@luisherranz
Copy link
Member Author

Thanks, Greg! ❤️

A huge kudos to @DAreRodz, @SantosGuillamot and @c4rl0sbr4v0 for shaping the Interactivity API with me, to @ockham for the initial work on the server directive processing logic, to @dmsnell for his support with the HTML APIs, to @gziolo, @mtias and @youknowriad for their continued support and feedback on the APIs, to @westonruter, @felixarntz and @swissspidy for their support and their help shaping this for WP Core, and finally to @Poliuk and @rmartinezduque for their under the scenes work to make this API a reality.

I'm sure I forget people, but thanks to everyone for your support of this initiative. This is just the beginning, but I hope it adds value to all the WordPress users for many years to come 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants