/** * Asserts whether expected exceptions are thrown for invalid hook implementations. * * @param string $module * The module whose invalid logic in its hooks to enable. * @param string $hook * The page render hook to assert expected exceptions for. */ function assertPageRenderHookExceptions($module, $hook) { // Assert a valid hook implementation doesn't trigger an exception. $page = []; drupal_prepare_page($page); // Assert an invalid hook implementation doesn't trigger an exception. \Drupal::state()->set($module . '.' . $hook . '.descendant_attached', TRUE); $assertion = $hook . '() implementation that sets #attached on a descendant triggers an exception'; $page = []; try { drupal_prepare_page($page); $this->error($assertion); } catch (\LogicException $e) { $this->pass($assertion); $this->assertEqual($e->getMessage(), 'Only #attached and #post_render_cache may be set in ' . $hook . '().'); } \Drupal::state()->set('bc_test.' . $hook . '.descendant_attached', FALSE); // Assert an invalid hook implementation doesn't trigger an exception. \Drupal::state()->set('bc_test.' . $hook . '.render_array', TRUE); $assertion = $hook . '() implementation that sets a child render array triggers an exception'; $page = []; try { drupal_prepare_page($page); $this->error($assertion); } catch (\LogicException $e) { $this->pass($assertion); $this->assertEqual($e->getMessage(), 'Only #attached and #post_render_cache may be set in ' . $hook . '().'); } \Drupal::state()->set($module . '.' . $hook . '.render_array', FALSE); }
/** * {@inheritdoc} */ public function render(HtmlFragmentInterface $fragment, $status_code = 200) { // Converts the given HTML fragment which represents the main content region // of the page into a render array. $page_content['main'] = array('#markup' => $fragment->getContent()); $page_content['#title'] = $fragment->getTitle(); if ($fragment instanceof CacheableInterface) { $page_content['main']['#cache']['tags'] = $fragment->getCacheTags(); } // Build the full page array by calling drupal_prepare_page(), which invokes // hook_page_build(). This adds the other regions to the page. $page_array = drupal_prepare_page($page_content); // Build the HtmlPage object. $page = new HtmlPage('', array(), $fragment->getTitle()); $page = $this->preparePage($page, $page_array); $page->setBodyTop(drupal_render($page_array['page_top'])); $page->setBodyBottom(drupal_render($page_array['page_bottom'])); $page->setContent(drupal_render($page_array)); $page->setStatusCode($status_code); if ($fragment instanceof CacheableInterface) { // Collect cache tags for all the content in all the regions on the page. $tags = $page_array['#cache']['tags']; // Tag every render cache item with the "rendered" cache tag. This allows us // to invalidate the entire render cache, regardless of the cache bin. $tags['rendered'] = TRUE; $page->setCacheTags($tags); } return $page; }
/** * {@inheritdoc} */ public function render(HtmlFragmentInterface $fragment, $status_code = 200) { // Converts the given HTML fragment which represents the main content region // of the page into a render array. $page_content['main'] = array('#markup' => $fragment->getContent()); $page_content['#title'] = $fragment->getTitle(); if ($fragment instanceof CacheableInterface) { $page_content['main']['#cache']['tags'] = $fragment->getCacheTags(); } // Build the full page array by calling drupal_prepare_page(), which invokes // hook_page_build(). This adds the other regions to the page. $page_array = drupal_prepare_page($page_content); // Build the HtmlPage object. $page = new HtmlPage('', array(), $fragment->getTitle()); $page = $this->preparePage($page, $page_array); $page->setBodyTop(drupal_render($page_array['page_top'])); $page->setBodyBottom(drupal_render($page_array['page_bottom'])); $page->setContent(drupal_render($page_array)); $page->setStatusCode($status_code); drupal_process_attached($page_array); if (isset($page_array['page_top'])) { drupal_process_attached($page_array['page_top']); } if (isset($page_array['page_bottom'])) { drupal_process_attached($page_array['page_bottom']); } if ($fragment instanceof CacheableInterface) { // Persist cache tags associated with this page. Also associate the // "rendered" cache tag. This allows us to invalidate the entire render // cache, regardless of the cache bin. $cache_tags = $page_array['#cache']['tags']; $cache_tags[] = 'rendered'; // Only keep unique cache tags. We need to prevent duplicates here already // rather than only in the cache layer, because they are also used by // reverse proxies (like Varnish), not only by Drupal's page cache. $page->setCacheTags(array_unique($cache_tags)); } return $page; }
/** * {@inheritdoc} */ public function render(array $output, $status_code = 200) { if (!isset($output['#title'])) { $output['#title'] = $this->titleResolver->getTitle(\Drupal::request(), \Drupal::routeMatch()->getRouteObject()); } $page = new HtmlPage('', isset($output['#cache']) ? $output['#cache'] : array(), $output['#title']); $page_array = drupal_prepare_page($output); $page = $this->fragmentRenderer->preparePage($page, $page_array); $page->setBodyTop(drupal_render($page_array['page_top'])); $page->setBodyBottom(drupal_render($page_array['page_bottom'])); $page->setContent(drupal_render($page_array)); $page->setStatusCode($status_code); return $page; }