RenderContext example



  /** * {@inheritdoc} */
  public function mail($module$key$to$langcode$params = []$reply = NULL, $send = TRUE) {
    // Mailing can invoke rendering (e.g., generating URLs, replacing tokens),     // but e-mails are not HTTP responses: they're not cached, they don't have     // attachments. Therefore we perform mailing inside its own render context,     // to ensure it doesn't leak into the render context for the HTTP response     // to the current request.     return $this->renderer->executeInRenderContext(new RenderContext()function D) use ($module$key$to$langcode$params$reply$send) {
      return $this->doMail($module$key$to$langcode$params$reply$send);
    });
  }

  /** * Composes and optionally sends an email message. * * @param string $module * A module name to invoke hook_mail() on. The {$module}_mail() hook will be * called to complete the $message structure which will already contain * common defaults. * @param string $key * A key to identify the email sent. The final message ID for email altering * will be {$module}_{$key}. * @param string $to * The email address or addresses where the message will be sent to. The * formatting of this string will be validated with the * @link http://php.net/manual/filter.filters.validate.php PHP email validation filter. @endlink * Some examples are: * - user@example.com * - user@example.com, anotheruser@example.com * - User <user@example.com> * - User <user@example.com>, Another User <anotheruser@example.com> * @param string $langcode * Language code to use to compose the email. * @param array $params * (optional) Parameters to build the email. Use the key '_error_message' * to provide translatable markup to display as a message if an error * occurs, or set this to false to disable error display. * @param string|null $reply * Optional email address to be used to answer. * @param bool $send * If TRUE, call an implementation of * \Drupal\Core\Mail\MailInterface->mail() to deliver the message, and * store the result in $message['result']. Modules implementing * hook_mail_alter() may cancel sending by setting $message['send'] to * FALSE. * * @return array * The $message array structure containing all details of the message. If * already sent ($send = TRUE), then the 'result' element will contain the * success indicator of the email, failure being already written to the * watchdog. (Success means nothing more than the message being accepted at * php-level, which still doesn't guarantee it to be delivered.) * * @see \Drupal\Core\Mail\MailManagerInterface::mail() */

  protected function wrapControllerExecutionInRenderContext($controller, array $arguments) {
    $context = new RenderContext();

    $response = $this->renderer->executeInRenderContext($contextfunction D) use ($controller$arguments) {
      // Now call the actual controller, just like HttpKernel does.       return call_user_func_array($controller$arguments);
    });

    // If early rendering happened, i.e. if code in the controller called     // RendererInterface::render() outside of a render context, then the     // bubbleable metadata for that is stored in the current render context.     if (!$context->isEmpty()) {
      /** @var \Drupal\Core\Render\BubbleableMetadata $early_rendering_bubbleable_metadata */
      
$build['p1'] = [
      '#lazy_builder' => ['\Drupal\render_placeholder_message_test\RenderPlaceholderMessageTestController::setAndLogMessage', ['P1']],
      '#create_placeholder' => TRUE,
    ];
    $build['p2'] = [
      '#lazy_builder' => ['\Drupal\render_placeholder_message_test\RenderPlaceholderMessageTestController::setAndLogMessage', ['P2']],
      '#create_placeholder' => TRUE,
    ];

    /** @var \Drupal\Core\Render\RendererInterface $renderer */
    $renderer = $this->container->get('renderer');
    $renderer->executeInRenderContext(new RenderContext()function D) use (&$build$renderer) {
      return $renderer->render($build, FALSE);
    });

    $reordered = [];
    foreach ($placeholder_order as $placeholder) {
      $reordered[$placeholder] = $build['#attached']['placeholders'][$placeholder];
    }
    $build['#attached']['placeholders'] = $reordered;

    return $build;
  }

  
$view->storage->set('id', 'test_cache_header_storage');
    $view->display_handler->overrideOption('cache', [
      'type' => 'time',
      'options' => [
        'output_lifespan' => '3600',
      ],
    ]);

    $output = $view->buildRenderable();
    /** @var \Drupal\Core\Render\RendererInterface $renderer */
    $renderer = \Drupal::service('renderer');
    $renderer->executeInRenderContext(new RenderContext()function D) use (&$output$renderer) {
      return $renderer->render($output);
    });

    unset($view->pre_render_called);
    $view->destroy();

    $view->setDisplay();
    $output = $view->buildRenderable();
    $renderer->executeInRenderContext(new RenderContext()function D) use (&$output$renderer) {
      return $renderer->render($output);
    });

    

  public function testPlaceholderingDisabledForPostRequests($test_element$args) {
    $this->setUpUnusedCache();
    $this->setUpRequest('POST');

    $element = $test_element;

    // Render without replacing placeholders, to allow this test to see which     // #attached[placeholders] there are, if any.     $this->renderer->executeInRenderContext(new RenderContext()function D) use (&$element) {
      return $this->renderer->render($element);
    });
    // Only test cases where the placeholders have been specified manually are     // allowed to have placeholders. This means that of the different situations     // listed in providerPlaceholders(), only type B can have attached     // placeholders. Everything else, whether:     // 1. manual placeholdering     // 2. automatic placeholdering via already-present cacheability metadata     // 3. automatic placeholdering via bubbled cacheability metadata     // All three of those should NOT result in placeholders.     if (!isset($test_element['#attached']['placeholders'])) {
      
$variable = new TranslatableMarkup('test', []['langcode' => 'de']);
    $this->assertEquals('<span>test</span>', (string) $this->renderObjectWithTwig($variable));
  }

  /** * @return \Drupal\Component\Render\MarkupInterface * The rendered HTML. */
  protected function renderObjectWithTwig($variable) {
    /** @var \Drupal\Core\Render\RendererInterface $renderer */
    $renderer = \Drupal::service('renderer');
    $context = new RenderContext();
    return $renderer->executeInRenderContext($contextfunction D) use ($renderer$variable) {
      $elements = [
        '#type' => 'inline_template',
        '#template' => '{%- if variable is not empty -%}<span>{{ variable }}</span>{%- endif -%}',
        '#context' => ['variable' => $variable],
      ];
      return $renderer->render($elements);
    });
  }

}


  public function testViewsFormMainFormPreRender() {
    $element = [
      'output' => [
        '#plain_text' => '<!--will-be-escaped--><!--will-be-not-escaped-->',
      ],
      '#substitutions' => ['#value' => []],
    ];
    $element = \Drupal::service('renderer')->executeInRenderContext(new RenderContext()function D) use ($element) {
      return ViewsFormMainForm::preRenderViewsForm($element);
    });
    $this->setRawContent((string) $element['output']['#markup']);
    $this->assertEscaped('<em>escaped</em>');
    $this->assertRaw('<em>unescaped</em>');
  }

  /** * Test that hook_views_invalidate_cache() is called when a view is deleted. */
  public function testViewsInvalidateCacheOnDelete() {
    
    $view = Views::getView('test_views_handler_field_user_name');
    $view->initHandlers();
    $view->field['name']->options['link_to_user'] = TRUE;
    $view->field['name']->options['type'] = 'user_name';
    $view->field['name']->init($view$view->getDisplay('default'));
    $view->field['name']->options['id'] = 'name';
    $this->executeView($view);

    $anon_name = $this->config('user.settings')->get('anonymous');
    $view->result[0]->_entity->setUsername('');
    $view->result[0]->_entity->uid->value = 0;
    $render = $renderer->executeInRenderContext(new RenderContext()function D) use ($view) {
      return $view->field['name']->advancedRender($view->result[0]);
    });
    $this->assertStringContainsString($anon_name$render, 'For user 0 it should use the default anonymous name by default.');

    $render = $renderer->executeInRenderContext(new RenderContext()function D) use ($view$new_user) {
      return $view->field['name']->advancedRender($view->result[$new_user->id()]);
    });
    $this->assertStringContainsString($new_user->getDisplayName()$render, 'If link to user is checked the username should be part of the output.');
    $this->assertStringContainsString('user/' . $new_user->id()$render, 'If link to user is checked the link to the user should appear as well.');

    $view->field['name']->options['link_to_user'] = FALSE;
    
parent::setUp();
    $this->testPluginBase = new TestPluginBase();
  }

  /** * Tests that the token replacement in views works correctly. */
  public function testViewsTokenReplace() {
    $text = '{{ langcode__value }} means {{ langcode }}';
    $tokens = ['{{ langcode }}' => Markup::create('English'), '{{ langcode__value }}' => 'en'];

    $result = \Drupal::service('renderer')->executeInRenderContext(new RenderContext()function D) use ($text$tokens) {
      return $this->testPluginBase->viewsTokenReplace($text$tokens);
    });

    $this->assertSame('en means English', $result);
  }

  /** * Tests that the token replacement in views works correctly with dots. */
  public function testViewsTokenReplaceWithDots() {
    $text = '{{ argument.first }} comes before {{ argument.second }}';
    

        '#attached' => [
          'html_response_attachment_placeholders' => [
            'styles' => '<css-placeholder token="' . $placeholder_token . '">',
          ],
          'library' => [
            'media/oembed.frame',
          ],
        ],
        '#placeholder_token' => $placeholder_token,
      ];
      $context = new RenderContext();
      $content = $this->renderer->executeInRenderContext($contextfunction D) use ($element) {
        return $this->renderer->render($element);
      });
      $response
        ->setContent($content)
        ->setAttachments($element['#attached'])
        ->addCacheableDependency($resource)
        ->addCacheableDependency(CacheableMetadata::createFromRenderArray($element));

      // Modules and themes implementing hook_media_oembed_iframe_preprocess()       // can add additional #cache and #attachments to a render array. If this
'page' => $page,
    ];

    // The special page regions will appear directly in html.html.twig, not in     // page.html.twig, hence add them here, just before rendering html.html.twig.     $this->buildPageTopAndBottom($html);

    // Render, but don't replace placeholders yet, because that happens later in     // the render pipeline. To not replace placeholders yet, we use     // RendererInterface::render() instead of RendererInterface::renderRoot().     // @see \Drupal\Core\Render\HtmlResponseAttachmentsProcessor.     $render_context = new RenderContext();
    $this->renderer->executeInRenderContext($render_contextfunction D) use (&$html) {
      // RendererInterface::render() renders the $html render array and updates       // it in place. We don't care about the return value (which is just       // $html['#markup']), but about the resulting render array.       // @todo Simplify this when https://www.drupal.org/node/2495001 lands.       $this->renderer->render($html);
    });
    // RendererInterface::render() always causes bubbleable metadata to be     // stored in the render context, no need to check it conditionally.     $bubbleable_metadata = $render_context->pop();
    $bubbleable_metadata->applyTo($html);
    
public function execute() {
    parent::execute();

    return $this->view->render();
  }

  /** * {@inheritdoc} */
  public function render() {
    $build = [];
    $build['#markup'] = $this->renderer->executeInRenderContext(new RenderContext()function D) {
      return $this->view->style_plugin->render();
    });

    $this->view->element['#content_type'] = $this->getMimeType();
    $this->view->element['#cache_properties'][] = '#content_type';

    // Encode and wrap the output in a pre tag if this is for a live preview.     if (!empty($this->view->live_preview)) {
      $build['#prefix'] = '<pre>';
      $build['#plain_text'] = $build['#markup'];
      $build['#suffix'] = '</pre>';
      
$this->expectDeprecation('theme_render_and_autoescape() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. Theme engines must handle escaping by themselves. See https://www.drupal.org/node/3336253');
  }

  /** * @dataProvider providerTestThemeRenderAndAutoescape */
  public function testThemeRenderAndAutoescape($arg$expected) {
    if (is_array($arg) && isset($arg['#type']) && $arg['#type'] === 'link') {
      $arg = Link::createFromRoute($arg['#title']$arg['#url']);
    }

    $context = new RenderContext();
    // Use a closure here since we need to render with a render context.     $theme_render_and_autoescape = function D) use ($arg) {
      return theme_render_and_autoescape($arg);
    };
    /** @var \Drupal\Core\Render\RendererInterface $renderer */
    $renderer = \Drupal::service('renderer');
    $output = $renderer->executeInRenderContext($context$theme_render_and_autoescape);
    $this->assertEquals($expected$output);
    $this->assertIsString($output);
  }

  
class LinkGenerationTest extends KernelTestBase {

  protected static $modules = ['link_generation_test'];

  /** * Tests how hook_link_alter() can affect escaping of the link text. */
  public function testHookLinkAlter() {
    $url = Url::fromUri('http://example.com');
    $renderer = \Drupal::service('renderer');

    $link = $renderer->executeInRenderContext(new RenderContext()function D) use ($url) {
      return \Drupal::service('link_generator')->generate(['#markup' => '<em>link with markup</em>']$url);
    });
    $this->setRawContent($link);
    $this->assertInstanceOf(MarkupInterface::class$link);
    // Ensure the content of the link is not escaped.     $this->assertRaw('<em>link with markup</em>');

    // Test just adding text to an already safe string.     \Drupal::state()->set('link_generation_test_link_alter', TRUE);
    $link = $renderer->executeInRenderContext(new RenderContext()function D) use ($url) {
      return \Drupal::service('link_generator')->generate(['#markup' => '<em>link with markup</em>']$url);
    });

    $node1->setPublished();
    $node1->save();
    $node2 = Node::create([
      'type' => 'page',
      'title' => 'Another node',
      'uid' => 1,
    ]);
    $node2->setPublished();
    $node2->save();

    $this->container->get('renderer')->executeInRenderContext(new RenderContext()function D) use (&$node1, &$node2$action) {
      $action->execute([$node1$node2]);
    });

    $this->assertFalse($node1->isPublished());
    $this->assertTrue($node2->isPublished());
  }

}
Home | Imprint | This part of the site doesn't use cookies.