Personalization component source

Created on 21 May 2025, 4 months ago

Overview

Marketers want to create personalized experiences for their end users. They want to show the right content to the right person at the right time.

For achieving that, they need to be able to create personalization variations for each personalization segment.

Proposed resolution

We architected that a new component source will wrap the personalization variations.
Refine the implementation details still under discussion.
Provide that component source.

User interface changes

None.

πŸ“Œ Task
Status

Active

Version

0.0

Component

Personalization

Created by

πŸ‡ͺπŸ‡ΈSpain penyaskito Seville πŸ’ƒ, Spain πŸ‡ͺπŸ‡Έ, UTC+2 πŸ‡ͺπŸ‡Ί

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @penyaskito
  • πŸ‡ͺπŸ‡ΈSpain penyaskito Seville πŸ’ƒ, Spain πŸ‡ͺπŸ‡Έ, UTC+2 πŸ‡ͺπŸ‡Ί
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Bumping to because this is what will get us to 100% confidence in answering

    1. feature: ability to store variants of component trees for use cases like personalization (i.e. different component subtree for Belgians & Brits vs everyone else), responsive design (i.e. breakpoint-specific overrides), and arbitrary future use cases
  • Assigned to penyaskito
  • πŸ‡ͺπŸ‡ΈSpain penyaskito Seville πŸ’ƒ, Spain πŸ‡ͺπŸ‡Έ, UTC+2 πŸ‡ͺπŸ‡Ί
  • Pipeline finished with Failed
    about 1 month ago
    #564883
  • Pipeline finished with Failed
    about 1 month ago
    #565049
  • Pipeline finished with Failed
    about 1 month ago
    #566650
  • πŸ‡ͺπŸ‡ΈSpain penyaskito Seville πŸ’ƒ, Spain πŸ‡ͺπŸ‡Έ, UTC+2 πŸ‡ͺπŸ‡Ί

    So we've been assuming one component source β†’ one personalization component with dynamic slots.

    Somehow I forgot about #3525746-6: Update the React client preview view β†’ , where we agreed that the backend should provide one (maybe 2?) component source(s), that will have 2 component types (with one slot), the switch and the case, in the same way than the client layout model.

    It's clear that when rendering the component, for the purpose of this issue we

    a) can hard-code the negotiation when rendering a personalization in "live" mode. This will be fixed later in 🌱 [META] Personalization Variation negotiation and rendering Active .
    b) need to render all the switch/cases when rendering in "preview" mode. The client will need that for allowing live previews, and its the responsability of the client UI to render the cases based on the "active segment".

    For the component "switch", its inputs it's the mapping of segment ⇔ variation. Taking into account that this is a 1:1 relationship for now, but won't be in the future, and could have attributes in this relationship.

    For the component "case", there is no inputs. The "switch" mapping inputs above will reference the uuid of the "case".

    We might try doing a single component source, where the inputs are not mandatory. But it might need to become two different component sources.

  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    It's clear that when rendering the component, for the purpose of this issue we

    +1 to both

    We might try doing a single component source, where the inputs are not mandatory. But it might need to become two different component sources.

    Let's find out :)

  • Pipeline finished with Failed
    29 days ago
    #572530
  • Pipeline finished with Failed
    24 days ago
    Total: 1033s
    #575344
  • Pipeline finished with Failed
    24 days ago
    #575406
  • Pipeline finished with Failed
    24 days ago
    Total: 985s
    #575433
  • Pipeline finished with Failed
    24 days ago
    Total: 376s
    #575464
  • Pipeline finished with Failed
    24 days ago
    Total: 1081s
    #575467
  • Pipeline finished with Failed
    24 days ago
    Total: 1009s
    #575498
  • Pipeline finished with Failed
    24 days ago
    Total: 917s
    #575519
  • Pipeline finished with Failed
    23 days ago
    #576386
  • Pipeline finished with Failed
    23 days ago
    #576453
  • Pipeline finished with Failed
    23 days ago
    Total: 1101s
    #576913
  • Pipeline finished with Failed
    23 days ago
    Total: 1237s
    #576931
  • Pipeline finished with Failed
    22 days ago
    Total: 184s
    #577330
  • Pipeline finished with Failed
    22 days ago
    Total: 855s
    #577332
  • Pipeline finished with Failed
    22 days ago
    #577362
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Pushed a sequence of commits that is the result of @penyaskito and I pairing and debugging for ~2.5 hours πŸ₯΅πŸ˜΅

    Next steps

    1. lift πŸ“Œ Create recipe with personalization demo Active 's https://git.drupalcode.org/project/experience_builder/-/merge_requests/1... into this MR, and adjust it to no longer use static prop sources β€” it should become a LOT simpler :D
    2. next, write the test coverage (that uses the test/demo module the prior point is adding), that proves the appropriate "case" is rendered: the halloween one if ?campaign_utm_whatever=halloween is in the URL, the default in every other case
    3. … and NOT implement generic negotiation logic; that's for later β€” as far as I'm concerned we can even just do $variant_id = str_contains(\Drupal::request()->getUri(), 'halloween') ? 'halloween' : Segment::DEFAULT_ID; πŸ€“ We can swap out that logic for something much more advanced in πŸ“Œ Implement the Context for Variation and Variation negotiation Postponed πŸ‘
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    P.S.: for naming variants (i.e. "case" component instances), I propose we use ✨ [PP-2] Allow users to name components for the specific context Postponed . That'd keep the data model here as simple as possible, and would keep the "Human-readable name" part out of this MR.

  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Forgot something crucial in #9:

    ⚠️ OUT OF SCOPE: working component instance forms! Step 1 above should just make the sole Page<?code> content entity that <code>xb_personalization_demo is installing inspectable. These 2 new components should NEVER be visible in the list of components to instantiate (but they currently are) and they should NEVER be showing up in the layers menu on the left the way they currently are, but this is a great way of visualizing a known starting point (the xb_personalization_demo module described in #9.2+#9.3) for the UI to be developed against.

    IOW: consider this an incomplete yet pragmatic tech demo that enables bootstrapping this functionality πŸ€“

  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Updating title. Basically:

    • β†’ #9
    • β†’ #11
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Forgot the GIF I created πŸ™ˆ

    This is where @penyaskito and I got:

  • Pipeline finished with Failed
    17 days ago
    Total: 850s
    #580992
  • Pipeline finished with Success
    17 days ago
    Total: 1979s
    #581012
  • πŸ‡ͺπŸ‡ΈSpain penyaskito Seville πŸ’ƒ, Spain πŸ‡ͺπŸ‡Έ, UTC+2 πŸ‡ͺπŸ‡Ί

    This is ready for reviews.

    I've done some clean-up, and think this is in a commiteable state.

    To notice:

    #11 If we ever want to do that we might need a new anonymous class as \Drupal\experience_builder\Plugin\ExperienceBuilder\ComponentSource\BlockComponent::buildAnonymousFormForBlockPlugin does. Don't think it's worth the effort as this would go away anyway.

    We have a recipe now for setting up the automatic/manual test scenarios. See MR description for applying it.
    Ideally this would be build on top of `test_site` recipe, but that one's content didn't validate for me locally.
    I've added a note on the recipe.yml file about this.

    Our e2e test is actually a KernelTest πŸŽ‰
    We probably want a.playwright test in the future, specially when we have the UI changes, but for now this works and found it overkill here.

  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Reviewed ~70% of this MR. Remainder tomorrow.

  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    RTBC!

    What an epic MR!

    One last realization is that the client won't be able to start building the React UI changes in πŸ“Œ Update the React client preview view Postponed without also making back-end changes in the same MR β€” because the BE sending nodeType: switch|case as described by @effulgentsia at #3525746-6: Update the React client preview view β†’ will cause the UI to break immediately, which would've made #13 impossible.

    We both realized that it might actually be better to change variant IDs to not be some kind of machine name-esque string, but UUIDs. Not yet implemented here. Thread: https://git.drupalcode.org/project/experience_builder/-/merge_requests/1...

  • Pipeline finished with Failed
    15 days ago
    Total: 548s
    #583118
  • Pipeline finished with Success
    15 days ago
    Total: 787s
    #583111
  • Pipeline finished with Failed
    15 days ago
    Total: 2065s
    #583124
  • Pipeline finished with Failed
    15 days ago
    Total: 831s
    #583163
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    About to merge! πŸ₯³

  • Pipeline finished with Failed
    15 days ago
    Total: 673s
    #583188
  • Pipeline finished with Skipped
    15 days ago
    #583213
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Yay!

    Now only the docs MR! πŸ₯³

  • Pipeline finished with Failed
    15 days ago
    Total: 1099s
    #583198
  • πŸ‡ͺπŸ‡ΈSpain penyaskito Seville πŸ’ƒ, Spain πŸ‡ͺπŸ‡Έ, UTC+2 πŸ‡ͺπŸ‡Ί
  • Pipeline finished with Success
    15 days ago
    Total: 854s
    #583236
  • Pipeline finished with Success
    15 days ago
    Total: 1436s
    #583291
  • πŸ‡ͺπŸ‡ΈSpain penyaskito Seville πŸ’ƒ, Spain πŸ‡ͺπŸ‡Έ, UTC+2 πŸ‡ͺπŸ‡Ί
  • Pipeline finished with Skipped
    15 days ago
    #583409
  • Pipeline finished with Skipped
    15 days ago
    #583411
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    All done! πŸŽ‚

  • πŸ‡ͺπŸ‡ΈSpain penyaskito Seville πŸ’ƒ, Spain πŸ‡ͺπŸ‡Έ, UTC+2 πŸ‡ͺπŸ‡Ί

    I think there aren't any follow-ups needed, so marking as fixed πŸŽ‰

  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Yep! Don't know why I didn't do that πŸ˜…

Production build 0.71.5 2024