diff --git a/src/GraphQLTemplateTrait.php b/src/GraphQLTemplateTrait.php index bd578be..968fe1d 100644 --- a/src/GraphQLTemplateTrait.php +++ b/src/GraphQLTemplateTrait.php @@ -45,8 +45,109 @@ trait GraphQLTemplateTrait { /** * {@inheritdoc} + * Used with Drupal 10.3.0 and later. */ - public function display(array $context, array $blocks = []) { + public function yield(array $context, array $blocks = []): iterable + { + if (!static::hasGraphQLOperations()) { + return parent::yield($context, $blocks); + } + + if (isset($context['graphql_arguments'])) { + $context = $context['graphql_arguments']; + } + + $query = trim($this->getGraphQLQuery()); + + if (!$query) { + return parent::yield($context, $blocks); + } + + $arguments = []; + foreach (static::rawGraphQLArguments() as $var) { + if (isset($context[$var])) { + $arguments[$var] = $context[$var] instanceof EntityInterface ? $context[$var]->id() : $context[$var]; + } + } + + $queryResult = $this->env->getGraphQlServer()->executeOperation(OperationParams::create([ + 'query' => $query, + 'variables' => $arguments, + ])); + + $build = [ + '#cache' => [ + 'contexts' => $queryResult->getCacheContexts(), + 'tags' => $queryResult->getCacheTags(), + 'max-age' => $queryResult->getCacheMaxAge(), + ], + ]; + + $this->env->getRenderer()->render($build); + + $config = \Drupal::config('graphql_twig.settings'); + $debug_placement = $config->get('debug_placement'); + + if ($this->env->isDebug() && \Drupal::currentUser()->hasPermission('use graphql explorer')) { + // Auto-attach the debug assets if necessary. + $template_attached = ['#attached' => ['library' => ['graphql_twig/debug']]]; + $this->env->getRenderer()->render($template_attached); + } + + if ($this->env->isDebug() && $debug_placement == 'wrapped') { + printf( + '
', + 'graphql-twig-debug-wrapper', + htmlspecialchars($query), + htmlspecialchars(json_encode($arguments)), + ); + } + + if ($this->env->isDebug() && $queryResult->errors) { + print(''); + } + + if (!$queryResult->errors) { + // Allow graphql data alteration. + /** @var \Drupal\Core\Theme\ThemeManager $themeManager */ + $themeManager = \Drupal::service('theme.manager'); + $themeManager->alter('graphql_twig_data', $queryResult->data, $context); + $context['graphql'] = $queryResult->data; + + if ($this->env->isDebug() && $debug_placement == 'inside') { + $context['graphql_debug'] = [ + '#markup' => sprintf( + '
', + 'graphql-twig-debug-wrapper', + htmlspecialchars($query), + htmlspecialchars(json_encode($arguments)) + ), + ]; + + // Add the debug parent class to the element. + /** @var \Drupal\Core\Template\Attribute $attributes */ + $attributes = $context['attributes']; + $attributes->addClass('graphql-twig-debug-parent'); + } + } + + if ($this->env->isDebug() && $debug_placement == 'wrapped') { + print('
'); + } + + return parent::yield($context, $blocks); + } + + /** + * {@inheritdoc} + * Used with Drupal 10.2.0 and earlier. + * TODO: Remove this method when we just want to support Drupal 10.3.0 and later. + */ + public function display(array $context, array $blocks = []): void { if (!static::hasGraphQLOperations()) { parent::display($context, $blocks); return;