Browse Source

Merge branch '3313874-add-ability-to' into '3.x'

Issue #3313874: Add ability to evaluate conditions like the block visibility settings

See merge request project/twig_tweak!17
merge-requests/17/merge
Rodrigo Aguilera 2 years ago
parent
commit
68846ba597
  1. 8
      docs/cheat-sheet.md
  2. 42
      src/TwigTweakExtension.php

8
docs/cheat-sheet.md

@ -386,6 +386,14 @@ ensure that cache metadata are bubbled up.
{{ content.field_media|cache_metadata }}
```
## 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. Set the `#access` key to a render array to control visibility.
```twig
{# Display content only for the spanish language #}
{{ content|set_conditional_access('language', {'langcodes': {'es':'es'}}) }}
```
## PHP
PHP filter is disabled by default. You can enable it in `settings.php` file as
follows:

42
src/TwigTweakExtension.php

@ -6,6 +6,7 @@ use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\UrlHelper;
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;
@ -118,6 +119,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')) {
@ -704,6 +707,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.
*

Loading…
Cancel
Save