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

Update RRM snippet placement logic #9973

Closed
57 tasks
nfmohit opened this issue Jan 5, 2025 · 13 comments
Closed
57 tasks

Update RRM snippet placement logic #9973

nfmohit opened this issue Jan 5, 2025 · 13 comments
Labels
Module: RRM Reader Revenue Manager module related issues P0 High priority Team M Issues for Squad 2 Type: Enhancement Improvement of an existing feature

Comments

@nfmohit
Copy link
Collaborator

nfmohit commented Jan 5, 2025

Feature Description

The Reader Revenue Manager snippet placement logic should be updated to enable conditional and context-aware snippet placement, as follows:

  • If the current screen is a singular post, the following logic will be used in said order:
    • The googlesitekit_rrm_{Publication ID}:productID post meta setting will be checked.
      • If its value is none, no snippet will be added to the post.
      • If its value is anything other than an empty string, the snippet will be added with the value of the post meta setting as the product ID.
    • Otherwise, all taxonomy terms attached to the post will be queried and each attached term will be checked for a googlesitekit_rrm_{Publication ID}:productID term meta setting (if possible, a meta query will be used to query all terms with the meta set). The value for the first found match will be checked.
      • If its value is none, no snippet will be added to the post.
      • If its value is anything other than an empty string, the snippet will be added with the value of the term meta setting as the product ID.
    • Otherwise, the snippetMode module setting will be checked.
      • If it is per_post, no snippet will be added.
      • If it is post_type, it will be checked if the post type of the current post belongs to the postTypes array module setting.
        • If not, no snippet will be added.
        • If yes, the snippet will be added with the value of the productID module setting as the product ID.
      • If it is sitewide, the snippet will be added with the value of the productID module setting as the product ID.
  • If the current screen is not a singular post, the following logic will be used:
    • The snippetMode module setting will be checked.
      • If it is sitewide, the snippet will be added with the value of the productID module setting as the product ID.

If none of the above conditions are met, no snippet will be added.


Do not alter or remove anything below. The following sections will be managed by moderators only.

Acceptance criteria

  1. Singular Post Snippet Placement
    • When viewing a single post (e.g., a single blog post, custom post, etc.):
      1. Post-level Reader Revenue Manager configuration (in the WordPress editor sidebar):
        • If the user chooses "Off" (none), then no snippet should appear on that post.
        • If the user chooses any other product ID (e.g., "Open access" or a specific product ID), the snippet should appear on that post using that selected product ID.
      2. "Display CTAs" dropdown in the Reader Revenue Manager module settings edit screen if the per-post setting is not specified:
        • If "Specified pages" is selected, no snippet should be added unless overridden at the post level.
        • If “Specific content types” is selected:
          • Check if the post’s content type matches any of the chosen content types in Select the content types...".
            • If it does not match, no snippet should appear.
            • If it matches, the snippet should appear using the "Product ID" selected in the Reader Revenue Manager settings (e.g., "Open access" or another default product ID).
        • If “Site wide” is selected, the snippet should appear on this post using the "Product ID" in the Reader Revenue Manager settings.
  2. Non-Singular Post Snippet Placement
    • For any screen that is not a single post:
      • Check the "Display CTAs" dropdown in the Reader Revenue Manager settings:
        • If "Site wide" is chosen, the snippet should appear using the "Product ID" in the Reader Revenue Manager settings.
        • If "Specified pages" or "Specific content types" is chosen, no snippet should appear.
  3. Default/No Snippet Condition
    • If none of the above conditions apply (i.e., neither the user’s post-level settings nor the chosen "Display CTAs" options specify placing a snippet), then no snippet should be added.

Implementation Brief

Conditionally outputting the snippet

  • In includes/Modules/Reader_Revenue_Manager/Tag_Guard.php:
    • Add a new private class property named $post_product_id of string type.
    • Add a class constructor.
      • It should accept $settings as an instance of Google\Site_Kit\Core\Modules\Module_Settings and $post_product_id as a string.
      • It should call the constructor of the parent class with $settings passed to it.
      • It should assign the accepted $post_product_id to the $this->post_product_id.
    • The can_activate method should return true if the following conditions are met:
      • If the rrmModuleV2 feature flag is not enabled:
        • The publication ID is not empty (this condition currently exists).
      • If the rrmModuleV2 feature flag is enabled:
        • The publication ID is not empty.
        • If the currently viewed content is a singular post (is_singular()):
          • $this->post_product_id is not none.
          • $this->post_product_id is not an empty string, or, If in case it is an empty string:
            • The snippet mode ($settings[snippetMode]) is not per_post.
            • If the snippet mode is post_type, the current post type (get_post_type()) belongs to the RRM CTA post types. The RRM CTA post types should be obtained using the googlesitekit_reader_revenue_manager_cta_post_types filter, with a default value of $settings[postTypes].
        • If the currently viewed content is not a singular post:
          • The snippet mode is sitewide.

Embedding the Product ID

  • In includes/Modules/Reader_Revenue_Manager/Web_Tag.php:
    • Create a new private class property named $product_id of a string type.
    • Create a new public method named set_product_id
      • It should accept a product ID string, i.e. $product_id.
      • It should assign the accepted $product_id to the $this->product_id.
    • Update the enqueue_swg_script method:
      • In the $subscription array, replace openaccess with the product ID. The product ID should be obtained using a new googlesitekit_reader_revenue_manager_product_id filter, with a default value of $this->product_id.
      • Unconditionally call the wp_enqueue_script() method instead of depending on whether it is on a single post.

Update Post_Product_ID

  • In includes/Modules/Reader_Revenue_Manager/Post_Product_ID.php:
    • Create a new class property named $settings that would be an instance of Google\Site_Kit\Modules\Reader_Revenue_Manager\Settings.
    • In the class constructor, instead of accepting (and assigning) $publication_id, accept $settings (which would be an instance of Google\Site_Kit\Core\Modules\Module_Settings). Assign $settings to $this->settings.
    • Update get_meta_key method to obtain the required publication ID from $this->settings, i.e. $this->settings->get()['publicationID'].

Connecting it all together

  • In includes/Modules/Reader_Revenue_Manager.php:
    • Add a $post_product_id class property, which will hold an instance of Google\Site_Kit\Modules\Reader_Revenue_Manager\Post_Product_ID.
    • Add a class constructor:
      • Accept all necessary parameters and use them to call the constructor of the parent class.
      • Assign a new instance of Post_Product_ID to $this->post_product_id, passing a new instance of Post_Meta and the module settings ($this->get_settings()) to it.
    • Update the register method:
      • Remove the instantiation of Post_Product_ID as we're now doing it in the constructor. Instead, simply call $this->post_product_id->register().
    • Update the register_tag method:
      • Just before adding guards to the tags, determine the post product ID.
        • It should be an empty string by default.
        • If the rrmModuleV2 feature flag is enabled and it is a singular post, call $this->post_product_id->get() to obtain the post meta value, passing the ID of the current post (get_the_ID()) to it as the parameter.
      • Within the Tag_Guard instantiation, pass the calculated post product ID as the second parameter.
      • Just before calling the $tag->register() method, determine the final product ID to be added to the snippet:
        • It should be openaccess by default.
        • If the rrmModuleV2 feature flag is enabled:
          • It should instead use the value of the module setting by default, i.e. $settings['productID'].
          • If it is a singular post and the post product ID is not empty, use the value of the post product ID.
          • The product ID, unless it is openaccess, is stored in the form of {PUBLICATION_ID}:{PRODUCT_ID}. If that is the case, the product ID should be extracted by removing the {PUBLICATION_ID}: prefix.
        • Call the $tag->set_product_id() method, passing the calculated product ID to it.

Test Coverage

  • In tests/phpunit/integration/Modules/Reader_Revenue_Manager/Tag_GuardTest.php:
    • Update test coverage to include the above changes.
  • In tests/phpunit/integration/Modules/Reader_Revenue_Manager/Web_TagTest.php:
    • Update test coverage to include the above changes.
  • In tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_IDTest.php:
    • Update tests to cover changes to the class.
  • In tests/phpunit/integration/Modules/Reader_Revenue_ManagerTest.php:
    • Add coverage for alternative snippet results with feature flag.

QA Brief

  • Set up Site Kit with the rrmModule and rrmModuleV2 feature flags.
  • Set up the Reader Revenue Manager module.
  • Verify the ACs.

Clarifying different steps in the ACs

  • To check if a snippet is added, go to the front-end of the site (singular post or non-singular content), view page source and search for the Reader Revenue Manager snippet (e.g. Google Reader Revenue Manager snippet added by Site Kit).
  • To check the product ID in the snippet, observe the isPartOfProductId property, which should be in this format: {YOUR_PUBLICATION_ID}:{PRODUCT ID}, unless it is openaccess.
  • A way to set the post-level RRM configuration is not yet possible (as Add post-level RRM settings #9962 is under development). However, you can set the configuration manually using the following steps:
    1. Go to the respective post editor.
    2. Click on the vertical 3-dots in the top-right corner. Select "Preferences", and turn on "Custom fields" under "Advanced".
    3. A new "Custom Fields" panel should appear underneath the editor. Click on "Enter new" to add a new custom field. For the "Name", add googlesitekit_rrm_{YOUR_PUBLICATION_ID}:productID, e.g. googlesitekit_rrm_CAow7tS0AD:productID. For the value, add none (this will prevent snippet addition), openaccess, or any other product ID in the format of {YOUR_PUBLICATION_ID}:{ANY RANDOM PRODUCT ID}, e.g. CAow7tS0AD:advanced.
  • Since it is not possible to set a default product ID in Reader Revenue Manager settings (as Add RRM product ID setting #10065 is under development), you can use the following steps to set one manually:
    1. Go to any Site Kit screen.
    2. In the browser console, run the following script: googlesitekit.data.dispatch( 'modules/reader-revenue-manager' ).setProductID( '{YOUR_PUBLICATION_ID}:{ANY RANDOM PRODUCT ID}' ). You can also set it to openaccess, which is also the default value.
    3. Then, run the following script to save it: googlesitekit.data.dispatch( 'modules/reader-revenue-manager' ).saveSettings().

Changelog entry

  • Enable conditional and context-aware placement of the Reader Revenue Manager code snippet.
@nfmohit nfmohit self-assigned this Jan 5, 2025
@nfmohit nfmohit added P0 High priority Type: Enhancement Improvement of an existing feature Team M Issues for Squad 2 labels Jan 5, 2025
@nfmohit
Copy link
Collaborator Author

nfmohit commented Jan 6, 2025

@aaemnnosttv While brainstorming the ACs for this issue, I realised that I did not consider an edge-case scenario. Suppose, in a certain post, the RRM tag is not added based on the above logic. However, the user has added the inline button block (#9963). Since we're not adding the snippet, the button will not work. Do you have a suggestion on how we can address this edge-case? Thank you!

@nfmohit
Copy link
Collaborator Author

nfmohit commented Jan 9, 2025

Update: Upon further discussion regarding this internally with @aaemnnosttv, we've decided that we are not going to alter the snippet placement logic based on the addition of the inline button blocks. This edge case will be handled by the blocks themselves. I'll draft the ACs and move this forward accordingly.

@nfmohit nfmohit assigned hussain-t and unassigned aaemnnosttv and nfmohit Jan 9, 2025
@hussain-t hussain-t assigned nfmohit and unassigned hussain-t Jan 16, 2025
@nfmohit
Copy link
Collaborator Author

nfmohit commented Jan 17, 2025

Thank you for drafting the ACs, @hussain-t!

One general feedback regarding the overall ACs is that we should consider using less technical language and more UI-oriented instructions, as ideally, we should aim for the ACs to be conveniently readable, such as the QAB. For example:

  1. Instead of referring to googlesitekit_rrm_{Publication_ID}:productID post/term meta setting, we should consider referring to the actual setting added in the block editor (for post-level setting) and taxonomy screen (for taxonomy-term level setting). We should also refer to the associated dropdown options for the setting values.
  2. Instead of referring to the snippetMode module setting, we should refer to the associated setting field we will add to the Site Kit settings.

I understand the UI for many of the above has not been implemented yet or is still being defined; however, you should see them quite well described in the design document and the Figma designs.

Apart from the above:

Error Handling:

  • If any of the required settings (productID, postTypes, or snippetMode) are invalid, undefined, or unavailable, it should default to not adding a snippet to avoid unexpected behaviour.

We don't need to specify the above, as all three settings have default values, so it's unlikely they will be unavailable.

Please let me know if you have any questions or thoughts; thank you!

@nfmohit nfmohit assigned hussain-t and unassigned nfmohit Jan 17, 2025
@nfmohit nfmohit added the Module: RRM Reader Revenue Manager module related issues label Jan 18, 2025
@hussain-t
Copy link
Collaborator

Thanks, @nfmohit. I've addressed your feedback by updating the AC to use more UI-oriented language from the design doc. LMK if it looks good.

@hussain-t hussain-t assigned nfmohit and unassigned hussain-t Jan 20, 2025
@nfmohit
Copy link
Collaborator Author

nfmohit commented Feb 8, 2025

Thank you @hussain-t!

I've made some further changes to the AC, including removing any mention of the term-level settings as we've decided to postpone that, and some minor cosmetic changes.

Moving this forward, thanks!

@nfmohit nfmohit assigned nfmohit and unassigned nfmohit Feb 8, 2025
@hussain-t hussain-t assigned hussain-t and unassigned hussain-t Feb 13, 2025
@techanvil techanvil self-assigned this Feb 14, 2025
@techanvil
Copy link
Collaborator

Hey @nfmohit, thanks for drafting this IB. It's most of the way there, I just have a few, mostly minor points for your consideration:

Point 1:

  • The can_activate method should return true if the following conditions are met:
    • ...
    • If the rrmModuleV2 feature flag is enabled:
      • The publication ID is not empty.
      • If the currently viewed content is a singular post (is_singular()):
        • $this->post_product_id is not none.
        • If the snippet mode ($settings[snippetMode]) is per_post, $this->post_product_id is not empty.
        • If the snippet mode is post_type, the current post type (get_post_type()) belongs to the RRM CTA post types. The RRM CTA post types should be obtained using the googlesitekit_reader_revenue_manager_cta_post_types filter, with a default value of $settings[postTypes].
      • If the currently viewed content is not a singular post:
        • The snippet mode is sitewide.

This seems slightly at odds with the AC/design doc requirements: the above logic suggests that the snippet mode post_type will override the tag placement when a product ID has been specified for the post, such that if a product ID has been specified for the post, but the post type is not in the selected list RRM CTA post types, the tag will not be placed. The AC/DD indicates that a product ID selected at the post level will override any snippet mode logic.

From "snippet placement" in the design doc (which the AC is consistent with):

  • If the current screen is a singular post, the following logic will be used in said order:
    • The googlesitekit_rrm_{Publication ID}:productID post meta setting will be checked.
      • If its value is none, no snippet will be added to the post.
      • If its value is anything other than an empty string, the snippet will be added with the value of the post meta setting as the product ID.
    • Otherwise, the snippetMode module setting will be checked.

Point 2:

  • In includes/Modules/Reader_Revenue_Manager/Post_Product_ID.php:
    • Create a new class property named $settings that would be an instance of Google\Site_Kit\Core\Modules\Module_Settings.
    • In the class constructor, instead of accepting (and assigning) $publication_id, accept $settings (which would be an instance of Google\Site_Kit\Core\Modules\Module_Settings). Assign $settings to $this->settings.
    • Update get_meta_key method to obtain the required publication ID from $this->settings, i.e. $this->settings->get()['publicationID'].

A minor point, but I would suggest $settings should be specified as an instance of Google\Site_Kit\Modules\Reader_Revenue_Manager\Settings, we aren't writing a class with generic behaviour that operates on the base class and so might as well be more specific about the type.


Point 3:

  • Add a $post_product_id class property of string type.

Looks like you mean of type Post_Product_ID ? This class is admittedly a named a bit confusingly, as an instance with a corresponding name does look like it should be a string or integer.


Point 4:

Lastly, I think we need to consider the implication of #10228, which is that we'll presumably need to strip the publication ID from the product ID before replacing openaccess in Web_Tag. It seems we could manage that in one of the following two points:

  • Call the $tag->set_product_id() method, passing the calculated product ID to it.
  • In the $subscription array, replace openaccess with the product ID. The product ID should be obtained using a new googlesitekit_reader_revenue_manager_product_id filter, with a default value of $this->product_id.

@techanvil techanvil assigned nfmohit and unassigned techanvil Feb 14, 2025
@nfmohit
Copy link
Collaborator Author

nfmohit commented Feb 14, 2025

@techanvil Thank you for the kind IBR. I have updated the IB and addressed all four very valid and nicely captured points. Back to you for another pass, thank you!

@nfmohit nfmohit assigned techanvil and unassigned nfmohit Feb 14, 2025
@techanvil
Copy link
Collaborator

techanvil commented Feb 17, 2025

Thanks @nfmohit! That's looking good. One last point:

  • If the rrmModuleV2 feature flag is enabled:
    • It should instead use the value of the module setting by default, i.e. $settings['productID'].
    • If it is a singular post and the post product ID is not empty, use the value of the post product ID.
    • The product ID is stored in the form of {PUBLICATION_ID}:{PRODUCT_ID}. The product ID should be extracted by removing the {PUBLICATION_ID}: prefix.

It's worth bearing in mind that the post product ID may have a value of openaccess (without a {PUBLICATION_ID}: prefix) as well as a product ID in the form {PUBLICATION_ID}:{PRODUCT_ID}, so it would be worth making this clear here.

@techanvil techanvil assigned nfmohit and unassigned techanvil Feb 17, 2025
@nfmohit
Copy link
Collaborator Author

nfmohit commented Feb 17, 2025

@techanvil Excellent point, I've updated the IB, thank you!

@nfmohit nfmohit assigned techanvil and unassigned nfmohit Feb 17, 2025
@techanvil
Copy link
Collaborator

That's great, thanks @nfmohit!

IB ✅

@techanvil techanvil removed their assignment Feb 17, 2025
@nfmohit nfmohit self-assigned this Feb 17, 2025
@nfmohit nfmohit removed their assignment Feb 18, 2025
@techanvil techanvil assigned techanvil and nfmohit and unassigned techanvil Feb 18, 2025
@nfmohit nfmohit assigned techanvil and unassigned nfmohit Feb 18, 2025
techanvil added a commit that referenced this issue Feb 19, 2025
@techanvil techanvil removed their assignment Feb 19, 2025
@kelvinballoo kelvinballoo self-assigned this Feb 19, 2025
@kelvinballoo
Copy link
Collaborator

kelvinballoo commented Feb 27, 2025

QA UPDATE ⚠

ITEM 1 Singular Post Snippet Placement
AC:
When viewing a single post (e.g., a single blog post, custom post, etc.): Post-level Reader Revenue Manager configuration (in the WordPress editor sidebar): If the user chooses "Off" (none), then no snippet should appear on that post.

I have set it to 'Off'/none in the BE but snippet is still appearing with the default product ID.

9973.-.03.-.set.to.none.in.BE.-.still.appear.-.not.ok.with.explanations.to.upload.mov
____________________________________________________

ITEM 2 Singular Post Snippet Placement - Random product ID
If the user chooses any other product ID (e.g., "Open access" or a specific product ID), the snippet should appear on that post using that selected product ID.

From my understanding, as long as we override it as a post level, we should be retrieving the post's product ID. I've set up a random ID but we are still retrieving the default 'Open access'

I assume that's not expected. Can you confirm?

9973.-.04.-.set.to.random.product.ID.-.did.not.change.mov
____________________________________________________

ITEM 3 : Image snippets
I am unsure how to verify snippets on images.
We did have a conversation on slack about that, which I know how to access images but how do we actually view the snippets then?
The reason I ask is if I view the media and right click, there is no page source.
Inspecting the image also doesn't show any snippets.

Image is attached for reference.

Image

Other areas tested as follows:

  • Non-Singular Post Snippet Placement ✅
    For any screen that is not a single post, verified that for the "Display CTAs" dropdown in the Reader Revenue Manager settings:

    • If "Site wide" is chosen, the snippet appears using the "Product ID" in the Reader Revenue Manager settings.
    • If "Specified pages" or "Specific content types" is chosen, no snippet appears.
    9973.-.Non-Singular.Post.Snippet.Placement.-.Sitewide.specific.content.specified.pages.mov
  • Default/No Snippet Condition ✅

    • If neither the user’s post-level settings nor the chosen "Display CTAs" options specify placing a snippet), no snippet is added:
    Set the Display CTA as 'Specified pages' and the post level settings as none, there is no snippet added. Image Image

@nfmohit
Copy link
Collaborator Author

nfmohit commented Feb 27, 2025

Hi @kelvinballoo, thank you for sharing your observations!

ITEM 1 Singular Post Snippet Placement
ITEM 2 Singular Post Snippet Placement - Random product ID

In your screenshots and screencasts, I can see that you're setting the name of the custom field as googlesitekit_rrm_CAow_va1DA:kelvinqa. However, the part kelvinqa is incorrect, it should be productID in literal terms, so in your case, it should be googlesitekit_rrm_CAow_va1DA:productID.

It should also be noted that now that #9962 has been merged, you can use the settings in the block editor sidebar instead of the custom fields.

ITEM 3 : Image snippets

In the linked Slack thread, my screenshot indicated a "View attachment page" action, which is a different link than the direct image source URL. Were you able to view the attachment page?

@nfmohit nfmohit removed their assignment Feb 27, 2025
@kelvinballoo
Copy link
Collaborator

QA Update ✅

Thanks @nfmohit , these were verified good after a re-test.
Moving ticket to approval.

  • Singular Post Snippet Placement ✅

    • When viewing a single post and Post-level Reader Revenue Manager configuration is (none), then no snippet appear on that post.

      9973.-.NEW.-.Post.level.-.product.ID.none.but.snippet.appears.-.ok.mov
    • When viewing a single post and Post-level Reader Revenue Manager configuration is any other product ID (e.g., "Open access" or a specific product ID), the snippet appears on that post using that selected product ID.

      9973.-.NEW.-.Post.level.-.product.ID.mov
    • When viewing a single post and "Display CTAs" dropdown in the Reader Revenue Manager module settings are as follows:

      • "Specified pages" -> no snippet should be added

        9973.-.01.-.Specified.pages.-.No.snippet.mov
      • "Specified pages" but the post level has a specific value -> snippet should appear with post level value

        9973.-.NEW.-.Post.level.overriding.specified.pages.mov
      • Check if the post’s content type matches any of the chosen content types in Select the content types...". If it does not match, no snippet should appear.
        If it matches, the snippet should appear using the "Product ID" selected in the Reader Revenue Manager settings (e.g., "Open access" or another default product ID).
        These points were verified good through the following scenarios:

        • Tested on post while content specified is pages -> No snippet
        • Tested on post while content specified is post-> Snippet
        • Tested on post while content specified is media -> No spinnet
        • Tested on post while content specified is post, pages, media ->Snippet
        • Tested on pages while content specified is pages -> Snippet
        • Tested on pages while content specified is post-> No snippet
        • Tested on pages while content specified is media -> No snippet
        • Tested on pages while content specified is post, pages, media ->Snippet
          Note: It wasn't possible to test on a media attachment file and it's not worth it based on the slack conversation here.
      • If “Site wide” is selected, the snippet appears on this post using the "Product ID" in the Reader Revenue Manager settings.

        9973.-.02.-.Sitewide.-.snippet.ok.mov
        Image Image
  • Non-Singular Post Snippet Placement ✅
    For any screen that is not a single post, verified that for the "Display CTAs" dropdown in the Reader Revenue Manager settings:

    • If "Site wide" is chosen, the snippet appears using the "Product ID" in the Reader Revenue Manager settings.
    • If "Specified pages" or "Specific content types" is chosen, no snippet appears.
    9973.-.Non-Singular.Post.Snippet.Placement.-.Sitewide.specific.content.specified.pages.mov
  • Default/No Snippet Condition ✅

    • If neither the user’s post-level settings nor the chosen "Display CTAs" options specify placing a snippet), no snippet is added:
    Set the Display CTA as 'Specified pages' and the post level settings as none, there is no snippet added. Image Image

@kelvinballoo kelvinballoo removed their assignment Feb 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Module: RRM Reader Revenue Manager module related issues P0 High priority Team M Issues for Squad 2 Type: Enhancement Improvement of an existing feature
Projects
None yet
Development

No branches or pull requests

6 participants