diff --git a/src/TwigTweakExtension.php b/src/TwigTweakExtension.php index 7052240..b23ec21 100644 --- a/src/TwigTweakExtension.php +++ b/src/TwigTweakExtension.php @@ -6,6 +6,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\Unicode; use Drupal\Component\Uuid\Uuid; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Field\EntityReferenceFieldItemListInterface; use Drupal\Core\Field\FieldItemInterface; use Drupal\Core\Field\FieldItemListInterface; @@ -14,6 +15,7 @@ use Drupal\Core\Link; use Drupal\Core\Render\Element; use Drupal\Core\Render\Markup; use Drupal\Core\Site\Settings; +use Drupal\Core\Theme\ThemeManagerInterface; use Drupal\Core\Url; use Drupal\file\Entity\File; use Drupal\file\FileInterface; @@ -35,6 +37,28 @@ use Twig\TwigFunction; */ class TwigTweakExtension extends AbstractExtension { + /** + * The module handler to invoke alter hooks. + * + * @var \Drupal\Core\Extension\ModuleHandlerInterface + */ + protected $moduleHandler; + + /** + * The theme manager to invoke alter hooks. + * + * @var \Drupal\Core\Theme\ThemeManagerInterface + */ + protected $themeManager; + + /** + * Constructs the TwigTweakExtension object. + */ + public function __construct(ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager) { + $this->moduleHandler = $module_handler; + $this->themeManager = $theme_manager; + } + /** * {@inheritdoc} */ @@ -42,7 +66,7 @@ class TwigTweakExtension extends AbstractExtension { $context_options = ['needs_context' => TRUE]; $all_options = ['needs_environment' => TRUE, 'needs_context' => TRUE]; - return [ + $functions = [ new TwigFunction('drupal_view', 'views_embed_view'), new TwigFunction('drupal_view_result', 'views_get_view_result'), new TwigFunction('drupal_block', [self::class, 'drupalBlock']), @@ -67,6 +91,11 @@ class TwigTweakExtension extends AbstractExtension { new TwigFunction('drupal_breakpoint', [self::class, 'drupalBreakpoint'], $all_options), new TwigFunction('drupal_contextual_links', [self::class, 'drupalContextualLinks']), ]; + + $this->moduleHandler->alter('twig_tweak_functions', $functions); + $this->themeManager->alter('twig_tweak_functions', $functions); + + return $functions; } /** @@ -92,9 +121,24 @@ class TwigTweakExtension extends AbstractExtension { $filters[] = new TwigFilter('php', [self::class, 'phpFilter']); } + $this->moduleHandler->alter('twig_tweak_filters', $filters); + $this->themeManager->alter('twig_tweak_filters', $filters); + return $filters; } + /** + * {@inheritdoc} + */ + public function getTests(): array { + $tests = []; + + $this->moduleHandler->alter('twig_tweak_tests', $tests); + $this->themeManager->alter('twig_tweak_tests', $tests); + + return $tests; + } + /** * Builds the render array for a block. */ diff --git a/tests/src/Functional/TwigTweakTest.php b/tests/src/Functional/TwigTweakTest.php index 264bdb4..042a8e7 100644 --- a/tests/src/Functional/TwigTweakTest.php +++ b/tests/src/Functional/TwigTweakTest.php @@ -358,6 +358,18 @@ final class TwigTweakTest extends BrowserTestBase { // -- File URL from media field. $xpath = '//div[@class = "tt-file-url-from-media-field" and contains(text(), "/files/image-1.png")]'; $this->assertXpath($xpath); + + // -- Hook twig_tweak_functions_alter(). + $xpath = '//div[@class = "tt-functions_alter" and text() = "-=bar=-"]'; + $this->assertXpath($xpath); + + // -- Hook twig_tweak_filters_alter(). + $xpath = '//div[@class = "tt-filters_alter" and text() = "bar"]'; + $this->assertXpath($xpath); + + // -- Hook twig_tweak_tests_alter(). + $xpath = '//div[@class = "tt-tests_alter" and text() = "Yes"]'; + $this->assertXpath($xpath); } /** diff --git a/tests/twig_tweak_test/templates/twig-tweak-test.html.twig b/tests/twig_tweak_test/templates/twig-tweak-test.html.twig index dcc9f28..0cca8eb 100644 --- a/tests/twig_tweak_test/templates/twig-tweak-test.html.twig +++ b/tests/twig_tweak_test/templates/twig-tweak-test.html.twig @@ -89,4 +89,7 @@
{{ node.field_image|file_url }}
{{ node.field_image[0]|file_url }}
{{ node.field_media|file_url }}
+
{{ foo('bar') }}
+
{{ 'foo'|bar }}
+
{{ 'ok' is ok ? 'Yes' : 'No' }}
diff --git a/tests/twig_tweak_test/twig_tweak_test.module b/tests/twig_tweak_test/twig_tweak_test.module index 02c9795..6114e8d 100644 --- a/tests/twig_tweak_test/twig_tweak_test.module +++ b/tests/twig_tweak_test/twig_tweak_test.module @@ -11,6 +11,9 @@ use Drupal\Core\Access\AccessResultInterface; use Drupal\file\FileInterface; use Drupal\node\Entity\Node; use Drupal\node\NodeInterface; +use Twig\TwigFilter; +use Twig\TwigFunction; +use Twig\TwigTest; /** * Implements hook_page_bottom(). @@ -72,3 +75,30 @@ function twig_tweak_test_file_access(FileInterface $file): AccessResultInterface $result->setCacheMaxAge(70); return $result; } + +/** + * Implements hook_twig_tweak_functions_alter(). + */ +function twig_tweak_test_twig_tweak_functions_alter(array &$functions) { + $functions[] = new TwigFunction('foo', function (string $value): string { + return "-=$value=-"; + }); +} + +/** + * Implements hook_twig_tweak_filters_alter(). + */ +function twig_tweak_test_twig_tweak_filters_alter(array &$filters) { + $filters[] = new TwigFilter('bar', function (string $input): string { + return str_replace('foo', 'bar', $input); + }); +} + +/** + * Implements hook_twig_tweak_tests_alter(). + */ +function twig_tweak_test_twig_tweak_tests_alter(array &$tests) { + $tests[] = new TwigTest('ok', function ($input): bool { + return $input == 'ok'; + }); +} diff --git a/twig_tweak.api.php b/twig_tweak.api.php new file mode 100644 index 0000000..31d0bfa --- /dev/null +++ b/twig_tweak.api.php @@ -0,0 +1,67 @@ +getRequestTime() - $node->getCreatedTime() > 3600 * 24 * 365; + }); +} + +/** + * @} End of "addtogroup hooks". + */ diff --git a/twig_tweak.services.yml b/twig_tweak.services.yml index 70d11cf..8ae8efa 100644 --- a/twig_tweak.services.yml +++ b/twig_tweak.services.yml @@ -1,6 +1,7 @@ services: twig_tweak.twig_extension: class: Drupal\twig_tweak\TwigTweakExtension + arguments: ['@module_handler', '@theme.manager'] tags: - { name: twig.extension }