diff --git a/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php b/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php index 0c08d66f53347f2945ee4bc678078ec48cd311f6..05caf97454232fa85cd7214c2be4a71f5703a826 100644 --- a/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php +++ b/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php @@ -148,6 +148,13 @@ public function viewElements(FieldItemListInterface $items) { $element[$delta] = array( '#markup' => String::checkPlain($link_title), ); + + if (!empty($item->_attributes)) { + // Piggyback on the metadata attributes, which will be placed in the + // field template wrapper, and set the URL value in a content + // attribute. + $item->_attributes += array('content' => $item->url); + } } else { $element[$delta] = array( @@ -162,6 +169,14 @@ public function viewElements(FieldItemListInterface $items) { $element[$delta]['#route_name'] = $url->getRouteName(); $element[$delta]['#route_parameters'] = $url->getRouteParameters(); } + + if (!empty($item->_attributes)) { + $element[$delta]['#options'] += array ('attributes' => array()); + $element[$delta]['#options']['attributes'] += $item->_attributes; + // Unset field item attributes since they have been included in the + // formatter output and should not be rendered in the field template. + unset($item->_attributes); + } } } diff --git a/core/modules/link/src/Plugin/Field/FieldFormatter/LinkSeparateFormatter.php b/core/modules/link/src/Plugin/Field/FieldFormatter/LinkSeparateFormatter.php index 7a427e5480572ca156bac34537174325d279366e..40daa4493a1934eee7978cfd2701ea9ee767c050 100644 --- a/core/modules/link/src/Plugin/Field/FieldFormatter/LinkSeparateFormatter.php +++ b/core/modules/link/src/Plugin/Field/FieldFormatter/LinkSeparateFormatter.php @@ -77,6 +77,15 @@ public function viewElements(FieldItemListInterface $items) { '#url_title' => $url_title, '#url' => $url, ); + + if (!empty($item->_attributes)) { + // Set our RDFa attributes on the element that is being built. + $url->setOption('attributes', $item->_attributes); + + // Unset field item attributes since they have been included in the + // formatter output and should not be rendered in the field template. + unset($item->_attributes); + } } return $element; } diff --git a/core/modules/rdf/src/Tests/Field/LinkFieldRdfaTest.php b/core/modules/rdf/src/Tests/Field/LinkFieldRdfaTest.php new file mode 100644 index 0000000000000000000000000000000000000000..501352038e6fa37514fb048547becd40aa812d5e --- /dev/null +++ b/core/modules/rdf/src/Tests/Field/LinkFieldRdfaTest.php @@ -0,0 +1,197 @@ + 'Field formatter: link', + 'description' => 'Tests RDFa output by link field formatters.', + 'group' => 'RDF', + ); + } + + /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(); + + $this->createTestField(); + + // Add the mapping. + $mapping = rdf_get_mapping('entity_test', 'entity_test'); + $mapping->setFieldMapping($this->fieldName, array( + 'properties' => array('schema:link'), + ))->save(); + + } + + /** + * Tests all formatters with link to external page. + */ + public function testAllFormattersExternal() { + // Set up test values. + $this->testValue = 'http://test.me/foo/bar/neque/porro/quisquam/est/qui-dolorem?foo/bar/neque/porro/quisquam/est/qui-dolorem'; + $this->entity = entity_create('entity_test', array()); + $this->entity->{$this->fieldName}->url = $this->testValue; + + // Set up the expected result. + $expected_rdf = array( + 'value' => $this->testValue, + 'type' => 'uri', + ); + + $this->runTestAllFormatters($expected_rdf, 'external'); + } + + /** + * Tests all formatters with link to internal page. + */ + public function testAllFormattersInternal() { + // Set up test values. + $this->testValue = 'admin'; + $this->entity = entity_create('entity_test', array()); + $this->entity->{$this->fieldName}->url = $this->testValue; + + // Set up the expected result. + // AssertFormatterRdfa looks for a full path. + $expected_rdf = array( + 'value' => $this->uri . '/' . $this->testValue, + 'type' => 'uri', + ); + + $this->runTestAllFormatters($expected_rdf, 'internal'); + } + + /** + * Tests all formatters with link to frontpage. + */ + public function testAllFormattersFront() { + // Set up test values. + $this->testValue = ''; + $this->entity = entity_create('entity_test', array()); + $this->entity->{$this->fieldName}->url = $this->testValue; + + // Set up the expected result. + $expected_rdf = array( + 'value' => $this->uri . '/', + 'type' => 'uri', + ); + + $this->runTestAllFormatters($expected_rdf, 'front'); + } + + /** + * Helper function to test all link formatters. + */ + public function runTestAllFormatters($expected_rdf, $type = NULL) { + + // Test the link formatter: trim at 80, no other settings. + $formatter = array( + 'type' => $type . ' link', + 'settings' => array( + 'trim_length' => 80, + 'url_only' => FALSE, + 'url_plain' => FALSE, + 'rel' => '', + 'target' => '', + ), + ); + $this->assertFormatterRdfa($formatter, 'http://schema.org/link', $expected_rdf); + + // Test the link formatter: trim at 40, nofollow, new window. + $formatter = array( + 'type' => $type . ' link', + 'settings' => array( + 'trim_length' => 40, + 'url_only' => FALSE, + 'url_plain' => FALSE, + 'rel' => 'nofollow', + 'target' => '_blank', + ), + ); + $this->assertFormatterRdfa($formatter, 'http://schema.org/link', $expected_rdf); + + // Test the link formatter: trim at 40, URL only (not plaintext) nofollow, + // new window. + $formatter = array( + 'type' => $type . ' link', + 'settings' => array( + 'trim_length' => 40, + 'url_only' => TRUE, + 'url_plain' => FALSE, + 'rel' => 'nofollow', + 'target' => '_blank', + ), + ); + $this->assertFormatterRdfa($formatter, 'http://schema.org/link', $expected_rdf); + + // Test the link_separate formatter: trim at 40, nofollow, new window. + $formatter = array( + 'type' => $type . ' link_separate', + 'settings' => array( + 'trim_length' => 40, + 'rel' => 'nofollow', + 'target' => '_blank', + ), + ); + $this->assertFormatterRdfa($formatter, 'http://schema.org/link', $expected_rdf); + + // Change the expected value here to literal. When formatted as plaintext + // then the RDF is expecting a 'literal' not a 'uri'. + $expected_rdf = array( + 'value' => $this->testValue, + 'type' => 'literal', + ); + // Test the link formatter: trim at 20, url only (as plaintext.) + $formatter = array( + 'type' => $type . ' link', + 'settings' => array( + 'trim_length' => 20, + 'url_only' => TRUE, + 'url_plain' => TRUE, + 'rel' => '0', + 'target' => '0', + ), + ); + $this->assertFormatterRdfa($formatter, 'http://schema.org/link', $expected_rdf); + + // Test the link formatter: do not trim, url only (as plaintext.) + $formatter = array( + 'type' => $type . ' link', + 'settings' => array( + 'trim_length' => 0, + 'url_only' => TRUE, + 'url_plain' => TRUE, + 'rel' => '0', + 'target' => '0', + ), + ); + $this->assertFormatterRdfa($formatter, 'http://schema.org/link', $expected_rdf); + } + +}