Problem/Motivation

Use of bazaarvoice_library_info_alter() to provide language specific BV loader files does not work as expected with the configured locales. B/c

hook_library_info_alter(), per this change record (I can't find any other documentation)

hook_library_info_alter(), a similar hook that executes at cache rebuild time instead, for better performance.

As a result, the first time hook_library_info_alter() is only invoked on cold caches, once built and caches, the library definition as it was first built persists through other page requests. For BV usage and dynamically changing BV Loader JS file based on locale, we need another solution.

Steps To Reproduce

  1. Assumes having properly configured product content type rendering BV hosted statistics/reviews on a site with more than one language and BV account/workbench configured with more than one locale and BV module locale configured
  2. Caches enabled
  3. On cold caches visit a product page in one language
  4. Observe the JS loader is correct using the correct locale
  5. View product in other other language
  6. Observe the JS loader is still using the first locale, not the locale configured for the second language

Proposed resolution

TBD

Remaining tasks

TBD

User interface changes

TBD

API changes

TBD

Data model changes

TBD

Release notes snippet

TBD

Comments

jasonawant created an issue. See original summary.

jasonawant’s picture

More info from another change record

Note that "dynamic" doesn't mean "runtime" (i.e. for every request) — that'd be terrible for performance. The dynamically added libraries are still cached, just like libraries defined in YML files. It's "dynamic" because you can use logic to add libraries.

A few ideas that come to mind

  • Add a library for each configured locale, but then require the #attach to specify which locale library its attaching; not ideal
  • Add JS that will append the BV loader
    to DOM using locale value provided hook_js_settings_alter()
jasonawant’s picture

Assigned: jasonawant » Unassigned

Talked to team members to outline a path forward to append the BV loader JS as

tag using a Drupal attach behavior. This JS will consume drupalSettings values representing the BV config as fragments of the BV loader JS path. In doing so, a hook_js_settings_alter() implementation can include the locale value associated with the language of the page request instead of the cached library definition. The solution below outlines continued support for bazaarvoice/hosted.external so any custom work that attaches this library will continue to work, no BC break. It also accounts for WriteReviewController::reviewContainer() usage of BazaarvoiceService::buildHostedJsPath().
  • Add drupalSettings definition with items representing config within bazaarvoice.libraries.yml , e.g. core.libraries.yml
  • Add new method (e.g. getBvDrupalSettings() to BazaarvoiceService to get configuration and prepare url fragments for drupalSettings
  • Implement a hook_js_settings_alter() to update DrupalSettings values from BV config using BazaarvoiceService method, e.g. system_js_settings_alter()
  • Refactor buildHostedJsPath() to use new method to get configuration and prepare path
  • Ensure WriteReviewController::reviewContainer() works when using buildHostedJsPath()
  • Add JS file to use prepared drupalSettings to append tag with async attribute
  • Update bazaarvoice/hosted.external in bazaarvoice.libraries.yml to point to the JS file above; add dependency on bazaarvoice/drupalSettings
  • Remove bazaarvoice_library_info_alter()
Note, our team is using patch from #2959188-11: Use v2 display API (bv.js instead of bvapi.js), so we'll likely continue from there.

Next Steps

  • Update issue summary with proposed solution and other sections
jasonawant’s picture

One remaining concern/question, how best to manage/store the parts of the JS loader resource path, and deliver it to the client via drupalSettings.

The BazaarvoiceService::buildHostedJsPath() with this patch in #2959188-11: Use v2 display API (bv.js instead of bvapi.js) returns the resource path as follows.

Hosted v1: has host and 4 pathname parts

$js_path = '//display.ugc.bazaarvoice.com/' . $mode . 'static/' . $client_name . '/' . $locale_code . '/bvapi.js';

Hosted v2: has host and 6 pathname parts

$js_path = '//apps.bazaarvoice.com/deployments/' . $client_name . '/' . $site_id . '/' . $mode . '/' . $locale_code . '/bv.js';

For client side logic to determine how to construct the JS resource path, how should drupalSettings be structured to inform client side logic how to construct the resource path?

jasonawant’s picture

Assigned: Unassigned » jasonawant

After reviewing this, and recognizing how crazy this approach is, there is a different simpler way using hook_js_alter() to localize the loader file!

jasonawant’s picture

Assigned: jasonawant » Unassigned
Status: Active » Needs review
StatusFileSize
new2.17 KB

Alright, so with a far simpler approach, I've replaced the hook_library_info_alter() with hook_js_alter() implementation. Without a great a way to substitute the resource path within hook_js_alter(), I've updated the library definition path in order to be sure this logic only replaces this specific item.

  • kamkejj committed ff1bf11 on 8.x-2.x
    Issue #3151507 by jasonawant: Use of bazaarvoice_library_info_alter() to...
kamkejj’s picture

Status: Needs review » Fixed

Applied patch to 8.x-2.x branch.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.