Voting starts in March for the Drupal Association Board election.
On multilingual sites, when caching is enabled and language negotiation is set to "Path prefix with language fallback", page caches are set to the first visitor's browser language preferences in cases of fallback. All subsequent visitors get pages in that first visitor's language rather than their own.
Setting the language based on browser language means there are multiple languages in which a particular page/path can be served. However, since page caching is determined on the basis of the request URI, only one cache can be set per page/path.
More generally: The Drupal cache system doesn't support multiple versions of a page per URL. Any time a particular URL may be served in more than one version, the first visitor's version will determine the cache.
Steps to reproduce:
1. Drop browser language detection support (or limit it to authenticated users).
This approach would restrict browser language detection to authenticated users, who don't get late page caches, or else remove the "Path prefix with language fallback" option altogether.
Doing so would address the issue but lose some valuable functionality.
2. In the case of a language fallback, forward to the new path, including the correct prefix.
By forwarding, we could ensure that the path matches the language of the page served.
This approach would mean:
- Move the DRUPAL_BOOTSTRAP_LANGUAGE bootstrap phase to come before DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE. This is needed because we need to determine a potential language/path mismatch before consulting the cache.
- In the case that the path doesn't include a prefix for the negotiated language, abort bootstrapping and goto a prefixed path.
3. Include language information in the cache key.
If we determine language before caching, we can include language information in the cache key and so have language-appropriate cache results.
This approach would mean:
- Move the DRUPAL_BOOTSTRAP_LANGUAGE bootstrap phase to come before DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE.
- In page_get_cache() and page_set_cache(), call a helper function to add the language information to the cache key. E.g., append something like
'cache_language=' . $language->language.
I think all these options are worth considering, as well as other approaches others may come up with.
Options 2 and 3 are significant API changes. They represent two different basic approaches. Option 2 reflects the position that we should never have two different versions of the same URL. Option 3 assumes that having two different versions of the same URL should sometimes be supported. (See this related issue/discussion:.)
And even if we solve late page caching, we still have early page caching to worry about. Neither option 2 nor option 3 addresses the problem presented by DRUPAL_BOOTSTRAP_EARLY_PAGE_CACHE. If we have file-based caching, invoked before we have database access etc., how can we negotiate language ahead of invoking that cache so we know which version of a page we're concerned with?
FAILED: [[SimpleTest]]: [MySQL] 40,373 pass(es), 14 fail(s), and 0 exception(s). View
Failed: 10700 passes, 6 fails, 0 exceptions View
Failed: 10702 passes, 8 fails, 0 exceptions View
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch cache_negotiation_D6.patch. Unable to apply patch. See the log in the details link for more information. View