diff --git a/core/modules/email/lib/Drupal/email/Plugin/field/formatter/MailToFormatter.php b/core/modules/email/lib/Drupal/email/Plugin/field/formatter/MailToFormatter.php index 25e2945..1d345cf 100644 --- a/core/modules/email/lib/Drupal/email/Plugin/field/formatter/MailToFormatter.php +++ b/core/modules/email/lib/Drupal/email/Plugin/field/formatter/MailToFormatter.php @@ -38,6 +38,9 @@ public function viewElements(EntityInterface $entity, $langcode, FieldInterface '#title' => $item->value, '#href' => 'mailto:' . $item->value, ); + if (!empty($item->html_data_attributes)) { + $elements[$delta]['#attributes'] = $item->html_data_attributes; + } } return $elements; diff --git a/core/modules/file/lib/Drupal/file/Plugin/field/formatter/FileFormatterBase.php b/core/modules/file/lib/Drupal/file/Plugin/field/formatter/FileFormatterBase.php index 2ef9df2..76e15d7 100644 --- a/core/modules/file/lib/Drupal/file/Plugin/field/formatter/FileFormatterBase.php +++ b/core/modules/file/lib/Drupal/file/Plugin/field/formatter/FileFormatterBase.php @@ -18,6 +18,8 @@ * {@inheritdoc} */ public function prepareView(array $entities, $langcode, array $items) { + parent::prepareView($entities, $langcode, $items); + // Remove files specified to not be displayed. $fids = array(); foreach ($entities as $id => $entity) { diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/Field/EmailFieldRdfaTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/Field/EmailFieldRdfaTest.php new file mode 100644 index 0000000..617e17a --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/Field/EmailFieldRdfaTest.php @@ -0,0 +1,65 @@ + 'Field formatter - email', + 'description' => 'Tests RDFa output by email field formatters.', + 'group' => 'RDF', + ); + } + + public function setUp() { + parent::setUp(); + + $this->createTestField(); + + // Add the mapping. + $mapping = rdf_get_mapping('node', 'test_node_type'); + $mapping->setFieldMapping($this->fieldName, array( + 'properties' => array('schema:email'), + ))->save(); + + // Set up test values. + $this->testValue = 'test@example.com'; + $this->entity = $this->drupalCreateNode(array('type' => 'test_node_type')); + $this->entity->get($this->fieldName)->value = 'test@example.com'; + $this->entity->save(); + + $uri_info = $this->entity->uri(); + $this->uri = url($uri_info['path']); + } + + /** + * Tests the plain formatter. + */ + public function testPlainFormatter() { + $this->assertFormatterRdfa('text_plain', 'http://schema.org/email', $this->testValue); + } + + /** + * Tests the mailto formatter. + */ + public function testMailToFormatter() { + $this->assertFormatterRdfa('email_mailto', 'http://schema.org/email', 'mailto:' . $this->testValue, 'uri'); + } +} diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/Field/FieldRdfaTestBase.php b/core/modules/rdf/lib/Drupal/rdf/Tests/Field/FieldRdfaTestBase.php index af2aeb9..a3f73f8 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/Field/FieldRdfaTestBase.php +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/Field/FieldRdfaTestBase.php @@ -6,9 +6,9 @@ namespace Drupal\rdf\Tests\Field; -use Drupal\field\Tests\FieldUnitTestBase; +use Drupal\node\Tests\NodeTestBase; -abstract class FieldRdfaTestBase extends FieldUnitTestBase { +abstract class FieldRdfaTestBase extends NodeTestBase { /** * The machine name of the field type to test. @@ -45,6 +45,13 @@ */ public static $modules = array('rdf'); + function setUp() { + parent::setUp(); + + // Creates test content type. + $this->drupalCreateContentType(array('type' => 'test_node_type')); + } + /** * Helper function to test the formatter's RDFa. * @@ -58,9 +65,13 @@ * The object's type, either 'uri' or 'literal'. */ protected function assertFormatterRdfa($formatter, $property, $value, $object_type = 'literal') { - $build = field_view_field($this->entity, $this->fieldName, array('type' => $formatter)); - $rendered = "
" . drupal_render($build) . '
'; - $graph = new \EasyRdf_Graph($this->uri, $rendered, 'rdfa'); + // The field formatter will be rendered inside the entity. Sets the field + // formatter in the entity display options before rendering the entity. + entity_get_display('node', 'test_node_type', 'default') + ->setComponent($this->fieldName, array('type' => $formatter)) + ->save(); + $build = entity_view_multiple(array($this->entity), 'default'); + $graph = new \EasyRdf_Graph($this->uri, drupal_render($build), 'rdfa'); $expected_value = array( 'type' => $object_type, @@ -78,9 +89,9 @@ protected function createTestField() { 'type' => $this->fieldType, ))->save(); entity_create('field_instance', array( - 'entity_type' => 'entity_test', + 'entity_type' => 'node', 'field_name' => $this->fieldName, - 'bundle' => 'entity_test', + 'bundle' => 'test_node_type', ))->save(); } diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/Field/TaxonomyTermReferenceRdfaTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/Field/TaxonomyTermReferenceRdfaTest.php new file mode 100644 index 0000000..95bf3c1 --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/Field/TaxonomyTermReferenceRdfaTest.php @@ -0,0 +1,109 @@ + 'Field formatter - taxonomy term reference', + 'description' => 'Tests RDFa output by taxonomy term reference field formatters.', + 'group' => 'RDF', + ); + } + + public function setUp() { + parent::setUp(); + + $vocabulary = entity_create('taxonomy_vocabulary', array( + 'name' => $this->randomName(), + 'vid' => drupal_strtolower($this->randomName()), + 'langcode' => Language::LANGCODE_NOT_SPECIFIED, + )); + $vocabulary->save(); + + entity_create('field_entity', array( + 'field_name' => $this->fieldName, + 'type' => 'taxonomy_term_reference', + 'cardinality' => FIELD_CARDINALITY_UNLIMITED, + 'settings' => array( + 'allowed_values' => array( + array( + 'vocabulary' => $vocabulary->id(), + 'parent' => 0, + ), + ), + ), + ))->save(); + entity_create('field_instance', array( + 'entity_type' => 'node', + 'field_name' => $this->fieldName, + 'bundle' => 'test_node_type', + ))->save(); + $this->term = entity_create('taxonomy_term', array( + 'name' => $this->randomName(), + 'vid' => $vocabulary->id(), + 'langcode' => Language::LANGCODE_NOT_SPECIFIED, + )); + $this->term->save(); + + // Add the mapping. + $mapping = rdf_get_mapping('node', 'test_node_type'); + $mapping->setFieldMapping($this->fieldName, array( + 'properties' => array('schema:about'), + ))->save(); + + // Set up test values. + $this->entity = $this->drupalCreateNode(array('type' => 'test_node_type')); + $this->entity->get($this->fieldName)->offsetGet(0)->get('target_id')->setValue($this->term->id()); + $this->entity->save(); + $this->uri = $this->getAbsoluteUri($this->entity); + } + + /** + * Tests the plain formatter. + */ + public function testPlainFormatter() { + $term_uri = $this->getAbsoluteUri($this->term); + $this->assertFormatterRdfa('taxonomy_term_reference_plain', 'http://schema.org/about', $term_uri, 'uri'); + } + + /** + * Test the link formatter. + */ + public function testLinkFormatter() { + $term_uri = $this->getAbsoluteUri($this->term); + $this->assertFormatterRdfa('taxonomy_term_reference_link', 'http://schema.org/about', $term_uri, 'uri'); + } +} diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module index 428f16b..8652564 100644 --- a/core/modules/rdf/rdf.module +++ b/core/modules/rdf/rdf.module @@ -197,6 +197,26 @@ function rdf_rdfa_attributes($mapping, $data = NULL) { */ /** + * Implements hook_entity_prepare_view(). + */ +function rdf_entity_prepare_view($entity_type, array $entities, array $displays, $view_mode) { + // Iterates over the RDF mappings for each entity and prepares the RDFa + // attributes to be added inside field formatters. + foreach ($entities as $id => $entity) { + $mapping = rdf_get_mapping($entity_type, $entity->bundle()); + // Only prepares the RDFa attributes for the fields which are configured + // to be displayed. + foreach ($displays[$entity->bundle()]->getComponents() as $name => $options) { + $field_mapping = $mapping->getPreparedFieldMapping($name); + if ($field_mapping['properties']) { + $property = $entity->get($name); + $property->html_data_attributes = rdf_rdfa_attributes($field_mapping); + } + } + } +} + +/** * Implements hook_comment_load(). */ function rdf_comment_load($comments) { @@ -318,43 +338,6 @@ function rdf_preprocess_node(&$variables) { } /** - * Implements hook_preprocess_HOOK() for field.tpl.php. - */ -function rdf_preprocess_field(&$variables) { - $element = $variables['element']; - $entity_type = $element['#entity_type']; - $bundle = $element['#bundle']; - $field_name = $element['#field_name']; - $field_mapping = rdf_get_mapping($entity_type, $bundle) - ->getPreparedFieldMapping($field_name); - - if (!empty($field_mapping)) { - foreach ($element['#items'] as $delta => $item) { - $variables['item_attributes'][$delta] = rdf_rdfa_attributes($field_mapping, $item); - // If this field is an image, RDFa will not output correctly when the - // image is in a containing tag. If the field is a file, RDFa will - // not output correctly if the filetype icon comes before the link to the - // file. We correct this by adding a resource attribute to the div if - // this field has a URI. - if (isset($item['entity']->uri)) { - if (!empty($element[$delta]['#image_style'])) { - $variables['item_attributes'][$delta]['resource'] = entity_load('image_style', $element[$delta]['#image_style'])->buildUrl($item['entity']->getFileUri()); - } - else { - $variables['item_attributes'][$delta]['resource'] = file_create_url($item['entity']->getFileUri()); - } - } - // Convert the item_attributes for this field item back into an Attribute - // object for printing. This is necessary because at this time this - // preprocess function overwrites $variables['item_attributes'][$delta], - // which is initialized as an Attribute object in - // template_preprocess_field(). - $variables['item_attributes'][$delta] = new Attribute($variables['item_attributes'][$delta]); - } - } -} - -/** * Implements hook_preprocess_HOOK() for user.tpl.php. */ function rdf_preprocess_user(&$variables) { @@ -559,38 +542,6 @@ function rdf_preprocess_taxonomy_term(&$variables) { } /** - * Implements hook_field_attach_view_alter(). - */ -function rdf_field_attach_view_alter(&$output, $context) { - // Append term mappings on displayed taxonomy links. - foreach (element_children($output) as $field_name) { - $element = &$output[$field_name]; - if ($element['#field_type'] == 'taxonomy_term_reference' && $element['#formatter'] == 'taxonomy_term_reference_link') { - foreach ($element['#items'] as $delta => $item) { - // This function is invoked during entity preview when taxonomy term - // reference items might contain free-tagging terms that do not exist - // yet and thus have no $item['entity']. - if (isset($item['entity'])) { - $term = $item['entity']; - $mapping = rdf_get_mapping('taxonomy_term', $term->bundle()); - $bundle_mapping = $mapping->getPreparedBundleMapping(); - if (!empty($bundle_mapping['types'])) { - $element[$delta]['#options']['attributes']['typeof'] = $bundle_mapping['types']; - } - $name_field_mapping = $mapping->getPreparedFieldMapping('name'); - if (!empty($name_field_mapping['properties'])) { - // A property attribute is used with an empty datatype attribute so - // the term name is parsed as a plain literal in RDFa 1.0 and 1.1. - $element[$delta]['#options']['attributes']['property'] = $name_field_mapping['properties']; - $element[$delta]['#options']['attributes']['datatype'] = ''; - } - } - } - } - } -} - -/** * Implements hook_preprocess_HOOK() for theme_image(). */ function rdf_preprocess_image(&$variables) { diff --git a/core/modules/system/system.module b/core/modules/system/system.module index bd58f93..dfa7bf4 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -8,6 +8,7 @@ use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Cache\Cache; use Drupal\Core\Language\Language; +use Drupal\Core\Template\Attribute; use Drupal\Core\Utility\ModuleInfo; use Drupal\system\Plugin\Block\SystemMenuBlock; use Drupal\user\UserInterface; diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/LinkFormatter.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/LinkFormatter.php index 6ce9e53..cb1a40e 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/LinkFormatter.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/LinkFormatter.php @@ -50,6 +50,13 @@ public function viewElements(EntityInterface $entity, $langcode, FieldInterface '#href' => $uri['path'], '#options' => $uri['options'], ); + + if (!empty($item->html_data_attributes)) { + if (!isset($elements[$delta]['#options']['attributes'])) { + $elements[$delta]['#options']['attributes'] = array(); + } + $elements[$delta]['#options']['attributes'] += $item->html_data_attributes; + } } } diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/TaxonomyFormatterBase.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/TaxonomyFormatterBase.php index a0ed35f..9ab8792 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/TaxonomyFormatterBase.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/formatter/TaxonomyFormatterBase.php @@ -25,6 +25,8 @@ * unsets values for invalid terms that do not exist. */ public function prepareView(array $entities, $langcode, array $items) { + parent::prepareView($entities, $langcode, $items); + $tids = array(); // Collect every possible term attached to any of the fieldable entities. diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php index dd0ee71..688c569 100644 --- a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php +++ b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php @@ -42,7 +42,18 @@ public function viewElements(EntityInterface $entity, $langcode, FieldInterface // https://drupal.org/node/2026339. $itemBC = $item->getValue(TRUE); $output = text_sanitize($this->getFieldSetting('text_processing'), $langcode, $itemBC, 'value'); - $elements[$delta] = array('#markup' => $output); + if (empty($item->html_data_attributes)) { + $elements[$delta] = array('#markup' => $output); + } + else { + // Adds a wrapping element if attributes are specified for this item. + $elements[$delta] = array( + '#type' => 'html_tag', + '#tag' => 'div', + '#attributes' => $item->html_data_attributes, + '#value' => $output, + ); + } } return $elements; diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextPlainFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextPlainFormatter.php index 2a95803..c5af4c5 100644 --- a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextPlainFormatter.php +++ b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextPlainFormatter.php @@ -38,9 +38,20 @@ public function viewElements(EntityInterface $entity, $langcode, FieldInterface $elements = array(); foreach ($items as $delta => $item) { - // The text value has no text format assigned to it, so the user input - // should equal the output, including newlines. - $elements[$delta] = array('#markup' => nl2br(check_plain($item->value))); + if (empty($item->html_data_attributes)) { + // The text value has no text format assigned to it, so the user input + // should equal the output, including newlines. + $elements[$delta] = array('#markup' => nl2br(check_plain($item->value))); + } + else { + // Adds a wrapping element if attributes are specified for this item. + $elements[$delta] = array( + '#type' => 'html_tag', + '#tag' => 'span', + '#attributes' => $item->html_data_attributes, + '#value' => nl2br(check_plain($item->value)), + ); + } } return $elements;