core/modules/system/theme.api.php | 60 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/core/modules/system/theme.api.php b/core/modules/system/theme.api.php index db1dbbf..e555eef 100644 --- a/core/modules/system/theme.api.php +++ b/core/modules/system/theme.api.php @@ -339,6 +339,10 @@ * regenerated. So my cache tags would be: ['node:5', 'user:3', 'file:4', * 'config:filter.format.basic_html']. * + * (Note: Drupal sets all the cache metadata in the above example automatically: + * the entity view builder and field formatters take care of that. It's just + * meant to be a concrete example that is intuitively understood by all.) + * * In summary: when a render array represents a thing, then: * - cache keys identify a representation of a thing * - may only be set if this render array should be cached @@ -351,6 +355,62 @@ * Note that every Entity and Config has a ::getCacheTags() method, with which * one can easily get the cache tags of the objects a render array depends upon. * + * Looking at a concrete example: + * @code + * $config = \Drupal::config('system.site'); + * $current_user = \Drupal::currentUser(); + * + * $build = [ + * '#prefix' => '', + * '#cache' => [ + * 'contexts' => [ + * 'user', + * ], + * 'tags' => \Drupal\Core\Cache\Cache::mergeTags( + * $config->getCacheTags(), + * \Drupal\user\Entity\User::load($current_user->id())->getCacheTags() + * ), + * ], + * ]; + * @encode + * + * We're generating markup that contains the user name and the site name. The + * user name is tied to a User entity, so we want to associate its cache tags. + * And since that output varies per user (it's a personal welcome message, after + * all), we must also specify the 'user' cache context. The site name is stored + * in config, so we want to associate the cache tags of the config that the + * output depends on as well. + * + * That's quite a bit of code. But we're now informing Drupal correctly about + * the cacheability of this render array & markup! + * + * Let's see how that changes if we make the welcome message not personal, but + * generic: + * @code + * $config = \Drupal::config('system.site'); + * + * $build = [ + * '#prefix' => '', + * '#cache' => [ + * 'tags' => $config->getCacheTags(), + * ], + * ]; + * @encode + * + * The generated markup is only slightly different, but the code became much + * simpler! It's logical though: the markup can now be used for all users, so + * less cacheability metadata is necessary. Most notably, no cache contexts are + * present anymore (after all, there's only a single variation left now). + * * Finally: it is easy to see what cache contexts a certain page varies by and * which cache tags it is invalidated by: one must only look at the * X-Drupal-Cache-Contexts and X-Drupal-Cache-Tags headers!