From d352a3bf9594d2a41f2745fd120a0296c05ebc08 Mon Sep 17 00:00:00 2001 From: Rodrigo Aguilera Date: Thu, 6 Oct 2022 17:14:04 +0200 Subject: [PATCH] Transform into a twig filter. --- docs/cheat-sheet.md | 9 ++--- src/TwigTweakExtension.php | 75 +++++++++++++++++++++----------------- 2 files changed, 46 insertions(+), 38 deletions(-) diff --git a/docs/cheat-sheet.md b/docs/cheat-sheet.md index 301d1d4..fa8ec32 100644 --- a/docs/cheat-sheet.md +++ b/docs/cheat-sheet.md @@ -351,13 +351,12 @@ ensure that cache metadata are bubbled up. {{ content.field_media|cache_metadata }} ``` -## Conditions from context +## Conditions from context for access to render arrays The system that controls the visibility of blocks can be used to evaluate -if a condition is fullfilled. +if a condition is fullfilled. Set the `#access` key to a render array to control visibility. ```twig -{% if languageIsSpanish = drupal_condition_evaluate('language', {'langcodes': {'es':'es'}}) %} -Hola -{% endif %} +{# Display content only for the spanish language #} +{{ content|set_conditional_access('language', {'langcodes': {'es':'es'}}) }} ``` ## PHP diff --git a/src/TwigTweakExtension.php b/src/TwigTweakExtension.php index acc12bd..854e2fa 100644 --- a/src/TwigTweakExtension.php +++ b/src/TwigTweakExtension.php @@ -5,6 +5,7 @@ namespace Drupal\twig_tweak; use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\Unicode; use Drupal\Component\Uuid\Uuid; +use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Extension\ModuleHandlerInterface; @@ -86,8 +87,6 @@ class TwigTweakExtension extends AbstractExtension { new TwigFunction('drupal_breakpoint', [self::class, 'drupalBreakpoint'], $all_options), // @phpcs:ignore Drupal.Arrays.Array.LongLineDeclaration new TwigFunction('drupal_contextual_links', [self::class, 'drupalContextualLinks']), - // @phpcs:ignore Drupal.Arrays.Array.LongLineDeclaration - new TwigFunction('drupal_condition_evaluate', [self::class, 'drupalConditionEvaluate']), ]; $this->moduleHandler->alter('twig_tweak_functions', $functions); @@ -118,6 +117,8 @@ class TwigTweakExtension extends AbstractExtension { new TwigFilter('entity_link', [self::class, 'entityLink']), new TwigFilter('translation', [self::class, 'entityTranslation']), new TwigFilter('cache_metadata', [self::class, 'CacheMetadata']), + // @phpcs:ignore Drupal.Arrays.Array.LongLineDeclaration + new TwigFilter('set_conditional_access', [self::class, 'setConditionalAccess']), ]; if (Settings::get('twig_tweak_enable_php_filter')) { @@ -422,37 +423,6 @@ class TwigTweakExtension extends AbstractExtension { return $build; } - /** - * Use a condition plugin to evaluate based on the context. - * - * @param string $plugin_id - * The plugin ID. - * @param array $configuration - * Configuration for the plugin. - * - * @return bool - * The evaluation of the plugin. - */ - public static function drupalConditionEvaluate(string $plugin_id, array $configuration = []): bool { - $pluginInstance = \Drupal::service('plugin.manager.condition')->createInstance($plugin_id); - $pluginInstance->setConfiguration($configuration); - $contextRepository = \Drupal::service('context.repository'); - $availableContexts = $contextRepository->getAvailableContexts(); - - // Ensure that the contexts have data by getting corresponding runtime contexts. - $availableRuntimeContexts = $contextRepository->getRuntimeContexts(array_keys($availableContexts)); - $pluginContextDefinitions = $pluginInstance->getContextDefinitions(); - foreach ($pluginContextDefinitions as $name => $pluginContextDefinition) { - // Identify and fetch the matching runtime context, with the plugin's context definition. - $matches = \Drupal::service('context.handler')->getMatchingContexts($availableRuntimeContexts, $pluginContextDefinition); - $matchingContext = reset($matches); - - // Set the value to the plugin's context, from runtime context value. - $pluginInstance->setContextValue($name, $matchingContext->getContextValue()); - } - return $pluginInstance->evaluate(); - } - /** * Emits a breakpoint to the debug client. * @@ -719,6 +689,45 @@ class TwigTweakExtension extends AbstractExtension { return \Drupal::service('twig_tweak.cache_metadata_extractor')->extractCacheMetadata($input); } + /** + * Use a condition plugin to give access to a render array. + * + * The evaluation is based on the context. + * + * @param string $build + * A render array. + * @param string $plugin_id + * The plugin ID. + * @param array $configuration + * Configuration for the plugin. + * + * @return array + * The render array with the evaluation of the plugin in the #access key. + */ + public static function setConditionalAccess($build, string $plugin_id, array $configuration = []): array { + $pluginInstance = \Drupal::service('plugin.manager.condition')->createInstance($plugin_id); + $pluginInstance->setConfiguration($configuration); + $contextRepository = \Drupal::service('context.repository'); + $availableContexts = $contextRepository->getAvailableContexts(); + + // Ensure that the contexts have data by getting corresponding runtime contexts. + $availableRuntimeContexts = $contextRepository->getRuntimeContexts(array_keys($availableContexts)); + $pluginContextDefinitions = $pluginInstance->getContextDefinitions(); + foreach ($pluginContextDefinitions as $name => $pluginContextDefinition) { + // Identify and fetch the matching runtime context, with the plugin's context definition. + $matches = \Drupal::service('context.handler')->getMatchingContexts($availableRuntimeContexts, $pluginContextDefinition); + $matchingContext = reset($matches); + $build['#cache']['contexts'] = Cache::mergeContexts($matchingContext->getCacheContexts(), $build['#cache']['contexts'] ?? []); + $build['#cache']['tags'] = Cache::mergeTags($matchingContext->getCacheTags(), $build['#cache']['tags'] ?? []); + $build['#cache']['max-age'] = Cache::mergeMaxAges($matchingContext->getCacheMaxAge(), $build['#cache']['max-age'] ?? Cache::PERMANENT); + + // Set the value to the plugin's context, from runtime context value. + $pluginInstance->setContextValue($name, $matchingContext->getContextValue()); + } + $build['#access'] = $pluginInstance->evaluate(); + return $build; + } + /** * Evaluates a string of PHP code. *