/** * Merges the values of another bubbleable metadata object with this one. * * @param \Drupal\Core\Render\BubbleableMetadata $other * The other bubbleable metadata object. * @return static * A new bubbleable metadata object, with the merged data. * * @todo Add unit test for this in * \Drupal\Tests\Core\Render\BubbleableMetadataTest when * drupal_merge_attached() no longer is a procedural function and remove * the '@codeCoverageIgnore' annotation. */ public function merge(BubbleableMetadata $other) { $result = new BubbleableMetadata(); $result->contexts = Cache::mergeContexts($this->contexts, $other->contexts); $result->tags = Cache::mergeTags($this->tags, $other->tags); $result->maxAge = Cache::mergeMaxAges($this->maxAge, $other->maxAge); $result->attached = Renderer::mergeAttachments($this->attached, $other->attached); $result->postRenderCache = NestedArray::mergeDeep($this->postRenderCache, $other->postRenderCache); return $result; }
/** * {@inheritdoc} */ public function renderBarePage(array $content, $title, $page_theme_property, array $page_additions = []) { $attributes = ['class' => [str_replace('_', '-', $page_theme_property)]]; $html = ['#type' => 'html', '#attributes' => $attributes, 'page' => ['#type' => 'page', '#theme' => $page_theme_property, '#title' => $title, 'content' => $content] + $page_additions]; // For backwards compatibility. // @todo In Drupal 9, add a $show_messages function parameter. if (!isset($page_additions['#show_messages']) || $page_additions['#show_messages'] === TRUE) { $html['page']['messages'] = ['#type' => 'status_messages']; } // We must first render the contents of the html.html.twig template, see // \Drupal\Core\Render\MainContent\HtmlRenderer::renderResponse() for more // information about this; the exact same pattern is used there and // explained in detail there. $this->renderer->render($html['page'], TRUE); // Add the bare minimum of attachments from the system module and the // current maintenance theme. system_page_attachments($html['page']); return $this->renderer->render($html); }
/** * {@inheritdoc} */ public function renderBarePage(array $content, $title, $page_theme_property, array $page_additions = []) { $attributes = ['class' => [str_replace('_', '-', $page_theme_property)]]; $html = ['#type' => 'html', '#attributes' => $attributes, 'page' => ['#type' => 'page', '#theme' => $page_theme_property, '#title' => $title, 'content' => $content] + $page_additions]; // For backwards compatibility. // @todo In Drupal 9, add a $show_messages function parameter. if (!isset($page_additions['#show_messages']) || $page_additions['#show_messages'] === TRUE) { $html['page']['highlighted'] = ['#type' => 'status_messages']; } // Add the bare minimum of attachments from the system module and the // current maintenance theme. system_page_attachments($html['page']); $this->renderer->renderRoot($html); $response = new HtmlResponse(); $response->setContent($html); // Process attachments, because this does not go via the regular render // pipeline, but will be sent directly. $response = $this->htmlResponseAttachmentsProcessor->processAttachments($response); return $response; }
/** * Add an AJAX command to the response. * * @param \Drupal\Core\Ajax\CommandInterface $command * An AJAX command object implementing CommandInterface. * @param boolean $prepend * A boolean which determines whether the new command should be executed * before previously added commands. Defaults to FALSE. * * @return AjaxResponse * The current AjaxResponse. */ public function addCommand(CommandInterface $command, $prepend = FALSE) { if ($prepend) { array_unshift($this->commands, $command->render()); } else { $this->commands[] = $command->render(); } if ($command instanceof CommandWithAttachedAssetsInterface) { $assets = $command->getAttachedAssets(); $attachments = ['library' => $assets->getLibraries(), 'drupalSettings' => $assets->getSettings()]; $attachments = Renderer::mergeAttachments($this->attachments, $attachments); $this->setAttachments($attachments); } return $this; }
/** * Renders form and status messages and returns an ajax response. * * Used for both submission buttons. * * @param array $form * The form. * * @return \Drupal\Core\Ajax\AjaxResponse * An ajax response to replace the form. */ protected function ajaxRenderFormAndMessages(array &$form) { $response = new AjaxResponse(); // Retrieve the element to be rendered. $status_messages = ['#type' => 'status_messages', '#weight' => -10]; // For some crazy reason, if we do this inline in the replace command, it // breaks ajax functionality entirely. $output = $this->renderer->renderRoot($form); $messages = $this->renderer->renderRoot($status_messages); $message_wrapper_id = '#' . self::MESSAGE_WRAPPER_ID; $response->setAttachments($form['#attached']); $response->addCommand(new ReplaceCommand(NULL, $output)); $response->addCommand(new HtmlCommand($message_wrapper_id, '')); $response->addCommand(new AppendCommand($message_wrapper_id, $messages)); return $response; }
/** * #post_render_cache callback; replaces the placeholder with comment links. * * Renders the links on a comment. * * @param array $element * The renderable array that contains the to be replaced placeholder. * @param array $context * An array with the following keys: * - comment_entity_id: a comment entity ID * - view_mode: the view mode in which the comment entity is being viewed * - langcode: in which language the comment entity is being viewed * - commented_entity_type: the entity type to which the comment is attached * - commented_entity_id: the entity ID to which the comment is attached * - in_preview: whether the comment is currently being previewed * * @return array * A renderable array representing the comment links. */ public function renderLinks(array $element, array $context) { $callback = 'comment.post_render_cache:renderLinks'; $placeholder = $this->generatePlaceholder($callback, $context); $links = array('#theme' => 'links__comment', '#pre_render' => array('drupal_pre_render_links'), '#attributes' => array('class' => array('links', 'inline'))); if (!$context['in_preview']) { /** @var \Drupal\comment\CommentInterface $entity */ $entity = $this->entityManager->getStorage('comment')->load($context['comment_entity_id']); $commented_entity = $entity->getCommentedEntity(); $links['comment'] = $this->buildLinks($entity, $commented_entity); // Allow other modules to alter the comment links. $hook_context = array('view_mode' => $context['view_mode'], 'langcode' => $context['langcode'], 'commented_entity' => $commented_entity); $this->moduleHandler->alter('comment_links', $links, $entity, $hook_context); } $markup = $this->renderer->render($links); $element['#markup'] = str_replace($placeholder, $markup, $element['#markup']); return $element; }
/** * Invokes the page attachment hooks. * * @param array &$page * A #type 'page' render array, for which the page attachment hooks will be * invoked and to which the results will be added. * * @throws \LogicException * * @internal * * @see hook_page_attachments() * @see hook_page_attachments_alter() */ public function invokePageAttachmentHooks(array &$page) { // Modules can add attachments. $attachments = []; foreach ($this->moduleHandler->getImplementations('page_attachments') as $module) { $function = $module . '_page_attachments'; $function($attachments); } if (array_diff(array_keys($attachments), ['#attached', '#post_render_cache']) !== []) { throw new \LogicException('Only #attached and #post_render_cache may be set in hook_page_attachments().'); } // Modules and themes can alter page attachments. $this->moduleHandler->alter('page_attachments', $attachments); \Drupal::theme()->alter('page_attachments', $attachments); if (array_diff(array_keys($attachments), ['#attached', '#post_render_cache']) !== []) { throw new \LogicException('Only #attached and #post_render_cache may be set in hook_page_attachments_alter().'); } // Merge the attachments onto the $page render array. $page = Renderer::mergeBubbleableMetadata($page, $attachments); }
/** * {@inheritdoc} */ public function build() { $form = array(); /** @var \Drupal\contact\Entity\ContactForm $contact_form */ $contact_form = $this->getContactForm(); if ($contact_form) { $contact_message = $this->createContactMessage(); // The personal contact form has a fixed recipient: the user who's // contact page we visit. We use the 'user' property from the URL // to determine this user. For example: user/{user}. if ($contact_message->isPersonal()) { $user = \Drupal::routeMatch()->getParameter('user'); $contact_message->set('recipient', $user); } $form = $this->entityFormBuilder->getForm($contact_message); $form['#cache']['contexts'][] = 'user.permissions'; $this->renderer->addCacheableDependency($form, $contact_form); } return $form; }