DefaultHtmlFragmentRenderer.php 4.58 KB
Newer Older
1 2 3 4 5 6 7 8 9
<?php

/**
 * @file
 * Contains \Drupal\Core\Page\DefaultHtmlFragmentRenderer
 */

namespace Drupal\Core\Page;

10
use Drupal\Core\Cache\CacheableInterface;
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
use Drupal\Core\Language\Language;
use Drupal\Core\Language\LanguageManager;

/**
 * Default page rendering engine.
 */
class DefaultHtmlFragmentRenderer implements HtmlFragmentRendererInterface {

  /**
   * The language manager.
   *
   * @var \Drupal\Core\Language\LanguageManager
   */
  protected $languageManager;

  /**
   * Constructs a new DefaultHtmlPageRenderer.
   *
   * @param \Drupal\Core\Language\LanguageManager $language_manager
   *   The language manager service.
   */
  public function __construct(LanguageManager $language_manager) {
    $this->languageManager = $language_manager;
  }

  /**
   * {@inheritdoc}
   */
39
  public function render(HtmlFragmentInterface $fragment, $status_code = 200) {
40 41 42 43 44 45 46
    // 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();

47 48 49 50
    if ($fragment instanceof CacheableInterface) {
      $page_content['main']['#cache']['tags'] = $fragment->getCacheTags();
    }

51 52 53 54 55
    // 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.
56
    $page = new HtmlPage('', array(), $fragment->getTitle());
57 58 59 60 61 62
    $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);

63 64 65 66 67 68 69 70 71
    if ($fragment instanceof CacheableInterface) {
      // Collect cache tags for all the content in all the regions on the page.
      $tags = $page_array['#cache']['tags'];
      // Enforce the generic "content" cache tag on all pages.
      // @todo Remove the "content" cache tag. @see https://drupal.org/node/2124957
      $tags['content'] = TRUE;
      $page->setCacheTags($tags);
    }

72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
    return $page;
  }

  /**
   * Enhances a page object based on a render array.
   *
   * @param \Drupal\Core\Page\HtmlPage $page
   *   The page object to enhance.
   * @param array $page_array
   *   The page array to extract onto the page object.
   *
   * @return \Drupal\Core\Page\HtmlPage
   *   The modified page object.
   */
  public function preparePage(HtmlPage $page, &$page_array) {
    $page_array['#page'] = $page;

    // HTML element attributes.
    $language_interface = $this->languageManager->getCurrentLanguage();
    $html_attributes = $page->getHtmlAttributes();
    $html_attributes['lang'] = $language_interface->id;
    $html_attributes['dir'] = $language_interface->direction ? 'rtl' : 'ltr';

95 96 97 98 99 100 101 102 103 104 105
    $this->setDefaultMetaTags($page);

    // @todo: collect feed links from #attached rather than a static once
    // http://drupal.org/node/2256365 is completed.
    foreach (drupal_get_feeds() as $feed) {
      // Force the URL to be absolute, for consistency with other <link> tags
      // output by Drupal.
      $link = new FeedLinkElement($feed['title'], url($feed['url'], array('absolute' => TRUE)));
      $page->addLinkElement($link);
    }

106 107 108
    return $page;
  }

109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
  /**
   * Apply the default meta tags to the page object.
   *
   * @param \Drupal\Core\Page\HtmlPage $page
   *   The html page.
   */
  protected function setDefaultMetaTags(HtmlPage $page) {
    // Add default elements. Make sure the Content-Type comes first because the
    // IE browser may be vulnerable to XSS via encoding attacks from any content
    // that comes before this META tag, such as a TITLE tag.
    $page->addMetaElement(new MetaElement(NULL, array(
      'name' => 'charset',
      'charset' => 'utf-8',
    )));
    // Show Drupal and the major version number in the META GENERATOR tag.
    // Get the major version.
    list($version) = explode('.', \Drupal::VERSION, 2);
    $page->addMetaElement(new MetaElement('Drupal ' . $version . ' (http://drupal.org)', array(
      'name' => 'Generator',
    )));

    // Display the html.html.twig's default mobile metatags for responsive design.
    $page->addMetaElement(new MetaElement(NULL, array('name' => 'MobileOptimized', 'content' => 'width')));
    $page->addMetaElement(new MetaElement(NULL, array('name' => 'HandheldFriendly', 'content' => 'true')));
    $page->addMetaElement(new MetaElement(NULL, array('name' => 'viewport', 'content' => 'width=device-width')));
  }

136
}