Issue by mortendk, babruix, dasjo, joelpittet, visabhishek, cwells, jenlampton, Dragan Eror, nikhiltri, minneapolisdan, Manuel Garcia, sarahjean, acouch | scor: Node.html.twig template.

8.0.x
Alex Pott 2014-06-07 13:38:36 -05:00
parent 2f1e909a45
commit b001084e91
12 changed files with 129 additions and 114 deletions

View File

@ -182,25 +182,25 @@ class LocaleContentTest extends WebTestBase {
// 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.');
}

View File

@ -579,7 +579,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());
}
}
@ -642,9 +642,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'];
@ -660,23 +660,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.
@ -684,23 +678,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';
}
/**
@ -1213,9 +1206,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
@ -1550,7 +1543,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();

View File

@ -133,9 +133,9 @@ class NodeFieldMultilingualTestCase extends WebTestBase {
// 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.');
}

View File

@ -45,7 +45,7 @@ class NodePostSettingsTest extends NodeTestBase {
// 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 @@ class NodePostSettingsTest extends NodeTestBase {
$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.');
}
}

View File

@ -42,7 +42,8 @@ class NodeTitleTest extends NodeTestBase {
*/
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 @@ class NodeTitleTest extends NodeTestBase {
$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');

View File

@ -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,31 +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 information as loaded from the 'compact'
* view mode for the user entity.
* - 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
@ -76,27 +77,34 @@
* @ingroup themeable
*/
#}
<article id="node-{{ node.id }}" class="{{ attributes.class }} clearfix"{{ attributes|without('id', 'class') }}>
<article{{ attributes }}>
{{ title_prefix }}
{% if not page %}
<h2{{ title_attributes }}>
<a href="{{ node_url }}" rel="bookmark">{{ label }}</a>
<a href="{{ url }}" rel="bookmark">{{ label }}</a>
</h2>
{% endif %}
{{ title_suffix }}
{% if display_submitted %}
<footer>
{{ user_picture }}
<p class="submitted">{{ submitted }}</p>
<footer class="node__meta">
{{ author_picture }}
<div class="node__submitted {{ author_attributes.class }}"{{ author_attributes|without('class') }}>
{% trans %}Submitted by {{ author_name|passthrough }} on {{ date }}{% endtrans %}
{{ metadata }}
</div>
</footer>
{% endif %}
<div{{ content_attributes }}>
<div class="node__content {{ content_attributes.class }}"{{ content_attributes|without('class') }}>
{{ content|without('links') }}
</div>
{{ content.links }}
{% if content.links %}
<div class="node__links">
{{ content.links }}
</div>
{% endif %}
</article>

View File

@ -279,7 +279,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
@ -297,20 +297,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'] = '<span ' . new Attribute($author_attributes) . '>' . $variables['submitted'] . '</span>';
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.
@ -323,7 +322,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',

View File

@ -6,10 +6,10 @@
/**
* Publishing status.
*/
.unpublished {
.node--unpublished {
background-color: #fff4f4;
}
.preview {
.node--preview {
background-color: #ffffea;
}

View File

@ -1283,7 +1283,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,

View File

@ -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,
@ -665,7 +665,8 @@ h1.site-name {
/* ----------------- Content ------------------ */
.content {
.content,
.node__content {
margin-top: 10px;
}
h1#page-title {
@ -677,44 +678,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;
@ -735,8 +736,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 {
@ -753,10 +754,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;
@ -769,10 +770,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;

View File

@ -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,31 +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 information as loaded from the 'compact'
* view mode for the user entity.
* - 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
@ -70,33 +71,38 @@
* @see template_preprocess_node()
*/
#}
<article id="node-{{ node.id }}" class="{{ attributes.class }} clearfix" role="article"{{ attributes|without('id', 'class', 'role') }}>
<article class="{{ attributes.class }} clearfix"{{ attributes|without('class') }}>
<header>
{{ title_prefix }}
{% if not page %}
<h2{{ title_attributes }}>
<a href="{{ node_url }}">{{ label }}</a>
<h2 class="node__title {{ title_attributes.class }}"{{ title_attributes|without('class') }}>
<a href="{{ url }}" rel="bookmark">{{ label }}</a>
</h2>
{% endif %}
{{ title_suffix }}
{% if display_submitted %}
<div class="meta submitted">
{{ user_picture }}
{{ submitted }}
<div class="node__meta">
{{ author_picture }}
<span{{ author_attributes }}>
{% trans %}Submitted by {{ author_name|passthrough }} on {{ date }}{% endtrans %}
</span>
{{ metadata }}
</div>
{% endif %}
</header>
<div class="content clearfix"{{ content_attributes }}>
{{ content|without('links') }}
<div class="node__content clearfix {{ content_attributes.class }}"{{ content_attributes|without('class') }}>
{{ content|without('comment', 'links') }}
</div>
{% if content.links %}
<footer class="link-wrapper">
<div class="node__links">
{{ content.links }}
</footer>
</div>
{% endif %}
{{ content.comment }}
</article>

View File

@ -518,6 +518,9 @@ ul.admin-list {
div.submitted {
color: #898989;
}
.node__submitted {
margin: 1em 0;
}
/**
* Pagination.