=== modified file 'modules/node/node.install' --- modules/node/node.install 2009-08-31 16:24:15 +0000 +++ modules/node/node.install 2009-09-11 11:23:02 +0000 @@ -344,6 +344,13 @@ function node_schema() { 'not null' => TRUE, 'default' => '', ), + 'rdf_mapping' => array( + 'description' => 'The serialized mapping from basic node attributes to RDF terms.', + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + 'serialize' => TRUE, + ), ), 'primary key' => array('type'), ); @@ -562,6 +569,22 @@ function node_update_7007() { } /** + * Add a column to the node_type table to store RDF mappings. + */ +function node_update_7099() { + $ret = array(); + $attributes = array( + 'not null' => FALSE, + 'size' => 'big', + 'serialize' => TRUE, + 'description' => 'The serialized mapping from basic node attributes to RDF terms.', + ); + db_add_column($ret, 'node_type', 'rdf_mapping', 'text', $attributes); + + return $ret; +} + +/** * @} End of "defgroup updates-6.x-to-7.x" * The next series of updates should start at 8000. */ === modified file 'modules/node/node.module' --- modules/node/node.module 2009-09-15 20:54:27 +0000 +++ modules/node/node.module 2009-09-16 06:00:09 +0000 @@ -495,6 +495,7 @@ function node_type_save($info) { 'custom' => (int) $type->custom, 'modified' => (int) $type->modified, 'locked' => (int) $type->locked, + 'rdf_mapping' => serialize($type->rdf_mapping), ); if ($is_existing) { @@ -640,6 +641,9 @@ function _node_types_build() { ->addTag('node_type_access') ->execute(); foreach ($type_result as $type_object) { + if (isset($type_object->rdf_mapping)) { + $type_object->rdf_mapping = unserialize($type_object->rdf_mapping); + } // Check for node types from disabled modules and mark their types for removal. // Types defined by the node module in the database (rather than by a separate // module using hook_node_info) have a base value of 'node_content'. The isset() @@ -694,10 +698,40 @@ function node_type_set_defaults($info = $type->modified = 0; $type->locked = 1; $type->is_new = 1; + $type->rdf_mapping = array( + 'rdftype' => array('sioc:Item', 'foaf:Document'), + 'title' => array( + 'property' => array('dc:title'), + ), + 'created' => array( + 'property' => array('dc:date', 'dc:created'), + 'datatype' => 'xsd:dateTime', + 'callback' => 'date_iso8601', + ), + 'changed' => array( + 'property' => array('dc:modified'), + ), + 'body' => array( + 'property' => array('content:encoded'), + ), + 'uid' => array( + 'property' => array('sioc:has_creator', 'foaf:maker'), + ), + 'name' => array( + 'property' => array('foaf:name'), + ), + ); } - $new_type = clone $type; $info = (array) $info; + + // Use a specific RDF mapping for this node type if a module defines it. + $rdf_mapping = module_invoke_all('rdf_mapping'); + if (!empty($info['type']) && !empty($rdf_mapping[$info['type']])) { + $info['rdf_mapping'] = $rdf_mapping[$info['type']]; + } + + $new_type = clone $type; foreach ($info as $key => $data) { $new_type->$key = $data; } === modified file 'modules/node/node.test' --- modules/node/node.test 2009-08-29 04:16:14 +0000 +++ modules/node/node.test 2009-09-15 17:28:19 +0000 @@ -615,6 +615,68 @@ class NodeRSSContentTestCase extends Dru } } +class NodeRDFaTestCase extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => t('Node RDFa output'), + 'description' => t('Ensure that RDFa is output on node pages.'), + 'group' => t('Node'), + ); + } + + function setUp() { + parent::setUp('rdf'); + } + + function testNodeRdfa() { + $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1)); + $node_resource = check_url(url('node/' . $node->nid, array('fragment' => 'this'))); + $user_resource = check_url(url('user/' . $node->uid, array('fragment' => 'this'))); + + // Test node in full node mode. + $this->drupalGet('node/' . $node->nid); + + $result = $this->xpath('//div[contains(@class, "node") and contains(@typeof, "sioc:Item")]'); + $this->assertFalse(empty($result), t('Found a typeof attribute including sioc:Item')); + // $this->assertEqual($result[0]['about'], $node_resource, t('Found correct about attribute')); + + $result = $this->xpath('//div[contains(@class, "node") and contains(@typeof, "foaf:Document")]'); + $this->assertFalse(empty($result), t('Found a typeof attribute including foaf:Document')); + + $result = $this->xpath('//meta[contains(@property, "dc:title")]'); + $this->assertFalse(empty($result), t('Found a meta tag with property=dc:title')); + + // $result = $this->xpath('//*[contains(@class, "submitted")]//*[contains(@property, "dc:created")]'); + // $this->assertFalse(empty($result), t('Found a dc:created property')); + // $this->assertEqual($result[0]['datatype'], 'xsd:dateTime', t('Found datatype of xsd:dateTime')); + // $this->assertTrue(preg_match('/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+\d{2}:\d{2}/', $result[0]['content']), t('Found a content attribute in the correct format')); + + // $result = $this->xpath('//div[contains(@typeof, "foaf:Document")]//*[contains(@class, "content") and contains(@property, "content:encoded") and contains(@property, "dc:description")]'); + // $this->assertFalse(empty($result), t('Found content:encoded and dc:description properties')); + + // $result = $this->xpath('//*[contains(@class, "submitted")]//*[contains(@rel, "sioc:has_creator") and contains(@rel, "dc:creator")]'); + // $this->assertFalse(empty($result), t('Found sioc:has_creator and dc:creator')); + // $result = $this->xpath('//*[contains(@class, "submitted")]//*[contains(@rel, "dc:creator")]//*[contains(@property, "foaf:name") and contains(@typeof, "sioc:User")]'); + // $this->assertFalse(empty($result), t('Found foaf:name and sioc:User')); + // $this->assertEqual($result[0]['about'], $user_resource, t('Found correct about attribute')); + + // Test node in teaser mode. + $this->drupalGet(''); + + $result = $this->xpath('//div[contains(@class, "node") and contains(@typeof, "sioc:Item")]'); + $this->assertFalse(empty($result), t('Found a typeof attribute including sioc:Item')); + // $this->assertEqual($result[0]['about'], $node_resource, t('Found correct about attribute')); + + $result = $this->xpath('//div[contains(@class, "node") and contains(@typeof, "foaf:Document")]'); + $this->assertFalse(empty($result), t('Found a typeof attribute including foaf:Document')); + + $result = $this->xpath('//h2[contains(@property, "dc:title")]'); + $this->assertFalse(empty($result), t('Found a h2 tag with property=dc:title')); + + } + +} + /** * Test case to verify basic node_access functionality. * @todo Cover hook_access in a separate test class. === modified file 'modules/node/node.tpl.php' --- modules/node/node.tpl.php 2009-09-11 06:48:02 +0000 +++ modules/node/node.tpl.php 2009-09-12 09:07:46 +0000 @@ -83,8 +83,8 @@ $name, '@datetime' => $date)); + print t('Submitted by !username on !datetime', + array('!username' => $name, '!datetime' => $date)); ?>