diff --git a/README.md b/README.md index c014013..d88e838 100644 --- a/README.md +++ b/README.md @@ -39,3 +39,33 @@ to flush the display cache caches. * Call Home » Administration » Configuration » Development » Display Cache and submit the form. + +## Circumvent the display cache (Programmatically) + +There might be some cases where you do not want the cached entity in your module +or theme or whereever. + +There is a programmatically way to prevent display cache from fetching the +cached version of an entity view. + +Simply attach the constant `DISPLAY_CACHE_VIEW_MODE_CACHE_IGNORE_SUFFIX` to your +required view mode and display cache will not interfere. + +Please be aware that this feature should only be used by programmers INSIDE the +code. + +*Do not try to use this feature via the admin interface.* + +## Pitfalls + +Please be aware that JS, CSS and libraries attached in view hooks via +drupal_add_js(), drupal_add_css() or drupal_add_library() are not reattached +if the entity view is served from display cache. +To accomplish this, you need to attach it to the node render array directly via +the '#attached' key. That way the JS, CSS and libraries are stored along with +the rendered view mode's HTML. + +Setting the granularity to a very high level for example "Cache per URL and per +User" can lead to useless caching for big sites, because depending on the +caching mechanismens the lookup gets really slow or older cached items get +thrown away. diff --git a/display_cache.module b/display_cache.module index 72b348b..c825238 100644 --- a/display_cache.module +++ b/display_cache.module @@ -18,6 +18,13 @@ define('DISPLAY_CACHE_FIELDS', '2'); define('DISPLAY_CACHE_CACHE_BIN', 'cache_display_cache'); /** + * Suffix to a view mode that triggers on-the-fly re-rendering of the view mode. + * + * @var string + */ +define('DISPLAY_CACHE_VIEW_MODE_CACHE_IGNORE_SUFFIX', ':display_cache_no_cache'); + +/** * Implements hook_form_FORM_ID_alter(). */ function display_cache_form_field_ui_display_overview_form_alter(&$form, &$form_state) { @@ -42,13 +49,13 @@ function display_cache_menu() { // Menu item for configurations. $menu_items['admin/config/development/display-cache'] = array( - 'title' => 'Display Cache', - 'description' => 'Form to submit cache flush for display cache.', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('display_cache_flush_caches_form'), + 'title' => 'Display Cache', + 'description' => 'Form to submit cache flush for display cache.', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('display_cache_flush_caches_form'), 'access arguments' => array('administer display cache'), - 'file' => 'display_cache.admin.inc', - 'type' => MENU_NORMAL_ITEM, + 'file' => 'display_cache.admin.inc', + 'type' => MENU_NORMAL_ITEM, ); return $menu_items; @@ -59,7 +66,7 @@ function display_cache_menu() { */ function display_cache_admin_menu_cache_info() { $links['display_cache'] = array( - 'title' => 'Display Caches', + 'title' => 'Display Caches', 'callback' => '_display_cache_clear_cache', ); @@ -72,7 +79,7 @@ function display_cache_admin_menu_cache_info() { function display_cache_permission() { return array( 'administer display cache' => array( - 'title' => t('Administer Display Cache'), + 'title' => t('Administer Display Cache'), 'description' => t('Permission to administer display cache settings and clear display cache caches from the ui.'), ), ); @@ -152,10 +159,10 @@ function display_cache_get_settings($entity_type, $bundle, $view_mode) { if (!$settings) { return array( 'default' => array( - 'use' => DISPLAY_CACHE_DISABLED, + 'use' => DISPLAY_CACHE_DISABLED, 'page_granularity' => DISPLAY_CACHE_DISABLED, 'user_granularity' => DISPLAY_CACHE_DISABLED, - 'granularity' => DISPLAY_CACHE_DISABLED, + 'granularity' => DISPLAY_CACHE_DISABLED, ), ); } @@ -204,8 +211,8 @@ function display_cache_entity_view_alter(&$build, $entity_type) { $keys = display_cache_get_cache_keys($entity_type, $entity_id, $view_mode, 'entity'); $build['#cache'] = array( - 'keys' => $keys, - 'bin' => DISPLAY_CACHE_CACHE_BIN, + 'keys' => $keys, + 'bin' => DISPLAY_CACHE_CACHE_BIN, 'granularity' => $display_settings['granularity'], ); } @@ -244,8 +251,8 @@ function display_cache_field_attach_view_alter(&$output, $context) { $keys = display_cache_get_cache_keys($entity_type, $entity_id, $view_mode, $field_name); $element['#cache'] = array( - 'keys' => $keys, - 'bin' => 'cache_display_cache', + 'keys' => $keys, + 'bin' => DISPLAY_CACHE_CACHE_BIN, 'granularity' => $settings[$field_name]['granularity'], ); } @@ -279,19 +286,22 @@ function display_cache_entity_info_alter(&$entity_info) { function display_cache_view_entity($entities, $view_mode, $langcode, $entity_type) { $info = entity_get_info($entity_type); $return = array(); + $ignore_cache = (strpos($view_mode, DISPLAY_CACHE_VIEW_MODE_CACHE_IGNORE_SUFFIX) !== FALSE); + + if ($ignore_cache) { + $view_mode = str_replace(':display_cache_no_cache', '', $view_mode); + } foreach ($entities as $entity_id => $entity) { $render_array = array(); // Disable display_cache by global setting. - if (variable_get('display_cache_disable', FALSE) === FALSE) { - $entity_info = entity_get_info($entity_type); - // Try to find a bundle key from the entity info. - if (!empty($entity_info['entity keys']['bundle'])) { - $bundle_key = $entity_info['entity keys']['bundle']; + if (!$ignore_cache && variable_get('display_cache_disable', FALSE) === FALSE) { + if (!empty($info['entity keys']['bundle'])) { + $bundle_key = $info['entity keys']['bundle']; } elseif (!empty($entity_info['bundle keys']['bundle'])) { - $bundle_key = $entity_info['bundle keys']['bundle']; + $bundle_key = $info['bundle keys']['bundle']; } // This entity may not have a bundle key, fallback to the entity type. @@ -302,25 +312,10 @@ function display_cache_view_entity($entities, $view_mode, $langcode, $entity_typ $bundle = $entity_type; } - $settings = display_cache_get_settings($entity_type, $bundle, $view_mode); - - if ($settings['default']['use'] == DISPLAY_CACHE_ENABLED) { - // Get rendered HTML from cache. - $keys = display_cache_get_cache_keys($entity_type, $entity_id, $view_mode, 'entity'); - $cid_parts = array( - '#cache' => array( - 'keys' => $keys, - 'granularity' => $settings['default']['granularity'], - ), - ); - - $cid = drupal_render_cid_create($cid_parts); - $data = cache_get($cid, DISPLAY_CACHE_CACHE_BIN); - if (!empty($data->data)) { - $render_array = $data->data; - } - } + $render_array = display_cache_get_cached_display($entity_type, $bundle, $entity_id, $view_mode, 'entity'); } + + // No cached result was found. Render entity. if (empty($render_array)) { // Get renderable array. if (isset($info['entity view callback'])) { @@ -340,6 +335,51 @@ function display_cache_view_entity($entities, $view_mode, $langcode, $entity_typ } /** + * Check for cached display. + * + * @param string $entity_type + * The entity type. + * @param string $bundle + * The bundle. + * @param int $entity_id + * The entity id. + * @param string $view_mode + * The view mode. + * @param string $element + * Element which is cached like 'entity', 'field' or 'render_array'. + * + * @return array + * A render array containing only a #markup index. + */ +function display_cache_get_cached_display($entity_type, $bundle = NULL, $entity_id = NULL, $view_mode = NULL, $element = 'entity') { + // Initiate result. + $result = array(); + + // Get settings. + $settings = display_cache_get_settings($entity_type, $bundle, $view_mode); + + if ($settings['default']['use'] == DISPLAY_CACHE_ENABLED) { + // Get rendered HTML from cache. + $keys = display_cache_get_cache_keys($entity_type, $entity_id, $view_mode, $element); + $cid_parts = array( + '#cache' => array( + 'keys' => $keys, + 'granularity' => $settings['default']['granularity'], + ), + ); + + $cid = drupal_render_cid_create($cid_parts); + + $data = cache_get($cid, DISPLAY_CACHE_CACHE_BIN); + if (!empty($data->data)) { + $result = $data->data; + } + } + + return $result; +} + +/** * Implements hook_module_implements_alter(). * * Move the hook implementation of hook_entity_info_alter() to the bottom to be