diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleContentTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleContentTest.php index 093da50..7c80148 100644 --- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleContentTest.php +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleContentTest.php @@ -182,25 +182,25 @@ function testContentTypeDirLang() { // Check if English node does not have lang tag. $this->drupalGet('node/' . $nodes['en']->id()); - $pattern = '|id="node-' . $nodes['en']->id() . '"[^<>]*lang="en"|'; + $pattern = '|class="[^"]*node[^"]*"[^<>]*lang="en"|'; $this->assertNoPattern($pattern, 'The lang tag has not been assigned to the English node.'); // Check if English node does not have dir tag. - $pattern = '|id="node-' . $nodes['en']->id() . '"[^<>]*dir="ltr"|'; + $pattern = '|class="[^"]*node[^"]*"[^<>]*dir="ltr"|'; $this->assertNoPattern($pattern, 'The dir tag has not been assigned to the English node.'); // Check if Arabic node has lang="ar" & dir="rtl" tags. $this->drupalGet('node/' . $nodes['ar']->id()); - $pattern = '|id="node-' . $nodes['ar']->id() . '"[^<>]*lang="ar" dir="rtl"|'; + $pattern = '|class="[^"]*node[^"]*"[^<>]*lang="ar" dir="rtl"|'; $this->assertPattern($pattern, 'The lang and dir tags have been assigned correctly to the Arabic node.'); // Check if Spanish node has lang="es" tag. $this->drupalGet('node/' . $nodes['es']->id()); - $pattern = '|id="node-' . $nodes['es']->id() . '"[^<>]*lang="es"|'; + $pattern = '|class="[^"]*node[^"]*"[^<>]*lang="es"|'; $this->assertPattern($pattern, 'The lang tag has been assigned correctly to the Spanish node.'); // Check if Spanish node does not have dir="ltr" tag. - $pattern = '|id="node-' . $nodes['es']->id() . '"[^<>]*lang="es" dir="ltr"|'; + $pattern = '|class="[^"]*node[^"]*"[^<>]*lang="es" dir="ltr"|'; $this->assertNoPattern($pattern, 'The dir tag has not been assigned to the Spanish node.'); } diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php index 67b34e7..50c786c 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php @@ -132,9 +132,9 @@ function testMultilingualDisplaySettings() { // Check if node body is showed. $this->drupalGet('node/' . $node->id()); - $body = $this->xpath('//article[@id=:id]//div[@class=:class]/descendant::p', array( - ':id' => 'node-' . $node->id(), - ':class' => 'content', + $body = $this->xpath('//article[contains(concat(" ", normalize-space(@class), " "), :node-class)]//div[contains(concat(" ", normalize-space(@class), " "), :content-class)]/descendant::p', array( + ':node-class' => ' node ', + ':content-class' => 'node__content', )); $this->assertEqual(current($body), $node->body->value, 'Node body found.'); } diff --git a/core/modules/node/lib/Drupal/node/Tests/NodePostSettingsTest.php b/core/modules/node/lib/Drupal/node/Tests/NodePostSettingsTest.php index a7478a8..7cfaa7e 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodePostSettingsTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodePostSettingsTest.php @@ -45,7 +45,7 @@ function testPagePostInfo() { // Check that the post information is displayed. $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); - $elements = $this->xpath('//*[contains(@class,:class)]', array(':class' => 'submitted')); + $elements = $this->xpath('//div[contains(@class, :class)]', array(':class' => 'node__submitted')); $this->assertEqual(count($elements), 1, 'Post information is displayed.'); $node->delete(); @@ -61,7 +61,7 @@ function testPagePostInfo() { $this->drupalPostForm('node/add/page', $edit, t('Save')); // Check that the post information is displayed. - $elements = $this->xpath('//*[contains(@class,:class)]', array(':class' => 'submitted')); + $elements = $this->xpath('//div[contains(@class, :class)]', array(':class' => 'node__submitted')); $this->assertEqual(count($elements), 0, 'Post information is not displayed.'); } } diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTitleTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTitleTest.php index 9b503ff..784125c 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeTitleTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeTitleTest.php @@ -42,7 +42,8 @@ function setUp() { */ function testNodeTitle() { // Create "Basic page" content with title. - // Add the node to the frontpage so we can test if teaser links are clickable. + // Add the node to the frontpage so we can test if teaser links are + // clickable. $settings = array( 'title' => $this->randomName(8), 'promote' => 1, @@ -60,7 +61,7 @@ function testNodeTitle() { $this->assertEqual(current($this->xpath($xpath)), $node->label(), 'Node breadcrumb is equal to node title.', 'Node'); // Test node title in comment preview. - $this->assertEqual(current($this->xpath('//article[@id=:id]/h2/a/span', array(':id' => 'node-' . $node->id()))), $node->label(), 'Node preview title is equal to node title.', 'Node'); + $this->assertEqual(current($this->xpath('//article[contains(concat(" ", normalize-space(@class), " "), :node-class)]/h2/a/span', array(':node-class' => ' node--type-' . $node->bundle() . ' '))), $node->label(), 'Node preview title is equal to node title.', 'Node'); // Test node title is clickable on teaser list (/node). $this->drupalGet('node'); diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 4092e76..1a73492 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -586,7 +586,7 @@ function node_is_page(NodeInterface $node) { function node_preprocess_html(&$variables) { // If on an individual node page, add the node type to body classes. if (($node = \Drupal::request()->attributes->get('node')) && $node instanceof NodeInterface) { - $variables['attributes']['class'][] = drupal_html_class('node-type-' . $node->getType()); + $variables['attributes']['class'][] = drupal_html_class('node--type-' . $node->getType()); } } @@ -645,9 +645,9 @@ function template_preprocess_node(&$variables) { '#account' => $node->getOwner(), '#link_options' => array('attributes' => array('rel' => 'author')), ); - $variables['name'] = drupal_render($username); + $variables['author_name'] = drupal_render($username); - $variables['node_url'] = $node->url('canonical', array( + $variables['url'] = $node->url('canonical', array( 'language' => $node->language(), )); $variables['label'] = $variables['elements']['title']; @@ -663,23 +663,17 @@ function template_preprocess_node(&$variables) { // Display post information only on certain node types. // Avoid loading the entire node type config entity here that may not exist. $node_type_config = \Drupal::config('node.type.' . $node->bundle()); + // Used by RDF to add attributes around the author and date submitted. + $variables['author_attributes'] = new Attribute(); // Display submitted by default. $variables['display_submitted'] = $node_type_config->isNew() || $node_type_config->get('settings.node.submitted'); if ($variables['display_submitted']) { - $variables['submitted'] = t('Submitted by !username on !datetime', array('!username' => $variables['name'], '!datetime' => $variables['date'])); if (theme_get_setting('features.node_user_picture')) { // To change user picture settings (e.g. image style), edit the 'compact' // view mode on the User entity. Note that the 'compact' view mode might // not be configured, so remember to always check the theme setting first. - $variables['user_picture'] = user_view($node->getOwner(), 'compact'); + $variables['author_picture'] = user_view($node->getOwner(), 'compact'); } - else { - $variables['user_picture'] = array(); - } - } - else { - $variables['submitted'] = ''; - $variables['user_picture'] = ''; } // Add article ARIA role. @@ -687,23 +681,22 @@ function template_preprocess_node(&$variables) { // Gather node classes. $variables['attributes']['class'][] = 'node'; - $variables['attributes']['class'][] = drupal_html_class('node-' . $node->bundle()); + $variables['attributes']['class'][] = drupal_html_class('node--type-' . $node->bundle()); if ($node->isPromoted()) { - $variables['attributes']['class'][] = 'promoted'; + $variables['attributes']['class'][] = 'node--promoted'; } if ($node->isSticky()) { - $variables['attributes']['class'][] = 'sticky'; + $variables['attributes']['class'][] = 'node--sticky'; } if (!$node->isPublished()) { - $variables['attributes']['class'][] = 'unpublished'; + $variables['attributes']['class'][] = 'node--unpublished'; } if ($variables['view_mode']) { - $variables['attributes']['class'][] = drupal_html_class('view-mode-' . $variables['view_mode']); + $variables['attributes']['class'][] = drupal_html_class('node--view-mode-' . $variables['view_mode']); } if (isset($variables['preview'])) { - $variables['attributes']['class'][] = 'preview'; + $variables['attributes']['class'][] = 'node--preview'; } - $variables['content_attributes']['class'][] = 'content'; } /** @@ -1252,9 +1245,9 @@ function node_form_system_themes_admin_form_submit($form, &$form_state) { * * Next, all implementations of hook_node_access() will be called. Each * implementation may explicitly allow, explicitly deny, or ignore the access - * request. If at least one module says to deny the request, it will be rejected. - * If no modules deny the request and at least one says to allow it, the request - * will be permitted. + * request. If at least one module says to deny the request, it will be + * rejected. If no modules deny the request and at least one says to allow it, + * the request will be permitted. * * If all modules ignore the access request, then the node_access table is used * to determine access. All node access modules are queried using @@ -1589,7 +1582,8 @@ function node_access_rebuild($batch_mode = FALSE) { // Try to allocate enough time to rebuild node grants drupal_set_time_limit(240); - // Rebuild newest nodes first so that recent content becomes available quickly. + // Rebuild newest nodes first so that recent content becomes available + // quickly. $entity_query = \Drupal::entityQuery('node'); $entity_query->sort('nid', 'DESC'); $nids = $entity_query->execute(); diff --git a/core/modules/node/templates/node.html.twig b/core/modules/node/templates/node.html.twig index ae1162e..c80eecb 100644 --- a/core/modules/node/templates/node.html.twig +++ b/core/modules/node/templates/node.html.twig @@ -5,11 +5,11 @@ * * Available variables: * - node: Full node entity. - * - id: The node ID + * - id: The node ID. * - bundle: The type of the node, for example, "page" or "article". * - authorid: The user ID of the node author. - * - createdtime: Formatted creation date. Preprocess functions can reformat it by - * calling format_date() with the desired parameters on + * - createdtime: Formatted creation date. Preprocess functions can + * reformat it by calling format_date() with the desired parameters on * $variables['node']->getCreatedTime(). * - promoted: Whether the node is promoted to the front page. * - sticky: Whether the node is 'sticky'. Sticky nodes are ordered above @@ -20,30 +20,32 @@ * or print a subset such as {{ content.field_example }}. Use * {{ content|without('field_example') %} to temporarily suppress the printing * of a given child element. - * - user_picture: The node author's picture from user-picture.html.twig. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. * - date: Formatted creation date. Preprocess functions can reformat it by * calling format_date() with the desired parameters on * $variables['created']. - * - name: Themed username of node author output from theme_username(). - * - node_url: Direct URL of the current node. + * - author_name: Themed username of node author output from theme_username(). + * - url: Direct URL of the current node. * - display_submitted: Whether submission information should be displayed. - * - submitted: Submission information created from name and date during - * template_preprocess_node(). * - attributes: HTML attributes for the containing element. * The attributes.class element may contain one or more of the following * classes: * - node: The current template type (also known as a "theming hook"). - * - node-[type]: The current node type. For example, if the node is a - * "Article" it would result in "node-article". Note that the machine + * - node--[type]: The current node type. For example, if the node is a + * "Article" it would result in "node--article". Note that the machine * name will often be in a short form of the human readable label. - * - view-mode-[view_mode]: The View Mode of the node; for example, a teaser - * would result in: "view-mode-teaser", and full: "view-mode-full". - * - preview: Whether a node is in preview mode. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * - node--preview: Whether a node is in preview mode. * The following are controlled through the node publishing options. - * - promoted: Appears on nodes promoted to the front page. - * - sticky: Appears on nodes ordered above other non-sticky nodes in teaser - * listings. - * - unpublished: Appears on unpublished nodes visible only to site admins. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. * - title_prefix: Additional output populated by modules, intended to be * displayed in front of the main title tag that appears in the template. * - title_suffix: Additional output populated by modules, intended to be @@ -75,27 +77,34 @@ * @ingroup themeable */ #} -
+ {{ title_prefix }} {% if not page %} - {{ label }} + {{ label }} {% endif %} {{ title_suffix }} {% if display_submitted %} -
diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module index bf8c60e..e187e9e 100644 --- a/core/modules/rdf/rdf.module +++ b/core/modules/rdf/rdf.module @@ -278,7 +278,7 @@ function rdf_preprocess_node(&$variables) { $bundle = $variables['node']->bundle(); $mapping = rdf_get_mapping('node', $bundle); $bundle_mapping = $mapping->getPreparedBundleMapping('node', $bundle); - $variables['attributes']['about'] = empty($variables['node_url']) ? NULL: $variables['node_url']; + $variables['attributes']['about'] = empty($variables['url']) ? NULL: $variables['url']; $variables['attributes']['typeof'] = empty($bundle_mapping['types']) ? NULL : $bundle_mapping['types']; // Adds RDFa markup for the node title as metadata because wrapping the title @@ -296,20 +296,19 @@ function rdf_preprocess_node(&$variables) { // Adds RDFa markup for the relation between the node and its author. $author_mapping = $mapping->getPreparedFieldMapping('uid'); - if (!empty($author_mapping['properties']) && $variables['submitted']) { - $author_attributes = array('rel' => $author_mapping['properties']); - $variables['submitted'] = '' . $variables['submitted'] . ''; + if (!empty($author_mapping['properties']) && $variables['display_submitted']) { + $variables['author_attributes']['rel'] = $author_mapping['properties']; } // Adds RDFa markup for the date. $created_mapping = $mapping->getPreparedFieldMapping('created'); - if (!empty($created_mapping) && $variables['submitted']) { + if (!empty($created_mapping) && $variables['display_submitted']) { $date_attributes = rdf_rdfa_attributes($created_mapping, $variables['node']->getCreatedTime()); $rdf_metadata = array( '#theme' => 'rdf_metadata', '#metadata' => array($date_attributes), ); - $variables['submitted'] .= drupal_render($rdf_metadata); + $variables['metadata'] = drupal_render($rdf_metadata); } // Adds RDFa markup annotating the number of comments a node has. @@ -322,7 +321,8 @@ function rdf_preprocess_node(&$variables) { $count = 0; foreach ($valid_fields as $field_name) { $count += $variables['node']->get($field_name)->comment_count; - // Adds RDFa markup for the comment count near the node title as metadata + // Adds RDFa markup for the comment count near the node title as + // metadata. $comment_count_attributes = rdf_rdfa_attributes($comment_count_mapping, $variables['node']->get($field_name)->comment_count); $variables['title_suffix']['rdf_meta_comment_count'] = array( '#theme' => 'rdf_metadata', diff --git a/core/modules/system/css/system.theme.css b/core/modules/system/css/system.theme.css index b8678a3..e46e428 100644 --- a/core/modules/system/css/system.theme.css +++ b/core/modules/system/css/system.theme.css @@ -6,10 +6,10 @@ /** * Publishing status. */ -.unpublished { +.node--unpublished { background-color: #fff4f4; } -.preview { +.node--preview { background-color: #ffffea; } diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php index 4447052..6c33ea0 100644 --- a/core/modules/system/system.api.php +++ b/core/modules/system/system.api.php @@ -1323,7 +1323,7 @@ function hook_mail($key, &$message, $params) { $node = $params['node']; $variables += array( '%uid' => $node->getOwnerId(), - '%node_url' => url('node/' . $node->id(), array('absolute' => TRUE)), + '%url' => url('node/' . $node->id(), array('absolute' => TRUE)), '%node_type' => node_get_type_label($node), '%title' => $node->getTitle(), '%teaser' => $node->teaser, diff --git a/core/themes/bartik/css/style.css b/core/themes/bartik/css/style.css index 80ddc82..07986e2 100644 --- a/core/themes/bartik/css/style.css +++ b/core/themes/bartik/css/style.css @@ -132,7 +132,7 @@ ul.primary, .item-list .pager, div.field-type-taxonomy-term-reference, div.messages, -div.meta, +.node__meta, p.comment-time, table, .breadcrumb, @@ -667,7 +667,8 @@ h1.site-name { /* ----------------- Content ------------------ */ -.content { +.content, +.node__content { margin-top: 10px; } h1#page-title { @@ -679,44 +680,44 @@ h1#page-title { font-size: 1.429em; line-height: 1.4; } -.node .content { +.node__content { font-size: 1.071em; } -.view-mode-teaser .content { +.node--view-mode-teaser .node__content { font-size: 1em; } -.view-mode-teaser h2 { +.node--view-mode-teaser h2 { margin-top: 0; padding-top: 0.5em; } -.view-mode-teaser h2 a { +.node--view-mode-teaser h2 a { color: #181818; } -.view-mode-teaser { +.node--view-mode-teaser { border-bottom: 1px solid #d3d7d9; margin-bottom: 30px; padding-bottom: 15px; } -.view-mode-teaser.sticky { +.node--view-mode-teaser.node--sticky { background: #f9f9f9; background: rgba(0, 0, 0, 0.024); border: 1px solid #d3d7d9; padding: 0 15px 15px; } -.view-mode-teaser .content { +.node--view-mode-teaser .node__content { clear: none; line-height: 1.6; } -.meta { +.node__meta { font-size: 0.857em; color: #68696b; margin-bottom: -5px; } -.submitted .field-name-field-user-picture img { +.node__meta .field-name-field-user-picture img { float: left; /* LTR */ margin: 1px 20px 0 0; /* LTR */ } -[dir="rtl"] .submitted .field-name-field-user-picture img { +[dir="rtl"] .node__meta .field-name-field-user-picture img { float: right; margin-left: 20px; margin-right: 0; @@ -737,8 +738,8 @@ h1#page-title { .field-type-taxonomy-term-reference ul.links { font-size: 0.8em; } -.view-mode-teaser .field-type-taxonomy-term-reference .field-label, -.view-mode-teaser .field-type-taxonomy-term-reference ul.links { +.node--view-mode-teaser .field-type-taxonomy-term-reference .field-label, +.node--view-mode-teaser .field-type-taxonomy-term-reference ul.links { font-size: 0.821em; } .field-type-taxonomy-term-reference ul.links { @@ -755,10 +756,10 @@ h1#page-title { padding: 0 0 0 1em; float: right; } -.link-wrapper { +.node__links { text-align: right; } -[dir="rtl"] .link-wrapper { +[dir="rtl"] .node__links { text-align: left; margin-right: 236px; margin-left: 0; @@ -771,10 +772,12 @@ ul.links { color: #68696b; font-size: 0.821em; } +.node--unpublished, .unpublished { margin: -20px -15px 0; padding: 20px 15px 0; } +.node--unpublished .comment-text .comment-arrow, .unpublished .comment-text .comment-arrow { border-left: 1px solid #fff4f4; border-right: 1px solid #fff4f4; diff --git a/core/themes/bartik/templates/node.html.twig b/core/themes/bartik/templates/node.html.twig index 2848899..d45b0f0 100644 --- a/core/themes/bartik/templates/node.html.twig +++ b/core/themes/bartik/templates/node.html.twig @@ -5,11 +5,11 @@ * * Available variables: * - node: Full node entity. - * - id: The node ID + * - id: The node ID. * - bundle: The type of the node, for example, "page" or "article". * - authorid: The user ID of the node author. - * - createdtime: Formatted creation date. Preprocess functions can reformat - it by calling format_date() with the desired parameters on + * - createdtime: Formatted creation date. Preprocess functions can + * reformat it by calling format_date() with the desired parameters on * $variables['node']->getCreatedTime(). * - promoted: Whether the node is promoted to the front page. * - sticky: Whether the node is 'sticky'. Sticky nodes are ordered above @@ -20,30 +20,32 @@ * or print a subset such as {{ content.field_example }}. Use * {{ content|without('field_example') }} to exclude the printing of a * given child element. - * - user_picture: The node author's picture from user-picture.html.twig. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. * - date: Formatted creation date. Preprocess functions can reformat it by * calling format_date() with the desired parameters on * $variables['created']. - * - name: Themed username of node author output from theme_username(). - * - node_url: Direct URL of the current node. + * - author_name: Themed username of node author output from theme_username(). + * - url: Direct URL of the current node. * - display_submitted: Whether submission information should be displayed. - * - submitted: Submission information created from name and date during - * template_preprocess_node(). * - attributes: HTML attributes for the containing element. * The attributes.class element may contain one or more of the following * classes: * - node: The current template type (also known as a "theming hook"). - * - node-[type]: The current node type. For example, if the node is a - * "Article" it would result in "node-article". Note that the machine + * - node--[type]: The current node type. For example, if the node is a + * "Article" it would result in "node--article". Note that the machine * name will often be in a short form of the human readable label. - * - view-mode-[view_mode]: The View Mode of the node; for example, a teaser - * would result in: "view-mode-teaser", and full: "view-mode-full". - * - preview: Whether a node is in preview mode. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", + * and full: "node--view-mode-full". + * - is-preview: Whether a node is in preview mode. * The following are controlled through the node publishing options. - * - promoted: Appears on nodes promoted to the front page. - * - sticky: Appears on nodes ordered above other non-sticky nodes in teaser - * listings. - * - unpublished: Appears on unpublished nodes visible only to site admins. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. * - title_prefix: Additional output populated by modules, intended to be * displayed in front of the main title tag that appears in the template. * - title_suffix: Additional output populated by modules, intended to be @@ -69,33 +71,38 @@ * @see template_preprocess_node() */ #} -
+
{{ title_prefix }} {% if not page %} - - {{ label }} +

+ {{ label }}

{% endif %} {{ title_suffix }} {% if display_submitted %} -
-
- {{ content|without('links') }} +
+ {{ content|without('comment', 'links') }}
{% if content.links %} - +
{% endif %} + {{ content.comment }} +
diff --git a/core/themes/seven/style.css b/core/themes/seven/style.css index 33b3eee..c5db28e 100644 --- a/core/themes/seven/style.css +++ b/core/themes/seven/style.css @@ -518,6 +518,9 @@ ul.admin-list { div.submitted { color: #898989; } +.node__submitted { + margin: 1em 0; +} /** * Pagination.