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

Open
57 tasks
nfmohit opened this issue Jan 5, 2025 · 10 comments
Open
57 tasks

Update RRM snippet placement logic #9973

nfmohit opened this issue Jan 5, 2025 · 10 comments
Assignees
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
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

5 participants