site-kit-wp: Show Idea Hub context for post based on Idea Hub idea in WordPress block editor / Gutenberg
The WordPress block editor (Gutenberg) should indicate if the current post is a draft based on an Idea Hub idea.
Do not alter or remove anything below. The following sections will be managed by moderators only.
Acceptance criteria
- When editing a WordPress post that has Idea Hub idea metadata set in the block editor (Gutenberg), a notice like in this Figma file should be displayed on top of the editor.
- The copy used should actually differ from the Figma design and say: This post was created from an idea you picked in Site Kit’s Idea Hub: {idea} The bold “Google Site Kit” prefix from the Figma design should not be included.
- The notice should be dismissible. When dismissed, that dismissal should be cached temporarily for an hour, it doesn’t need to be persistently stored. Editing a particular post doesn’t happen all the time, and it’s okay to remind the user again if they open the same post in the editor after a while.
- This functionality should rely on the Gutenberg Notice API.
- The entire integration should be implemented in a separate JS file that is loaded only in the block editor (from the
Idea_Hubclass in PHP), if necessary for the current post. Other than typical for Site Kit JS code, the code here should actually rely on WordPress’s included versions of@wordpress/*dependencies (e.g. referencewp.datainstead of@wordpress/data, and includewp-datain the dependencies for the asset in PHP) and not come with any of our own bundled dependencies, to not double-load dependencies and minimize the footprint in the block editor.
Implementation Brief
PHP
- Edit the
Assetclass:- Add the following constants to the class:
CONTEXT_ADMIN_GLOBAL = 'admin-global'CONTEXT_ADMIN_POST_EDITOR = 'admin-post-editor'CONTEXT_ADMIN_POSTS = 'admin-posts'CONTEXT_ADMIN_SITEKIT = 'admin-sitekit'
- Add
'load_contexts' => array( self::CONTEXT_ADMIN_SITEKIT ),to the array of default values for the$argsproperty. - Add a new public method
has_context( $context )that returnsTRUEif the incoming$contextexists in the$this->args['load_contexts']array.
- Add the following constants to the class:
- Update the
enqueue_assetsmethod of theModule_With_Assetsinterface to accept$context = Asset::CONTEXT_ADMIN_SITEKITargument. - Edit the
enqueue_assetsmethod of theModule_With_Assets_Traittrait to have the same new$context = Asset::CONTEXT_ADMIN_SITEKITargument and to filter out assets that don’t have provided context before enqueueing assets. - Add a new hook for the
enqueue_block_editor_assetsaction in theAssets::registermethod to enqueue registered gutenberg assets. UseAssets::get_assets()method to return registered assets and filter out assets that don’t support theCONTEXT_ADMIN_POST_EDITORcontext. - Edit the
Idea_Hub::setup_assetsmethod to define a new Script for thedist/js/googlesitekit-idea-hub-notice.jswith theCONTEXT_ADMIN_POST_EDITORcontext andwp-dataas a dependency.
JS
-
Create
assets/js/googlesitekit-idea-hub-notice.jswhich has theshowIdeaHubNoticefunction and the file which will be enqueued in the block editor only. -
Update
webpack.config.jsto add a new entry for the above file similar toanalytics-advanced-tracking. -
The
showIdeaHubNoticefunction should do the following:- Check if the current post has idea hub metadata via the
getEditedPostAttributeselector ofcore/editordata store. As per the IB,wp.datashould be used. For e.g:const postMeta = wp.data.select( 'core/editor' ).getEditedPostAttribute( 'meta' ); - The following meta keys should be present and not empty to identify an idea hub post:
googlesitekitpersistent_idea_namegooglesitekitpersistent_idea_textgooglesitekitpersistent_idea_topics
- Import the
setItemandgetItemfromassets/js/googlesitekit/api/cache.js. - Use the
getItemfunction to check if there is an item in local storage with the keymodules::idea-hub::dismissed-editor-notice-<post_ID>where<post_ID>is the ID of the currently edited post. To get the current post ID, query thecore/editordata store via thegetCurrentPostIdselector. - If
cacheHitisfalsefrom the result ofgetItem, then the user has not dismissed the notice. The Gutenberg notice API will be used to display the notice but theonDismisscallback did not work until recently. To circumvent that, we can create listen to data store changes checking whether the notice is still present on the page or has been dismissed. - To display the notice:
- Use the Gutenberg notice API to create an info dismissable notice as per the designs in Figma by using the
createInfoNoticeaction of thecore/noticesdata store. For e.g:
wp.data.dispatch( 'core/notices' ).createInfoNotice( 'My custom notice', options ); // options is an object- The text for the notice should be as per the second bullet point from the AC where
{idea}is the value from the post meta with thegooglesitekitpersistent_idea_textkey. - The
idof the notice should begooglesitekit-idea-hub-notice. - Since we want to know when the user dismisses the notice and the
onDismissproperty does not work, listen to the data store to see if the notice is still present.- Define a function,
hasNoticewhich returnstrueif the notice id defined in the previous bullet point is in the list of notices. To get the list of notices, use thegetNoticesselector of thecore/noticedata store. - Define another function,
handleDataChangechange, which checks whetherhasNoticereturnstrue. If this is the case, then the notice is currently being displayed on the page. IfhasNoticereturnsfalse, this means that the user has dismissed the notice. In that case, do the following:- Use the
setItemto set the keymodules::idea-hub::dismissed-editor-notice-<post_ID>to havetrueas value. - We can only pass the
keyandvalueparameters to thesetItemfunction since the default parameters set the expiry for the item in local storage to 1 hour.
- Use the
- Listen to the changes to the data store using the
subscribefunction ofwp.data, passinghandleDataChangeas parameter. Thesubscribefunction returns a unsubscribe function used to stop the subscription. This should occur in thehandleDataChangefunction whenhasNoticereturnsfalse.
- Define a function,
- Use the Gutenberg notice API to create an info dismissable notice as per the designs in Figma by using the
- If
cacheHitistruefrom the result ofgetItem, do not do anything. It means that the user has seen the notice and dismissed it in the past hour.
- Check if the current post has idea hub metadata via the
-
POC for listening to data changes: https://github.com/google/site-kit-wp/issues/3272#issuecomment-865895705
Test Coverage
- No new tests to be added.
Visual Regression Changes
- N/A
QA Brief
To the engineer writing the QA Brief: Similar to #3271, this issue should be testable by our QA team and not require QA: Eng. Include a sample datastore call to do in the browser console (e.g. window.googlesitekit.data.dispatch( 'modules/idea-hub' ).createIdeaDraftPost( ... )) so that a draft post is created that can then be checked.
Changelog entry
- Add the Idea Hub notification to the WordPress block editor
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 25 (5 by maintainers)
Sounds good @aaemnnosttv . IB updated.
@asvinb per our conversation, can you take a look and see when the
__unstableHTMLoption was added? Maybe we can use this to pass our own content that includes a data attribute we can use for a selector.As a fallback, if the above isn’t available for the event listener option, we should probably treat the notice as dismissed after showing it once.
cc: @felixarntz
@aaemnnosttv @eugene-manuilov I agree with both of your points, let’s support multiple contexts, and use
admin-globalinstead ofadmin-general.@asvinb I’ve updated https://github.com/google/site-kit-wp/issues/3272#issuecomment-861730783 with the additional modifications, so you should now be able to continue the IB following that comment.
@felixarntz that sounds good to me for the most part, although I think each
Assetneeds to support multiple contexts – e.g.admin-sitekit, admin-posts.Also, maybe
admin-generalmight be more clear asadmin-global?@eugene-manuilov @aaemnnosttv Enhancing
Module_With_Assetsto support different contexts makes sense to me. Let’s do the following:Google\Site_Kit\Core\Assets\Assetto have a new$load_contextsfield (array of strings), with an array with “admin-sitekit” being the default (indicates that the asset should be loaded only on Site Kit admin screens).Google\Site_Kit\Core\Modules\Module_With_Assets(and its trait) so that bothget_assetsandenqueue_assetssupport an optional$load_contextparameter, that also relies on “admin-sitekit” as default. The trait should be adjusted so that the two method implementations then consider only the assets that have the specified$load_contextwith their$load_contextsarray.setup_assetsimplementations don’t need to be updated (since they all implicitly use “admin-sitekit”), but now it is possible to specify alternative load context values, which is what’s needed here.For now, let’s specify the following load context values:
admin-global(throughout the entire admin):googlesitekit-baseonly should rely on thisadmin-sitekit(default: any primary Site Kit area, including admin bar): relevant for all existing Site Kit assetsadmin-post-edit(Gutenberg / block editor): relevant for this issueadmin-posts(admin posts list table, i.e.wp-admin/edit.php); relevant for #3359Let me know if this sounds good to you, if so we can proceed with the IB.