Rework displaying dynamic information to JS for persistent caching

Created on 18 February 2025, 2 months ago

Problem/Motivation

The field displays pretty dynamic information, so caching on the backend can be pretty problematic.

Anyway, dropping the full page cache just to change the Open/Closed status is too much.

Also, we have to take into account the visitor's timezone, which can be different and can be detected right only on the frontend using JS.

Steps to reproduce

1. Get the page with static content, that is fully cached well and has good performance.

2. Add the Office Hours field display widget there, and get problems with always invalidated cache, or outdated information about Open/Close status.

Proposed resolution

To get rid of all these issues with caching and visitor's timezones we can just generate on the backend the static information and cache it on the Drupal side for unlimited time, and render the dynamic information like "Open/Close" status and highlighting of the current day - implement on the frontend using JavaScript.

What do you think about this idea?

Remaining tasks

User interface changes

API changes

Data model changes

Feature request
Status

Active

Version

1.0

Component

Code

Created by

🇦🇲Armenia murz Yerevan, Armenia

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

Comments & Activities

  • Issue created by @murz
  • 🇳🇱Netherlands johnv

    Hi,
    Maintainer and user base have gone through numerous attempts to make the caching work nicely.
    See the issues with ' field cache' or ' anonymous'.
    You do not explain your use case.
    - Are you working with anonymous users od authenticated users?
    - are you using core cache modules
    - are you using external cache?

    In the code, you Will find a JS code that refreshes the field, for anonymous users when page_cache module is enabled.
    You Will also find an alter hook, to change the request time, so you can introduce time zone.
    That hook was introduced, but i never got feedback on that. So it should be working.

    So, please check the code once again, and report back with the result.

  • 🇳🇱Netherlands johnv

    Some more remarks:
    - You will find that (for Anonymous users) a Ajax/JS call is done, calling public function updateStatus() to get the proper status. Is that of any use?
    - Please also check the function hook_office_hours_current_time_alter(int &$time, $entity)

  • 🇳🇱Netherlands johnv

    Reading your OP again.
    Indeed, the module is only designed with local time in mind.
    As stated above, there is a functionality to take the local limezone into account.
    However, not yet taking the cache into account when 'Authenticated users' are located in different timezones.
    Please assess 🐛 Status field caching still broken Active , which could set an inifinite cache max-age, and updating the open/closed status with a JS/Ajax call.

  • 🇮🇳India rahulkhandelwal1990 Gurgugram

    Hi johnv, I tried hook_office_hours_current_time_alter but it is not working for me. In my case i want to set a timezone for stores only and i have set it but it pick always user timezone not the one that i am setting.

  • 🇳🇱Netherlands johnv

    Can you specify a test script?
    Also, use latest dev.

  • 🇮🇳India rahulkhandelwal1990 Gurgugram

    function my_module_office_hours_current_time_alter(int &$time, $entity)
    {
    $date_time = new \DateTime();
    $date_time->setTimestamp($time);
    $date_time->setTimezone(new \DateTimeZone('Asia/Manila'));
    $time = $date_time->getTimestamp();
    // After this set timezone, i am expecting that store status will be display as per Manila timezone irrespective on user timezone.
    }

    Also when i use V1.26, (Add time slot, Clear, Copy last day) stop working for me. These link redirect to homepage.

  • 🇳🇱Netherlands johnv

    Indeed,
    that hook does not do your trick.
    IIRC I never got reaction from the requester after implementing it.

    I guess we hve 2 problems at hand:
    1- the time is not properly formatted, according to timezone
    2- the field cache is not correct for users from different time zones.

    Let me then rephrase the title of this issue from:
    "Rework displaying dynamic information to JS for persistent caching
    to:
    "Field cache and formatter incorrect when working with multiple timezones

    ad 1- time format
    The following hooks are available:
    - hook_office_hours_time_format_alter()
    - hook_office_hours_current_time_alter()
    I guess you need a:
    - hook_office_hours_timeslot_alter()

    At the short term I cannot help you out with this seemingly complicated issue.

    I invite you to check out OfficeHoursItem::formatTimeSlot() and propose a fix in that function or a calling function.
    Please also check the code by searching on 'timezone' and also the Issues

    It was determined that the timezone cannot be determined from within the module, but needs to be fed from custom code, since it is undefined where the appropriate timezone is set (user, entity, ...)

    ad 2- field cache
    As mentioned earlier, 'dropping the full page cache' is not the idea of the current implementation.
    A lot of effort is put into a correct maxAge, after which , indeed, a full page load is triggered.
    But for anonymous users, only the field itself is refreshed.

    Please check OfficeHoursFormatterBase, lines 670-704.
    There you can remove the checks for $this->currentUser->isAnonymous() and moduleExists('page_cache').
    This influences the field caching and starts a JS statusUpdate for only the displayed field.
    It normally only is activated for anonymous users, or when seasons and exceptions are in place.
    (Bear in mind, that there is a check to 10 seconds in the JS, so debugging might influence the DX)

    Also see 🐛 Status field caching still broken Active for an open issue, that I did not grasp entirely, but may be similar to your use case.

    Please report back with your results.

    It may be that we end up with a field setting 'always update the status, upon each field display'.

Production build 0.71.5 2024