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

Editor: Add extensibility to PreviewOptions v2 #64644

Merged
merged 7 commits into from
Sep 3, 2024

Conversation

lezama
Copy link
Contributor

@lezama lezama commented Aug 20, 2024

Extend Preview Dropdown with Plugin API

Resolves #25309

What?

This PR introduces a new API to extend the Preview dropdown menu in the post/page editor. It builds upon the work done in #50605, #36119, and #31984, focusing specifically on allowing plugins to add custom menu items to the Preview dropdown.

Key features:

  • Introduces PreviewDropdownMenuItem component for adding custom items to the Preview dropdown
  • Allows plugins to add menu items with custom titles and click handlers
  • Maintains the existing Preview dropdown structure while allowing for extensibility

Why?

This extension point allows for greater flexibility in preview functionality, enabling plugin developers to integrate custom preview options seamlessly into the WordPress editor. It addresses the need for varied publishing flows and tools, such as:

  • Custom format previews (e.g., AMP, social media shares)
  • Previewing content with different access restrictions or user roles
  • Specialized preview modes (e.g., dark mode, email format)

How?

  • Utilizes the existing ActionItem component from @wordpress/interface
  • Implements a slot/fill pattern to inject custom menu items into the Preview dropdown
  • Maintains the declarative nature of the API, allowing for future UI changes without breaking plugin implementations

Testing Instructions

  1. Import the PreviewDropdownMenuItem component in your plugin:
    import { PreviewDropdownMenuItem } from '@wordpress/editor';
  2. Implement a custom menu item:
    const CustomPreviewMenuItem = () => (
      <PreviewDropdownMenuItem
        onClick={ () => {
          // Your custom preview logic
        } }
      >
        Custom Preview
      </PreviewDropdownMenuItem>
    );
  3. Register your plugin with the custom menu item.
  4. Open the post/page editor and check the Preview dropdown for your custom menu item.
  5. Click the custom menu item and verify that your onClick handler is called.

Testing Instructions for Keyboard

  1. Open the post/page editor.
  2. Use Tab to navigate to the Preview dropdown button.
  3. Press Enter or Space to open the dropdown menu.
  4. Use arrow keys to navigate to your custom menu item.
  5. Press Enter to activate the custom menu item.
  6. Verify that the custom action is triggered.

Screenshots or screencast

No icon:

Screenshot 2024-08-20 at 1 55 05 PM

With icon:

Screenshot 2024-08-20 at 2 57 14 PM

More than one item:

Screenshot 2024-08-22 at 11 11 54 AM

Future Considerations

  • Allow for grouping of custom preview options
  • Enable custom preview canvas or sizes
  • Add support for item selection within custom groups

This PR lays the groundwork for these future enhancements while providing immediate value to plugin developers wanting to extend the preview functionality.

@github-actions github-actions bot added the First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository label Aug 20, 2024
Copy link

👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @lezama! In case you missed it, we'd love to have you join us in our Slack community.

If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information.

@lezama lezama marked this pull request as ready for review August 20, 2024 16:55
Copy link

github-actions bot commented Aug 20, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: lezama <[email protected]>
Co-authored-by: Mamaduka <[email protected]>
Co-authored-by: gziolo <[email protected]>
Co-authored-by: simison <[email protected]>
Co-authored-by: fabiankaegy <[email protected]>
Co-authored-by: youknowriad <[email protected]>
Co-authored-by: fumikito <[email protected]>
Co-authored-by: westonruter <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@simison
Copy link
Member

simison commented Aug 22, 2024

Unrelated to these code changes, but it's now more noticeable how the "new tab" preview is inset more compared to other items:

Screenshot 2024-08-22 at 11 11 01

Seems like a good follow-up fix in separate PR.

@simison simison added the [Type] New API New API to be used by plugin developers or package users. label Aug 22, 2024
@simison
Copy link
Member

simison commented Aug 22, 2024

@youknowriad @lezama :

  • Right now, this extends preview dropdown in post, page and site editors. What do you think about restricting v1 just to post editor. We can then see how it gets used, and allow extending page/post editor next up?
    • If we allow extending dropdown in all editors, we should figure out how plugin extenders can limit to just one editor, and how their custom code can know about the editor context.
  • Hesitant allowing custom icons yet, but not a strong opinion. Mostly thinking that later we want to allow multi-selections with check mark, and it's hard to tell how the icon API then should look like in that scenario.

@gziolo gziolo self-requested a review August 23, 2024 18:04
@fabiankaegy
Copy link
Member

Slightly off topic question here, but would we also be open to allowing extenders to define their own "Preview" modes for inside the editor? Similar to how core is currently working on the new "50%" version it would be super valuable to register custom preview sizes.

@fabiankaegy fabiankaegy added the Needs Dev Note Requires a developer note for a major WordPress release cycle label Aug 27, 2024
Comment on lines 41 to 49
export default compose(
withPluginContext( ( context, ownProps ) => {
return {
as: ownProps.as ?? MenuItem,
icon: ownProps.icon || context.icon,
name: 'core/plugin-preview-dropdown-menu',
};
} )
)( ActionItem );
Copy link
Member

Choose a reason for hiding this comment

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

We can probably drop the withPluginContext. It's only here for icon context, and as @simison noted, there's no need for inheriting icons just yet.

Copy link
Member

Choose a reason for hiding this comment

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

The note mentioned above for clarity:

Hesitant allowing custom icons yet, but not a strong opinion. Mostly thinking that later we want to allow multi-selections with check mark, and it's hard to tell how the icon API then should look like in that scenario.

It's all supported out of the box for the PluginMoreMenuItem:

Screenshot 2024-08-28 at 09 04 51

Whenever, the sidebar is selected, it's reflected in the menu with the checkmark icon ✔️. Let's not limit the options that are supported out of the box like the icon that get inherited for all fills. That's the part that makes the More Menu item behave as a checkbox:

<ComplementaryAreaMoreMenuItem
// Menu item is marked with unstable prop for backward compatibility.
// @see https://github.com/WordPress/gutenberg/issues/14457
__unstableExplicitMenuItem
scope="core"
{ ...props }
/>
);

role="menuitemcheckbox"
selectedIcon={ check }

Copy link
Member

Choose a reason for hiding this comment

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

Then, if we want to keep the icon from the plugin context, let's use the usePluginContext hook instead of compose and withPluginContext.

Copy link
Member

Choose a reason for hiding this comment

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

If usePluginContext exist, then it would be so much more up to recent React standards 😄

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

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

If we allow extending dropdown in all editors, we should figure out how plugin extenders can limit to just one editor, and how their custom code can know about the editor context.

The idea was that there would be the scope defined by the plugin's author when registering the plugin that would allow limiting where all fills gets injected. See https://github.com/WordPress/gutenberg/blob/trunk/packages/plugins/README.md#pluginarea:

import { PluginArea } from '@wordpress/plugins';

const Layout = () => (
	<div>
		Content of the page
		<PluginArea scope="my-page" />
	</div>
);

However, only the default scope is used in all editors, so it doesn't work in practice.

Comment on lines 41 to 49
export default compose(
withPluginContext( ( context, ownProps ) => {
return {
as: ownProps.as ?? MenuItem,
icon: ownProps.icon || context.icon,
name: 'core/plugin-preview-dropdown-menu',
};
} )
)( ActionItem );
Copy link
Member

Choose a reason for hiding this comment

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

The note mentioned above for clarity:

Hesitant allowing custom icons yet, but not a strong opinion. Mostly thinking that later we want to allow multi-selections with check mark, and it's hard to tell how the icon API then should look like in that scenario.

It's all supported out of the box for the PluginMoreMenuItem:

Screenshot 2024-08-28 at 09 04 51

Whenever, the sidebar is selected, it's reflected in the menu with the checkmark icon ✔️. Let's not limit the options that are supported out of the box like the icon that get inherited for all fills. That's the part that makes the More Menu item behave as a checkbox:

<ComplementaryAreaMoreMenuItem
// Menu item is marked with unstable prop for backward compatibility.
// @see https://github.com/WordPress/gutenberg/issues/14457
__unstableExplicitMenuItem
scope="core"
{ ...props }
/>
);

role="menuitemcheckbox"
selectedIcon={ check }

@gziolo
Copy link
Member

gziolo commented Aug 28, 2024

This PR introduces a new API to extend the Preview dropdown menu in the post/page editor. It builds upon the work done in #50605, #36119, and #31984, focusing specifically on allowing plugins to add custom menu items to the Preview dropdown.

Yes, there have been a few attempts in the past. Thank you so much for giving it another go. From my perspective, the only missing pieces are e2e tests (maybe one test with a supporting plugin registration is enough) that cover the extension point. All similar e2e tests live in https://github.com/WordPress/gutenberg/blob/trunk/test/e2e/specs/editor/plugins/plugins-api.spec.js.

Looking through the existing names for fills:

Screenshot 2024-08-28 at 09 51 37

I would favor renaming PluginPreviewDropdownMenuItem to PluginPreviewMenuItem as the dropdown part is only an implementation detail that could change over time.

@lezama lezama requested a review from ajitbohra as a code owner August 30, 2024 18:33
@lezama
Copy link
Contributor Author

lezama commented Aug 30, 2024

I would favor renaming PluginPreviewDropdownMenuItem to PluginPreviewMenuItem

Good call @gziolo.

From my perspective, the only missing pieces are e2e tests

Done :)

@lezama
Copy link
Contributor Author

lezama commented Aug 30, 2024

Slightly off topic question here, but would we also be open to allowing extenders to define their own "Preview" modes for inside the editor?

@fabiankaegy for this initial effort, I would maintain the separation of plugins and core actions, similar to the setup in the 'More' menu.

@gziolo gziolo changed the title Add extensibility to PreviewOptions v2 Editor: Add extensibility to PreviewOptions v2 Sep 1, 2024
@youknowriad
Copy link
Contributor

Sorry a bit late here

Right now, this extends preview dropdown in post, page and site editors. What do you think about restricting v1 just to post editor. We can then see how it gets used, and allow extending page/post editor next up?
If we allow extending dropdown in all editors, we should figure out how plugin extenders can limit to just one editor, and how their custom code can know about the editor context.

I don't think we should limit any feature per "editor". We should not see post/page editor as separate from site editor. These should be seen as the same editor. The extenders shouldn't ask themselves whether they should limit their usage to one editor, instead they should ask themselves whether they should limit their extensions per post type. More on this in the last section of this post https://make.wordpress.org/core/2024/06/18/editor-unified-extensibility-apis-in-6-6/

@youknowriad
Copy link
Contributor

This is looking good to me. I leave the final call for the others.

@youknowriad
Copy link
Contributor

The idea was that there would be the scope defined by the plugin's author when registering the plugin that would allow limiting where all fills gets injected. See https://github.com/WordPress/gutenberg/blob/trunk/packages/plugins/README.md#pluginarea:

Yes, I also found that our approach with any random numbers of slot/fills used within the same registerPlugin call is not optimal in terms of performance and it doesn't provide much information to the framework to orchestrate the rendering and the plugins properly but the ship has sailed here, a change to that right now would be a big project and it's probably not the right time for it.

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

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

All feedback addressed. I tested it using the plugin created to e2e tests and it all works great:

Screenshot 2024-09-03 at 13 02 57

There is some misalignment with the "preview in new tab" icon, but it's a preexisting issue. Thank you for taking it to the finish line. We will need to include this change in the dev notes for WordPress 6.7.

@mtias
Copy link
Member

mtias commented Sep 5, 2024

Thanks for driving this one through!

@fabiankaegy
Copy link
Member

Hey @lezama 👋

Would you be able to help write a Dev Note for this feature? We are tracking all the dev notes for 6.7 them in this tracking issue: #65784

We are hoping to have all drafts compiled by October 13th so we have some time to review before RC1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Extensibility The ability to extend blocks or the editing experience First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository Needs Dev Note Requires a developer note for a major WordPress release cycle [Type] New API New API to be used by plugin developers or package users.
Projects
Status: No status
Status: Done
Development

Successfully merging this pull request may close these issues.

Allow external preview links in Preview dropdown to be extended
7 participants