core/modules/filter/filter.module | 4 +-- core/modules/filter/src/FilterProcessResult.php | 29 ++++++++++++++++++++++ core/modules/filter/src/Plugin/FilterInterface.php | 6 ++--- core/modules/filter/src/Tests/FilterAPITest.php | 8 +++--- .../Plugin/Filter/FilterTestPostRenderCache.php | 12 ++++----- 5 files changed, 45 insertions(+), 14 deletions(-) diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module index 51b89e7..afdaadf 100644 --- a/core/modules/filter/filter.module +++ b/core/modules/filter/filter.module @@ -306,8 +306,8 @@ function filter_fallback_format() { * Note: this function should only be used when filtering text for use elsewhere * than on a rendered HTML page. If this is part of a HTML page, then a * renderable array with a #type 'processed_text' element should be used instead - * of this, because that will allow cache tags to be set and bubbled up, assets - * to be loaded and #post_render_cache callbacks to be associated. In other + * of this, because that will allow cacheability metadata to be set and bubbled + * up and attachments to be associated (assets, placeholders, etc.). In other * words: if you are presenting the filtered text in a HTML page, the only way * this will be presented correctly, is by using the 'processed_text' element. * diff --git a/core/modules/filter/src/FilterProcessResult.php b/core/modules/filter/src/FilterProcessResult.php index 268a179..c522497 100644 --- a/core/modules/filter/src/FilterProcessResult.php +++ b/core/modules/filter/src/FilterProcessResult.php @@ -116,4 +116,33 @@ public function setProcessedText($processed_text) { $this->processedText = $processed_text; return $this; } + + /** + * Creates a placeholder. + * + * @param string $callback + * The #pre_render_cache callback that will replace the placeholder with + * its eventual markup. + * @param array $context + * An array providing context for the #pre_render_cache callback. + * + * @see \Drupal\Core\Render\RendererInterface::generateCachePlaceholder() + * + * @return string + * The placeholder markup. + */ + public function createPlaceholder($callback, array $context) { + $placeholder = \Drupal::service('renderer')->generateCachePlaceholder($callback, $context); + $this->addAttachments([ + 'placeholders' => [ + $placeholder => [ + '#pre_render_cache' => [ + $callback => $context, + ], + ] + ], + ]); + return $placeholder; + } + } diff --git a/core/modules/filter/src/Plugin/FilterInterface.php b/core/modules/filter/src/Plugin/FilterInterface.php index aa2438b..5643a22 100644 --- a/core/modules/filter/src/Plugin/FilterInterface.php +++ b/core/modules/filter/src/Plugin/FilterInterface.php @@ -46,8 +46,8 @@ * - declare cache tags that the resulting filtered text depends upon, so when * either of those cache tags is invalidated, the render-cached HTML that the * filtered text is part of should also be invalidated; - * - declare #post_render_cache callbacks to apply uncacheable filtering, for - * example because it differs per user. + * - create placeholders to apply uncacheable filtering, for example because it + * changes every few seconds. * * @see \Drupal\filter\Plugin\FilterInterface::process() * @@ -169,7 +169,7 @@ public function prepare($text, $langcode); * * @return \Drupal\filter\FilterProcessResult * The filtered text, wrapped in a FilterProcessResult object, and possibly - * with associated assets, cache tags and #post_render_cache callbacks. + * with associated assets, cacheability metadata and placeholders. * * @see \Drupal\filter\FilterProcessResult */ diff --git a/core/modules/filter/src/Tests/FilterAPITest.php b/core/modules/filter/src/Tests/FilterAPITest.php index d12d2ba..21dea78 100644 --- a/core/modules/filter/src/Tests/FilterAPITest.php +++ b/core/modules/filter/src/Tests/FilterAPITest.php @@ -242,14 +242,16 @@ function testProcessedTextElement() { ); drupal_render_root($build); - // Verify the assets, cache tags and #pre_render_cache callbacks. - $expected_assets = array( + // Verify the attachments and cacheability metadata. + $expected_attachments = array( // The assets attached by the filter_test_assets filter. 'library' => array( 'filter/caption', ), + // The placeholders attached that still need to be processed. + 'placeholders' => [], ); - $this->assertEqual($expected_assets, $build['#attached'], 'Expected assets present'); + $this->assertEqual($expected_attachments, $build['#attached'], 'Expected attachments present'); $expected_cache_tags = array( // The cache tag set by the processed_text element itself. 'config:filter.format.element_test', diff --git a/core/modules/filter/tests/filter_test/src/Plugin/Filter/FilterTestPostRenderCache.php b/core/modules/filter/tests/filter_test/src/Plugin/Filter/FilterTestPostRenderCache.php index 2f78599..8438372 100644 --- a/core/modules/filter/tests/filter_test/src/Plugin/Filter/FilterTestPostRenderCache.php +++ b/core/modules/filter/tests/filter_test/src/Plugin/Filter/FilterTestPostRenderCache.php @@ -11,12 +11,12 @@ use Drupal\filter\Plugin\FilterBase; /** - * Provides a test filter to associate #post_render_cache callbacks. + * Provides a test filter to use placeholders. * * @Filter( * id = "filter_test_post_render_cache", * title = @Translation("Testing filter"), - * description = @Translation("Appends a placeholder to the content; associates #post_render_cache callbacks."), + * description = @Translation("Appends a placeholder to the content; associates #pre_render_cache callback."), * type = Drupal\filter\Plugin\FilterInterface::TYPE_TRANSFORM_REVERSIBLE * ) */ @@ -30,10 +30,10 @@ public function process($text, $langcode) { $context = array( 'thing' => 'llama', ); - $placeholder = drupal_render_cache_generate_placeholder($callback, $context); - $result = new FilterProcessResult($text . '

' . $placeholder . '

'); - // @todo Should we keep BC? - $result->addPostRenderCacheCallback($callback, $context); + + $result = new FilterProcessResult($text); + $placeholder = $result->createPlaceholder($callback, $context); + $result->setProcessedText($text . '

' . $placeholder . '

'); return $result; }