- Patch #493030 by scor, Stefan Freudenberg, pwolanin, fago, Benjamin Melançon, kriskras, dmitrig01, sun: added RDFa support to Drupal core. Oh my, oh my.
parent
0b750209b6
commit
24669bfb50
|
@ -184,3 +184,17 @@ function blog_block_view($delta = '') {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_rdf_mapping().
|
||||
*/
|
||||
function blog_rdf_mapping() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'node',
|
||||
'bundle' => 'blog',
|
||||
'mapping' => array(
|
||||
'rdftype' => array('sioct:Weblog'),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2494,3 +2494,38 @@ function comment_filter_format_delete($format, $fallback) {
|
|||
->condition('format', $format->format)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_rdf_mapping().
|
||||
*/
|
||||
function comment_rdf_mapping() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'comment',
|
||||
'bundle' => RDF_DEFAULT_BUNDLE,
|
||||
'mapping' => array(
|
||||
'rdftype' => array('sioct:Post'),
|
||||
'title' => array(
|
||||
'predicates' => array('dc:title'),
|
||||
),
|
||||
'created' => array(
|
||||
'predicates' => array('dc:date', 'dc:created'),
|
||||
'datatype' => 'xsd:dateTime',
|
||||
'callback' => 'date_iso8601',
|
||||
),
|
||||
'body' => array(
|
||||
'predicates' => array('content:encoded'),
|
||||
),
|
||||
'pid' => array(
|
||||
'predicates' => array('sioc:reply_of'),
|
||||
),
|
||||
'uid' => array(
|
||||
'predicates' => array('sioc:has_creator'),
|
||||
),
|
||||
'name' => array(
|
||||
'predicates' => array('foaf:name'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -864,3 +864,52 @@ class CommentRSSUnitTest extends CommentHelperCase {
|
|||
$this->assertNoRaw($raw, t('Hidden comments is not a part of RSS feed.'));
|
||||
}
|
||||
}
|
||||
|
||||
class RdfaCommentTestCase extends CommentHelperCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'RDFa comment markup',
|
||||
'description' => 'Test RDFa markup in comments.',
|
||||
'group' => 'RDF',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('comment', 'rdf');
|
||||
|
||||
$this->admin_user = $this->drupalCreateUser(array('administer content types', 'administer comments', 'administer permissions', 'administer blocks'));
|
||||
$this->web_user = $this->drupalCreateUser(array('access comments', 'post comments', 'create article content'));
|
||||
|
||||
$this->drupalLogin($this->web_user);
|
||||
$this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1));
|
||||
$this->drupalLogout();
|
||||
}
|
||||
|
||||
function testAttributesInMarkup() {
|
||||
// Set comments to not have subject.
|
||||
$this->drupalLogin($this->admin_user);
|
||||
$this->setCommentPreview(FALSE);
|
||||
$this->setCommentForm(TRUE);
|
||||
$this->setCommentSubject(TRUE);
|
||||
$this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, t('Comment paging changed.'));
|
||||
$this->drupalLogout();
|
||||
|
||||
// Post comment.
|
||||
$this->drupalLogin($this->web_user);
|
||||
$subject_text = 'foo';
|
||||
$comment_text = 'bar';
|
||||
$comment = $this->postComment($this->node, $comment_text, $subject_text, FALSE);
|
||||
$this->drupalGet('node/' . $this->node->nid);
|
||||
|
||||
$comment_container = $this->xpath("//div[contains(@class, 'comment') and @typeof='sioct:Post']");
|
||||
$this->assertFalse(empty($comment_container));
|
||||
$comment_title = $this->xpath("//h3[@property='dc:title']");
|
||||
$this->assertEqual((string)$comment_title[0]->a, 'foo');
|
||||
$comment_date = $this->xpath("//div[@typeof='sioct:Post']//*[contains(@property, 'dc:date') and contains(@property, 'dc:created')]");
|
||||
$this->assertFalse(empty($comment_date));
|
||||
$comment_author = $this->xpath("//div[@typeof='sioct:Post']//*[contains(@property, 'foaf:name')]");
|
||||
$this->assertEqual((string)$comment_author[0], $this->web_user->name);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1132,3 +1132,29 @@ function _forum_update_forum_index($nid) {
|
|||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_rdf_mapping().
|
||||
*/
|
||||
function forum_rdf_mapping() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'node',
|
||||
'bundle' => 'forum',
|
||||
'mapping' => array(
|
||||
'rdftype' => array('sioct:Post', 'sioct:ForumTopic'),
|
||||
'taxonomy_forums' => array(
|
||||
'predicates' => array('sioc:has_container'),
|
||||
'type' => 'rel',
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'taxonomy_term',
|
||||
'bundle' => 'forums',
|
||||
'mapping' => array(
|
||||
'rdftype' => array('sioct:Container'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -753,6 +753,47 @@ function node_type_set_defaults($info = array()) {
|
|||
return $new_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the default RDF mapping for the node entity type.
|
||||
*
|
||||
* These default mapping properties are used by rdf_save_mapping() to populate
|
||||
* non-existing properties before they are saved to the database.
|
||||
*
|
||||
* @return
|
||||
* A list of default mapping properties for the node entity type.
|
||||
*/
|
||||
function node_rdf_mapping() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'node',
|
||||
'bundle' => RDF_DEFAULT_BUNDLE,
|
||||
'mapping' => array(
|
||||
'rdftype' => array('sioc:Item', 'foaf:Document'),
|
||||
'title' => array(
|
||||
'predicates' => array('dc:title'),
|
||||
),
|
||||
'created' => array(
|
||||
'predicates' => array('dc:date', 'dc:created'),
|
||||
'datatype' => 'xsd:dateTime',
|
||||
'callback' => 'date_iso8601',
|
||||
),
|
||||
'changed' => array(
|
||||
'predicates' => array('dc:modified'),
|
||||
),
|
||||
'body' => array(
|
||||
'predicates' => array('content:encoded'),
|
||||
),
|
||||
'uid' => array(
|
||||
'predicates' => array('sioc:has_creator'),
|
||||
),
|
||||
'name' => array(
|
||||
'predicates' => array('foaf:name'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether a node hook exists.
|
||||
*
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* given element.
|
||||
* - $user_picture: The node author's picture from user-picture.tpl.php.
|
||||
* - $date: Formatted creation date (use $created to reformat with
|
||||
* format_date()).
|
||||
* format_date()). This data is excepted to be sanitized beforehand.
|
||||
* - $name: Themed username of node author output from theme_username().
|
||||
* - $node_url: Direct url of the current node.
|
||||
* - $terms: the themed list of taxonomy term links output from theme_links().
|
||||
|
@ -88,8 +88,8 @@
|
|||
<?php if ($display_submitted): ?>
|
||||
<span class="submitted">
|
||||
<?php
|
||||
print t('Submitted by !username on @datetime',
|
||||
array('!username' => $name, '@datetime' => $date));
|
||||
print t('Submitted by !username on !datetime',
|
||||
array('!username' => $name, '!datetime' => $date));
|
||||
?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Hooks provided by the RDF module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup hooks
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allow modules to define RDF mappings for bundles.
|
||||
*
|
||||
* Modules defining their own bundles can specify which RDF semantics should be
|
||||
* used to annotate these bundles. These mappings are then used for automatic
|
||||
* RDFa output in the HTML code.
|
||||
*
|
||||
* @return
|
||||
* An array of mapping structures. Each mapping has three mandatory keys:
|
||||
* - type: The name of an entity type.
|
||||
* - bundle: The name of a bundle.
|
||||
* - mapping: The mapping structure which applies to the entity type, bundle
|
||||
* pair. A mapping structure is an array with keys corresponding to
|
||||
* existing field instances in the bundle. Each field is then described in
|
||||
* terms of RDF mapping. 'predicates' is an array of RDF predicates which
|
||||
* describe the relation between the bundle (subject in RDF) and the value of
|
||||
* the field (object in RDF), this value being either some text, another
|
||||
* bundle or a URL in general. 'datatype' and 'callback' are used in RDFa to
|
||||
* format data so that it's readable by machine: a typical example is a date
|
||||
* which can be written in many different formats but should be translated
|
||||
* into a uniform format for machine comsumption. 'type' is a string used to
|
||||
* determine the type of RDFa markup which will be used in the final HTML
|
||||
* output, depending on whether the RDF object is a literal text or another
|
||||
* RDF resource. The 'rdftype' key is a special case which is used to define
|
||||
* the type of the instance, its value shoud be an array of RDF classes.
|
||||
*/
|
||||
function hook_rdf_mapping() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'node',
|
||||
'bundle' => 'blog',
|
||||
'mapping' => array(
|
||||
'rdftype' => array('sioct:Weblog'),
|
||||
'title' => array(
|
||||
'predicates' => array('dc:title'),
|
||||
),
|
||||
'created' => array(
|
||||
'predicates' => array('dc:date', 'dc:created'),
|
||||
'datatype' => 'xsd:dateTime',
|
||||
'callback' => 'date_iso8601',
|
||||
),
|
||||
'body' => array(
|
||||
'predicates' => array('content:encoded'),
|
||||
),
|
||||
'uid' => array(
|
||||
'predicates' => array('sioc:has_creator'),
|
||||
'type' => 'rel',
|
||||
),
|
||||
'name' => array(
|
||||
'predicates' => array('foaf:name'),
|
||||
),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup hooks".
|
||||
*/
|
|
@ -0,0 +1,9 @@
|
|||
; $Id$
|
||||
name = RDF
|
||||
description = Allows to map the site data structure to RDF and export it in RDFa.
|
||||
package = Core
|
||||
version = VERSION
|
||||
core = 7.x
|
||||
files[] = rdf.install
|
||||
files[] = rdf.module
|
||||
files[] = rdf.test
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the rdf module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_schema().
|
||||
*/
|
||||
function rdf_schema() {
|
||||
$schema['rdf_mapping'] = array(
|
||||
'description' => 'Stores custom RDF mappings for user defined content types or overriden module-defined mappings',
|
||||
'fields' => array(
|
||||
'type' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
'not null' => TRUE,
|
||||
'description' => 'The name of the entity type a mapping applies to (node, user, comment, etc.).',
|
||||
),
|
||||
'bundle' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
'not null' => TRUE,
|
||||
'description' => 'The name of the bundle a mapping applies to.',
|
||||
),
|
||||
'mapping' => array(
|
||||
'description' => 'The serialized mapping of the bundle type and fields to RDF terms.',
|
||||
'type' => 'text',
|
||||
'not null' => FALSE,
|
||||
'size' => 'big',
|
||||
'serialize' => TRUE,
|
||||
),
|
||||
),
|
||||
'primary key' => array('type', 'bundle'),
|
||||
);
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function rdf_install() {
|
||||
// The installer does not trigger hook_modules_installed() so it needs to
|
||||
// triggered programmatically on the modules which defined RDF mappings.
|
||||
$modules = module_implements('rdf_mapping');
|
||||
rdf_modules_installed($modules);
|
||||
}
|
|
@ -0,0 +1,590 @@
|
|||
<?php
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Enables semantically enriched output for Drupal sites.
|
||||
*
|
||||
* This module introduces RDFa to Drupal, which provides a set of XHTML
|
||||
* attributes to augment visual data with machine-readable hints.
|
||||
* @see http://www.w3.org/TR/xhtml-rdfa-primer/
|
||||
*
|
||||
* Modules can provide mappings of their bundles' data and metadata to RDFa
|
||||
* properties using the appropriate vocabularies. This module takes care of
|
||||
* injecting that data into variables available to themers in the .tpl files.
|
||||
* Drupal core themes ship with RDFa output enabled.
|
||||
*
|
||||
* Example mapping from node.module:
|
||||
* array(
|
||||
* 'type' => 'node',
|
||||
* 'bundle' => RDF_DEFAULT_BUNDLE,
|
||||
* 'mapping' => array(
|
||||
* 'rdftype' => array('sioc:Item', 'foaf:Document'),
|
||||
* 'title' => array(
|
||||
* 'predicates' => array('dc:title'),
|
||||
* ),
|
||||
* 'created' => array(
|
||||
* 'predicates' => array('dc:date', 'dc:created'),
|
||||
* 'datatype' => 'xsd:dateTime',
|
||||
* 'callback' => 'date_iso8601',
|
||||
* ),
|
||||
* 'body' => array(
|
||||
* 'predicates' => array('content:encoded'),
|
||||
* ),
|
||||
* 'uid' => array(
|
||||
* 'predicates' => array('sioc:has_creator'),
|
||||
* ),
|
||||
* 'name' => array(
|
||||
* 'predicates' => array('foaf:name'),
|
||||
* ),
|
||||
* ),
|
||||
* );
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defines the empty string as the name of the bundle to store default
|
||||
* RDF mappings of a type's properties (fields, et. al.).
|
||||
*/
|
||||
define('RDF_DEFAULT_BUNDLE', '');
|
||||
|
||||
/**
|
||||
* Implements hook_theme().
|
||||
*/
|
||||
function rdf_theme() {
|
||||
return array(
|
||||
'rdf_template_variable_wrapper' => array(
|
||||
'arguments' => array('content' => NULL, 'attributes' => array(), 'context' => array(), 'inline' => TRUE),
|
||||
),
|
||||
'rdf_metadata' => array(
|
||||
'arguments' => array('metadata' => array()),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a template variable in an HTML element with the desired attributes.
|
||||
*
|
||||
* @ingroup themeable
|
||||
*/
|
||||
function theme_rdf_template_variable_wrapper($variables) {
|
||||
$output = $variables['content'];
|
||||
if (!empty($output) && !empty($variables['attributes'])) {
|
||||
$attributes = drupal_attributes($variables['attributes']);
|
||||
$output = $variables['inline'] ? "<span$attributes>$output</span>" : "<div$attributes>$output</div>";
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a series of empty spans for exporting RDF metadata in RDFa.
|
||||
*
|
||||
* Sometimes it is useful to export data which is not semantically present in
|
||||
* the HTML output. For example, a hierarchy of comments is visible for a human
|
||||
* but not for machines because this hiearchy is not present in the DOM tree.
|
||||
* We can express it in RDFa via empty span tags. These won't be visible and
|
||||
* will give machines extra information about the content and its structure.
|
||||
*
|
||||
* @ingroup themeable
|
||||
*/
|
||||
function theme_rdf_metadata($variables) {
|
||||
$output = '';
|
||||
foreach ($variables['metadata'] as $attributes) {
|
||||
$output .= '<span' . drupal_attributes($attributes) . ' />';
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process function for wrapping some content with an extra tag.
|
||||
*/
|
||||
function rdf_process(&$variables, $hook) {
|
||||
if (!empty($variables['rdf_variable_attributes_array'])) {
|
||||
foreach ($variables['rdf_variable_attributes_array'] as $variable_name => $attributes) {
|
||||
$context = array('hook' => $hook, 'variable_name' => $variable_name, 'variables' => $variables);
|
||||
$variables[$variable_name] = theme('rdf_template_variable_wrapper', array('content' => $variables[$variable_name], 'attributes' => $attributes, 'context' => $context));
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($variables['metadata_attributes_array'])) {
|
||||
if (!isset($variables['content']['#prefix'])) {
|
||||
$variables['content']['#prefix'] = '';
|
||||
}
|
||||
$variables['content']['#prefix'] = theme('rdf_metadata', array('metadata' => $variables['metadata_attributes_array'])) . $variables['content']['#prefix'];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mapping for the attributes of the given type, bundle pair.
|
||||
*
|
||||
* @param $type
|
||||
* An entity type.
|
||||
* @param $bundle
|
||||
* A bundle name.
|
||||
* @return array
|
||||
* The mapping corresponding to the requested type, bundle pair or an empty
|
||||
* array.
|
||||
*/
|
||||
function rdf_get_mapping($type, $bundle = RDF_DEFAULT_BUNDLE) {
|
||||
// Retrieve the mapping from the entity info.
|
||||
$entity_info = entity_get_info($type);
|
||||
if (!empty($entity_info['bundles'][$bundle]['rdf_mapping'])) {
|
||||
return $entity_info['bundles'][$bundle]['rdf_mapping'];
|
||||
}
|
||||
else {
|
||||
return _rdf_get_default_mapping($type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves an RDF mapping to the database.
|
||||
*
|
||||
* Takes a mapping structure returned by hook_rdf_mapping() implementations
|
||||
* and creates or updates a record mapping for each encountered
|
||||
* type, bundle pair. If available, adds default values for non-existent
|
||||
* mapping keys.
|
||||
*
|
||||
* @param $mapping
|
||||
* The RDF mapping to save, as an array.
|
||||
* @return
|
||||
* Status flag indicating the outcome of the operation.
|
||||
*/
|
||||
function rdf_save_mapping($mapping) {
|
||||
// Adds default values for non-existent keys.
|
||||
$new_mapping = $mapping['mapping'] + _rdf_get_default_mapping($mapping['type']);
|
||||
$exists = (bool)rdf_read_mapping($mapping['type'], $mapping['bundle']);
|
||||
|
||||
if ($exists) {
|
||||
rdf_update_mapping($mapping['type'], $mapping['bundle'], $new_mapping);
|
||||
return SAVED_UPDATED;
|
||||
}
|
||||
else {
|
||||
rdf_create_mapping($mapping['type'], $mapping['bundle'], $new_mapping);
|
||||
return SAVED_NEW;
|
||||
}
|
||||
|
||||
cache_clear_all('entity_info', 'cache');
|
||||
drupal_static_reset('entity_get_info');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_modules_installed().
|
||||
*
|
||||
* Checks if the installed modules have any RDF mapping definitions to declare
|
||||
* and stores them in the rdf_mapping table.
|
||||
*
|
||||
* While both default entity mappings and specific bundle mappings can be
|
||||
* defined in hook_rdf_mapping(), we do not want to save the default entity
|
||||
* mappings in the database because users are not expected to alter these.
|
||||
* Instead they should alter specific bundle mappings which are stored in the
|
||||
* database so that they can be altered via the RDF CRUD mapping API.
|
||||
*/
|
||||
function rdf_modules_installed($modules) {
|
||||
// We need to clear the caches of entity_info as this is not done right
|
||||
// during the tests. see http://drupal.org/node/594234
|
||||
cache_clear_all('entity_info', 'cache');
|
||||
drupal_static_reset('entity_get_info');
|
||||
|
||||
foreach ($modules as $module) {
|
||||
if (function_exists($module . '_rdf_mapping')) {
|
||||
$mapping_array = call_user_func($module . '_rdf_mapping');
|
||||
foreach ($mapping_array as $mapping) {
|
||||
// Only the bundle mappings are saved in the database.
|
||||
if ($mapping['bundle'] != RDF_DEFAULT_BUNDLE) {
|
||||
rdf_save_mapping($mapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_modules_uninstalled().
|
||||
*/
|
||||
function rdf_modules_uninstalled($modules) {
|
||||
// @todo remove the RDF mappings.
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_info_alter().
|
||||
*
|
||||
* Adds the proper RDF mapping to each entity type, bundle pair.
|
||||
*/
|
||||
function rdf_entity_info_alter(&$entity_info) {
|
||||
// Loop through each entity type and its bundles.
|
||||
foreach ($entity_info as $entity_type => $entity_type_info) {
|
||||
if (isset($entity_type_info['bundles'])) {
|
||||
foreach ($entity_type_info['bundles'] as $bundle => $bundle_info) {
|
||||
if ($mapping = rdf_read_mapping($entity_type, $bundle)) {
|
||||
$entity_info[$entity_type]['bundles'][$bundle]['rdf_mapping'] = $mapping;
|
||||
}
|
||||
else {
|
||||
// If no mapping was found in the database, assign the default RDF
|
||||
// mapping for this entity type.
|
||||
$entity_info[$entity_type]['bundles'][$bundle]['rdf_mapping'] = _rdf_get_default_mapping($entity_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ready to render RDFa attributes for the given mapping.
|
||||
*
|
||||
* @param $mapping
|
||||
* An array containing a mandatory predicates key and optional datatype,
|
||||
* callback and type keys.
|
||||
* Example:
|
||||
* array(
|
||||
* 'predicates' => array('dc:created'),
|
||||
* 'datatype' => 'xsd:dateTime',
|
||||
* 'callback' => 'date_iso8601',
|
||||
* )
|
||||
* @param $data
|
||||
* A value that needs to be converted by the provided callback function.
|
||||
* @return array
|
||||
* An array containing RDFa attributes ready for rendering.
|
||||
*/
|
||||
function drupal_rdfa_attributes($mapping, $data = NULL) {
|
||||
// The type of mapping defaults to 'property'.
|
||||
$type = isset($mapping['type']) ? $mapping['type'] : 'property';
|
||||
|
||||
switch ($type) {
|
||||
// The mapping expresses the relationship between two resources.
|
||||
case 'rel':
|
||||
case 'rev':
|
||||
$attributes[$type] = $mapping['predicates'];
|
||||
break;
|
||||
|
||||
// The mapping expressed the relationship between a resource and some
|
||||
// literal text.
|
||||
case 'property':
|
||||
$attributes['property'] = $mapping['predicates'];
|
||||
|
||||
if (isset($mapping['callback']) && isset($data)) {
|
||||
$callback = $mapping['callback'];
|
||||
|
||||
if (function_exists($callback)) {
|
||||
$attributes['content'] = call_user_func($callback, $data);
|
||||
}
|
||||
if (isset($mapping['datatype'])) {
|
||||
$attributes['datatype'] = $mapping['datatype'];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_entity_load().
|
||||
*/
|
||||
function rdf_entity_load($entities, $type) {
|
||||
foreach ($entities as $entity) {
|
||||
// Extracts the bundle of the entity being loaded.
|
||||
list($id, $vid, $bundle) = field_extract_ids($type, $entity);
|
||||
$entity->rdf_mapping = rdf_get_mapping($type, $bundle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements MODULE_preprocess_HOOK().
|
||||
*/
|
||||
function rdf_preprocess_node(&$variables) {
|
||||
// Add RDFa markup to the node container. The about attribute specifies the
|
||||
// URI of the resource described within the HTML element, while the typeof
|
||||
// attribute indicates its RDF type (foaf:Document, or sioc:User, etc.).
|
||||
$variables['attributes_array']['about'] = empty($variables['node_url']) ? NULL: $variables['node_url'];
|
||||
$variables['attributes_array']['typeof'] = empty($variables['node']->rdf_mapping['rdftype']) ? NULL : $variables['node']->rdf_mapping['rdftype'];
|
||||
|
||||
// Add RDFa markup to the title of the node. Because the RDFa markup is added
|
||||
// to the h2 tag which might contain HTML code, we specify an empty datatype
|
||||
// to ensure the value of the title read by the RDFa parsers is a literal.
|
||||
$variables['title_attributes_array']['property'] = empty($variables['node']->rdf_mapping['title']['predicates']) ? NULL : $variables['node']->rdf_mapping['title']['predicates'];
|
||||
$variables['title_attributes_array']['datatype'] = '';
|
||||
|
||||
// In full node mode, the title is not displayed by node.tpl.php so it is
|
||||
// added in the head tag of the HTML page.
|
||||
if ($variables['page']) {
|
||||
$title_attributes['property'] = empty($variables['node']->rdf_mapping['title']['predicates']) ? NULL : $variables['node']->rdf_mapping['title']['predicates'];
|
||||
$title_attributes['content'] = $variables['node_title'];
|
||||
$title_attributes['about'] = $variables['node_url'];
|
||||
drupal_add_html_head('<meta' . drupal_attributes($title_attributes) . ' />');
|
||||
}
|
||||
|
||||
// Add RDFa markup for the date.
|
||||
if (!empty($variables['rdf_mapping']['created'])) {
|
||||
$date_attributes_array = drupal_rdfa_attributes($variables['rdf_mapping']['created'], $variables['created']);
|
||||
$variables['rdf_variable_attributes_array']['date'] = $date_attributes_array;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements MODULE_preprocess_HOOK().
|
||||
*/
|
||||
function rdf_preprocess_field(&$variables) {
|
||||
$entity_type = $variables['element']['#object_type'];
|
||||
$instance = $variables['instance'];
|
||||
$mapping = rdf_get_mapping($entity_type, $instance['bundle']);
|
||||
$field_name = $instance['field_name'];
|
||||
|
||||
if (!empty($mapping) && !empty($mapping[$field_name])) {
|
||||
foreach ($variables['items'] as $delta => $item) {
|
||||
if (!empty($item['#item'])) {
|
||||
$variables['item_attributes_array'][$delta] = drupal_rdfa_attributes($mapping[$field_name], $item['#item']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements MODULE_preprocess_HOOK().
|
||||
*/
|
||||
function rdf_preprocess_user_profile(&$variables) {
|
||||
// Adds RDFa markup to the user profile page. Fields displayed in this page
|
||||
// will automatically describe the user.
|
||||
// @todo move to user.module
|
||||
$account = user_load($variables['user']->uid);
|
||||
if (!empty($account->rdf_mapping['rdftype'])) {
|
||||
$variables['attributes_array']['typeof'] = $account->rdf_mapping['rdftype'];
|
||||
$variables['attributes_array']['about'] = url('user/' . $account->uid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements MODULE_preprocess_HOOK().
|
||||
*/
|
||||
function rdf_preprocess_username(&$variables) {
|
||||
$account = $variables['account'];
|
||||
if (!empty($account->rdf_mapping['name'])) {
|
||||
if ($account->uid != 0) {
|
||||
// The following RDFa construct allows to fit all the needed information
|
||||
// into the a tag and avoids having to wrap it with an extra span.
|
||||
|
||||
// An RDF resource for the user is created with the 'about' attribute and
|
||||
// the profile URI is used to identify this resource. Even if the user
|
||||
// profile is not accessible, we generate its URI regardless in order to
|
||||
// be able to identify the user in RDF.
|
||||
$variables['attributes_array']['about'] = url('user/' . $account->uid);
|
||||
// The 'typeof' attribute specifies the RDF type(s) of this resource. They
|
||||
// are defined in the 'rdftype' property of the user object RDF mapping.
|
||||
// Since the full user object is not available in $variables, it needs to
|
||||
// be loaded. This is due to the collision between the node and user
|
||||
// when they are merged into $account and some properties are overridden.
|
||||
$variables['attributes_array']['typeof'] = user_load($account->uid)->rdf_mapping['rdftype'];
|
||||
|
||||
// This first thing we are describing is the relation between the user and
|
||||
// the parent resource (e.g. a node). Because the set of predicate link
|
||||
// the parent to the user, we must use the 'rev' RDFa attribute to specify
|
||||
// that the relationship is reverse.
|
||||
if (!empty($account->rdf_mapping['uid']['predicates'])) {
|
||||
$variables['attributes_array']['rev'] = $account->rdf_mapping['uid']['predicates'];
|
||||
// We indicate the parent identifier in the 'resource' attribute,
|
||||
// typically this is the entity URI. This is the object in RDF.
|
||||
$parent_uri = '';
|
||||
if (!empty($account->path['source'])) {
|
||||
$parent_uri = url($account->path['source']);
|
||||
}
|
||||
elseif (!empty($account->cid)) {
|
||||
$parent_uri = url('comment/' . $account->cid, array('fragment' => 'comment-' . $account->cid));
|
||||
}
|
||||
$variables['attributes_array']['resource'] = $parent_uri;
|
||||
}
|
||||
|
||||
// The second information we annotate is the name of the user with the
|
||||
// 'property' attribute. We do not need to specify the RDF object here
|
||||
// because it's the value inside the a tag which will be used
|
||||
// automatically according to the RDFa parsing rules.
|
||||
$variables['attributes_array']['property'] = $account->rdf_mapping['name']['predicates'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements MODULE_preprocess_HOOK().
|
||||
*/
|
||||
function rdf_preprocess_comment(&$variables) {
|
||||
$comment = $variables['comment'];
|
||||
if (!empty($comment->rdf_mapping['rdftype'])) {
|
||||
// Add RDFa markup to the comment container. The about attribute specifies
|
||||
// the URI of the resource described within the HTML element, while the
|
||||
// typeof attribute indicates its RDF type (e.g. sioc:Post, etc.).
|
||||
$variables['attributes_array']['about'] = url('comment/' . $comment->cid, array('fragment' => 'comment-' . $comment->cid));
|
||||
$variables['attributes_array']['typeof'] = $comment->rdf_mapping['rdftype'];
|
||||
}
|
||||
|
||||
// RDFa markup for the date of the comment.
|
||||
if (!empty($comment->rdf_mapping['created'])) {
|
||||
$date_attributes_array = drupal_rdfa_attributes($comment->rdf_mapping['created'], $comment->created);
|
||||
$variables['rdf_variable_attributes_array']['created'] = $date_attributes_array;
|
||||
}
|
||||
if (!empty($comment->rdf_mapping['title'])) {
|
||||
// Add RDFa markup to the subject of the comment. Because the RDFa markup is
|
||||
// added to an h3 tag which might contain HTML code, we specify an empty
|
||||
// datatype to ensure the value of the title read by the RDFa parsers is a
|
||||
// literal.
|
||||
$variables['title_attributes_array']['property'] = $comment->rdf_mapping['title']['predicates'];
|
||||
$variables['title_attributes_array']['datatype'] = '';
|
||||
}
|
||||
if (!empty($comment->rdf_mapping['body'])) {
|
||||
// We need a special case here since the comment body is not a field. Note
|
||||
// that for that reason, fields attached to comment will be ignored by RDFa
|
||||
// parsers since we set the property attribute here.
|
||||
// @todo use fields instead, see http://drupal.org/node/538164
|
||||
$variables['content_attributes_array']['property'] = $comment->rdf_mapping['body']['predicates'];
|
||||
}
|
||||
|
||||
// Annotates the parent relationship between the current comment and the node
|
||||
// it belongs to. If available, the parent comment is also annotated.
|
||||
if (!empty($comment->rdf_mapping['pid'])) {
|
||||
// Relation to parent node.
|
||||
$parent_node_attributes['rel'] = $comment->rdf_mapping['pid']['predicates'];
|
||||
$parent_node_attributes['resource'] = url('node/' . $comment->nid);
|
||||
$variables['metadata_attributes_array'][] = $parent_node_attributes;
|
||||
|
||||
// Relation to parent comment if it exists.
|
||||
if ($comment->pid != 0) {
|
||||
$parent_comment_attributes['rel'] = $comment->rdf_mapping['pid']['predicates'];
|
||||
$parent_comment_attributes['resource'] = url('comment/' . $comment->pid, array('fragment' => 'comment-' . $comment->pid));
|
||||
$variables['metadata_attributes_array'][] = $parent_comment_attributes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements MODULE_preprocess_HOOK().
|
||||
*/
|
||||
function rdf_preprocess_field_formatter_taxonomy_term_link(&$variables) {
|
||||
$term = $variables['element']['#item']['taxonomy_term'];
|
||||
if (!empty($term->rdf_mapping['rdftype'])) {
|
||||
$variables['link_options']['attributes']['typeof'] = $term->rdf_mapping['rdftype'];
|
||||
}
|
||||
if (!empty($term->rdf_mapping['name']['predicates'])) {
|
||||
$variables['link_options']['attributes']['property'] = $term->rdf_mapping['name']['predicates'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default RDF mapping for the given entity type.
|
||||
*
|
||||
* @param $type
|
||||
* An entity type.
|
||||
* @return array
|
||||
* The RDF mapping or an empty array.
|
||||
*/
|
||||
function _rdf_get_default_mapping($type) {
|
||||
$default_mappings = &drupal_static(__FUNCTION__, array());
|
||||
|
||||
if (empty($default_mappings)) {
|
||||
// Get all modules implementing hook_rdf_mapping().
|
||||
$modules = module_implements('rdf_mapping');
|
||||
|
||||
// Only consider the default entity mapping definitions.
|
||||
foreach ($modules as $module) {
|
||||
$mappings = module_invoke($module, 'rdf_mapping');
|
||||
foreach ($mappings as $mapping) {
|
||||
if ($mapping['bundle'] == RDF_DEFAULT_BUNDLE) {
|
||||
$default_mappings[$mapping['type']] = $mapping['mapping'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return empty($default_mappings[$type]) ? array() : $default_mappings[$type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an RDF mapping binded to a bundle and an entity type.
|
||||
*
|
||||
* RDF CRUD API, handling RDF mapping creation and deletion.
|
||||
*
|
||||
* @param $type
|
||||
* The entity type the mapping refers to (node, user, comment, term, etc.).
|
||||
* @param $bundle
|
||||
* The bundle the mapping refers to.
|
||||
* @param $mapping
|
||||
* An associative array represeting an RDF mapping structure.
|
||||
* @return array
|
||||
* The stored mapping.
|
||||
*/
|
||||
function rdf_create_mapping($type, $bundle, $mapping) {
|
||||
$fields = array(
|
||||
'type' => $type,
|
||||
'bundle' => $bundle,
|
||||
'mapping' => serialize($mapping)
|
||||
);
|
||||
|
||||
db_insert('rdf_mapping')->fields($fields)->execute();
|
||||
|
||||
return $mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an RDF mapping record directly from the database.
|
||||
*
|
||||
* RDF CRUD API, handling RDF mapping creation and deletion.
|
||||
*
|
||||
* @param $type
|
||||
* The entity type the mapping refers to.
|
||||
* @param $bundle
|
||||
* The bundle the mapping refers to.
|
||||
* @return array
|
||||
* An RDF mapping structure or FALSE if the mapping could not be found.
|
||||
*/
|
||||
function rdf_read_mapping($type, $bundle) {
|
||||
$query = db_select('rdf_mapping')->fields(NULL, array('mapping'))
|
||||
->condition('type', $type)->condition('bundle', $bundle)->execute();
|
||||
|
||||
$mapping = unserialize($query->fetchField());
|
||||
|
||||
if (!is_array($mapping)) {
|
||||
$mapping = array();
|
||||
}
|
||||
|
||||
return $mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an RDF mapping binded to a bundle and an entity type.
|
||||
*
|
||||
* RDF CRUD API, handling RDF mapping creation and deletion.
|
||||
*
|
||||
* @param $type
|
||||
* The entity type the mapping refers to.
|
||||
* @param $bundle
|
||||
* The bundle the mapping refers to.
|
||||
* @param $mapping
|
||||
* An associative array representing an RDF mapping structure.
|
||||
* @return bool
|
||||
* Return boolean TRUE if mapping updated, FALSE if not.
|
||||
*/
|
||||
function rdf_update_mapping($type, $bundle, $mapping) {
|
||||
$fields = array('mapping' => serialize($mapping));
|
||||
$num_rows = db_update('rdf_mapping')->fields($fields)
|
||||
->condition('type', $type)->condition('bundle', $bundle)->execute();
|
||||
|
||||
return (bool) ($num_rows > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the mapping for the given pair of type and bundle from the database.
|
||||
*
|
||||
* RDF CRUD API, handling RDF mapping creation and deletion.
|
||||
*
|
||||
* @param $type
|
||||
* The entity type the mapping refers to.
|
||||
* @param $bundle
|
||||
* The bundle the mapping refers to.
|
||||
* @return bool
|
||||
* Return boolean TRUE if mapping deleted, FALSE if not.
|
||||
*/
|
||||
function rdf_delete_mapping($type, $bundle) {
|
||||
$num_rows = db_delete('rdf_mapping')->condition('type', $type)
|
||||
->condition('bundle', $bundle)->execute();
|
||||
|
||||
return (bool) ($num_rows > 0);
|
||||
}
|
|
@ -0,0 +1,193 @@
|
|||
<?php
|
||||
// $Id$
|
||||
|
||||
class RdfMappingHookTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'RDF mapping hook',
|
||||
'description' => 'Test hook_rdf_mapping().',
|
||||
'group' => 'RDF',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('rdf', 'rdf_test', 'field_test');
|
||||
// We need to trigger rdf_modules_installed() because
|
||||
// hook_modules_installed() is not automatically invoked during testing.
|
||||
rdf_modules_installed(array('rdf_test'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that hook_rdf_mapping() correctly returns and processes mapping.
|
||||
*/
|
||||
function testMapping() {
|
||||
// Test that the mapping is returned correctly by the hook.
|
||||
$mapping = rdf_get_mapping('test_entity', 'test_bundle');
|
||||
$this->assertIdentical($mapping['rdftype'], array('sioc:Post'), t('Mapping for rdftype is sioc:Post.'));
|
||||
$this->assertIdentical($mapping['title'], array('predicates' => array('dc:title')), t('Mapping for title is dc:title.'));
|
||||
$this->assertIdentical($mapping['created'], array(
|
||||
'predicates' => array('dc:created'),
|
||||
'datatype' => 'xsd:dateTime',
|
||||
'callback' => 'date_iso8601',
|
||||
), t('Mapping for created is dc:created with datatype xsd:dateTime and callback date_iso8601.'));
|
||||
$this->assertIdentical($mapping['uid'], array('predicates' => array('sioc:has_creator', 'dc:creator')), t('Mapping for uid is sioc:has_creator and dc:creator.'));
|
||||
|
||||
$mapping = rdf_get_mapping('test_entity', 'test_bundle_no_mapping');
|
||||
$this->assertEqual($mapping, array(), t('Empty array returned when an entity type, bundle pair has no mapping.'));
|
||||
}
|
||||
}
|
||||
|
||||
class RdfMarkupTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'RDFa markup',
|
||||
'description' => 'Test RDFa markup generation.',
|
||||
'group' => 'RDF',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('rdf', 'field_test', 'rdf_test');
|
||||
rdf_modules_installed(array('field_test', 'rdf_test'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test drupal_rdfa_attributes().
|
||||
*/
|
||||
function testDrupalRdfaAtributes() {
|
||||
$date = 1252750327;
|
||||
$isoDate = date('c', $date);
|
||||
|
||||
$expected_type = 'xsd:dateTime';
|
||||
$expected_property = array('dc:created');
|
||||
$expected_value = $isoDate;
|
||||
|
||||
$mapping = rdf_get_mapping('test_entity', 'test_bundle');
|
||||
$attributes = drupal_rdfa_attributes($mapping['created'], $date);
|
||||
|
||||
$this->assertEqual($expected_type, $attributes['datatype']);
|
||||
$this->assertEqual($expected_property, $attributes['property']);
|
||||
$this->assertEqual($expected_value, $attributes['content']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class RdfCrudTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'RDF mapping CRUD functions',
|
||||
'description' => 'Test the RDF mapping CRUD functions.',
|
||||
'group' => 'RDF',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('rdf', 'rdf_test');
|
||||
}
|
||||
|
||||
function testCreateReadUpdateWrite() {
|
||||
$test_mapping = rdf_test_rdf_mapping();
|
||||
|
||||
$this->assertTrue(is_array(rdf_read_mapping('test_entity', 'test_bundle')));
|
||||
$this->assertEqual(count(rdf_read_mapping('test_entity', 'test_bundle')), 0);
|
||||
$this->assertEqual(
|
||||
rdf_create_mapping('test_entity', 'test_bundle', $test_mapping[0]['mapping']),
|
||||
$test_mapping[0]['mapping']
|
||||
);
|
||||
|
||||
try {
|
||||
rdf_create_mapping('test_entity', 'test_bundle', $test_mapping[0]['mapping']);
|
||||
$this->fail('No Exception thrown when attempting to insert the same mapping another time.');
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$this->pass('Exception thrown when attempting to insert the same mapping another time.');
|
||||
}
|
||||
|
||||
$this->assertEqual($test_mapping[0]['mapping'],
|
||||
rdf_read_mapping('test_entity', 'test_bundle'));
|
||||
$this->assertTrue(rdf_update_mapping('test_entity', 'test_bundle',
|
||||
$test_mapping[1]['mapping']));
|
||||
$this->assertEqual($test_mapping[1]['mapping'],
|
||||
rdf_read_mapping('test_entity', 'test_bundle'));
|
||||
$this->assertTrue(rdf_delete_mapping('test_entity', 'test_bundle'));
|
||||
$this->assertFalse(rdf_read_mapping('test_entity', 'test_bundle'));
|
||||
}
|
||||
|
||||
function testSaveMapping() {
|
||||
$test_mapping = rdf_test_rdf_mapping();
|
||||
rdf_save_mapping($test_mapping[0]);
|
||||
|
||||
$this->assertEqual($test_mapping[0]['mapping'],
|
||||
rdf_read_mapping('test_entity', 'test_bundle'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class RdfMappingDefinitionTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'RDF mapping definition functionality',
|
||||
'description' => 'Test the different types of RDF mappings and ensure the proper RDFa markup in included in node pages.',
|
||||
'group' => 'RDF',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('rdf', 'rdf_test', 'blog');
|
||||
// We need to trigger rdf_modules_installed() because
|
||||
// hook_modules_installed() is not automatically invoked during testing.
|
||||
rdf_modules_installed(array('rdf_test', 'node'));
|
||||
// entity_info caches must be cleared during testing. This is done
|
||||
// automatically during the manual installation.
|
||||
cache_clear_all('entity_info', 'cache');
|
||||
drupal_static_reset('entity_get_info');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a node of type blog and test whether the RDF mapping defined for
|
||||
* this node type in rdf_test.module is used in the node page.
|
||||
*/
|
||||
function testAttributesInMarkup1() {
|
||||
$node = $this->drupalCreateNode(array('type' => 'blog'));
|
||||
$this->drupalGet('node/' . $node->nid);
|
||||
|
||||
$this->assertRaw('typeof="sioct:Weblog"');
|
||||
// Ensure the default bundle mapping for node is used. These attributes come
|
||||
// from the node default bundle definition.
|
||||
$this->assertRaw('property="dc:title"');
|
||||
$this->assertRaw('property="dc:date dc:created"');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a content type and a node of type test_bundle_hook_install and test
|
||||
* whether the RDF mapping defined in rdf_test.install is used.
|
||||
*/
|
||||
function testAttributesInMarkup2() {
|
||||
$type = $this->drupalCreateContentType(array('type' => 'test_bundle_hook_install'));
|
||||
$node = $this->drupalCreateNode(array('type' => 'test_bundle_hook_install'));
|
||||
$this->drupalGet('node/' . $node->nid);
|
||||
|
||||
$this->assertRaw('typeof="foo:mapping_install1 bar:mapping_install2"');
|
||||
// Ensure the default bundle mapping for node is used. These attributes come
|
||||
// from the node default bundle definition.
|
||||
$this->assertRaw('property="dc:title"');
|
||||
$this->assertRaw('property="dc:date dc:created"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a random content type and node and ensure the default mapping for
|
||||
* node is used.
|
||||
*/
|
||||
function testAttributesInMarkup3() {
|
||||
$type = $this->drupalCreateContentType();
|
||||
$node = $this->drupalCreateNode(array('type' => $type->type));
|
||||
$this->drupalGet('node/' . $node->nid);
|
||||
|
||||
$this->assertRaw('typeof="sioc:Item foaf:Document"');
|
||||
// Ensure the default bundle mapping for node is used. These attributes come
|
||||
// from the node default bundle definition.
|
||||
$this->assertRaw('property="dc:title"');
|
||||
$this->assertRaw('property="dc:date dc:created"');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
; $Id$
|
||||
name = "RDF module tests"
|
||||
description = "Support module for RDF module testing."
|
||||
package = Testing
|
||||
version = VERSION
|
||||
core = 7.x
|
||||
files[] = rdf_test.install
|
||||
files[] = rdf_test.module
|
||||
hidden = TRUE
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the rdf module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implement hook_install().
|
||||
*/
|
||||
function rdf_test_install() {
|
||||
$rdf_mappings = array(
|
||||
array(
|
||||
'type' => 'node',
|
||||
'bundle' => 'test_bundle_hook_install',
|
||||
'mapping' => array(
|
||||
'rdftype' => array('foo:mapping_install1', 'bar:mapping_install2'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
foreach ($rdf_mappings as $rdf_mapping) {
|
||||
rdf_save_mapping($rdf_mapping);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Dummy module implementing RDF related hooks to test API interaction with
|
||||
* the RDF module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of hook_rdf_mapping().
|
||||
*/
|
||||
function rdf_test_rdf_mapping() {
|
||||
return array(
|
||||
0 => array(
|
||||
'type' => 'test_entity',
|
||||
'bundle' => 'test_bundle',
|
||||
'mapping' => array(
|
||||
'rdftype' => array('sioc:Post'),
|
||||
'title' => array(
|
||||
'predicates' => array('dc:title'),
|
||||
),
|
||||
'created' => array(
|
||||
'predicates' => array('dc:created'),
|
||||
'datatype' => 'xsd:dateTime',
|
||||
'callback' => 'date_iso8601',
|
||||
),
|
||||
'uid' => array(
|
||||
'predicates' => array('sioc:has_creator', 'dc:creator'),
|
||||
),
|
||||
'foobar' => array(
|
||||
'predicates' => array('foo:bar'),
|
||||
),
|
||||
),
|
||||
),
|
||||
1 => array(
|
||||
'type' => 'node',
|
||||
'bundle' => 'blog',
|
||||
'mapping' => array(
|
||||
'rdftype' => array('sioct:Weblog'),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
|
@ -35,7 +35,7 @@
|
|||
*/
|
||||
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
|
||||
"http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language; ?>" dir="<?php print $language->dir; ?>"
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language; ?>" version="XHTML+RDFa 1.0" dir="<?php print $language->dir; ?>"
|
||||
<?php print $rdf_namespaces; ?>>
|
||||
|
||||
<head profile="<?php print $grddl_profile; ?>">
|
||||
|
|
|
@ -265,15 +265,18 @@ function system_rdf_namespaces() {
|
|||
return array(
|
||||
'admin' => 'http://webns.net/mvcb/',
|
||||
'content' => 'http://purl.org/rss/1.0/modules/content/',
|
||||
'dc' => 'http://purl.org/dc/elements/1.1/',
|
||||
'dcterms' => 'http://purl.org/dc/terms/',
|
||||
'dc' => 'http://purl.org/dc/terms/',
|
||||
'foaf' => 'http://xmlns.com/foaf/0.1/',
|
||||
'owl' => 'http://www.w3.org/2002/07/owl#',
|
||||
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
|
||||
'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
|
||||
'rss' => 'http://purl.org/rss/1.0/',
|
||||
'tags' => 'http://www.holygoat.co.uk/owl/redwood/0.1/tags/',
|
||||
'sioc' => 'http://rdfs.org/sioc/ns#',
|
||||
'xsd' => 'http://www.w3.org/2001/XMLSchema',
|
||||
'sioct' => 'http://rdfs.org/sioc/types#',
|
||||
'ctag' => 'http://commontag.org/ns#',
|
||||
'skos' => 'http://www.w3.org/2004/02/skos/core#',
|
||||
'xsd' => 'http://www.w3.org/2001/XMLSchema#',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1102,7 +1102,8 @@ function taxonomy_field_formatter_info() {
|
|||
*/
|
||||
function theme_field_formatter_taxonomy_term_link($variables) {
|
||||
$term = $variables['element']['#item']['taxonomy_term'];
|
||||
return l($term->name, taxonomy_term_path($term));
|
||||
$attributes = empty($variables['link_options']) ? array() : $variables['link_options'];
|
||||
return l($term->name, taxonomy_term_path($term), $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1405,6 +1406,47 @@ function taxonomy_field_settings_form($field, $instance, $has_data) {
|
|||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement hook_rdf_mapping().
|
||||
*
|
||||
* @return array
|
||||
* The rdf mapping for vocabularies and terms.
|
||||
*/
|
||||
function taxonomy_rdf_mapping() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'taxonomy_term',
|
||||
'bundle' => RDF_DEFAULT_BUNDLE,
|
||||
'mapping' => array(
|
||||
'rdftype' => array('skos:Concept'),
|
||||
'name' => array(
|
||||
'predicates' => array('skos:prefLabel'),
|
||||
),
|
||||
'description' => array(
|
||||
'predicates' => array('skos:definition'),
|
||||
),
|
||||
// The vocabulary this term belongs to.
|
||||
'vid' => array(
|
||||
'predicates' => array('skos:member'),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'taxonomy_vocabulary',
|
||||
'bundle' => RDF_DEFAULT_BUNDLE,
|
||||
'mapping' => array(
|
||||
'rdftype' => array('skos:Collection'),
|
||||
'name' => array(
|
||||
'predicates' => array('rdfs:label'),
|
||||
),
|
||||
'description' => array(
|
||||
'predicates' => array('rdfs:comment'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @defgroup taxonomy indexing Taxonomy functions maintaining {taxonomy_index}.
|
||||
*
|
||||
|
@ -1495,4 +1537,3 @@ function taxonomy_taxonomy_term_delete($term) {
|
|||
/**
|
||||
* @} End of "defgroup taxonomy indexing"
|
||||
*/
|
||||
|
||||
|
|
|
@ -3255,3 +3255,21 @@ function user_cookie_save(array $values, array $fields = array('name', 'mail', '
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_rdf_mapping().
|
||||
*/
|
||||
function user_rdf_mapping() {
|
||||
return array(
|
||||
array(
|
||||
'type' => 'user',
|
||||
'bundle' => RDF_DEFAULT_BUNDLE,
|
||||
'mapping' => array(
|
||||
'rdftype' => array('sioc:User'),
|
||||
'name' => array(
|
||||
'predicates' => array('foaf:name'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -18,4 +18,5 @@ dependencies[] = shortcut
|
|||
dependencies[] = toolbar
|
||||
dependencies[] = field_ui
|
||||
dependencies[] = file
|
||||
dependencies[] = rdf
|
||||
files[] = default.profile
|
||||
|
|
|
@ -166,6 +166,28 @@ function default_install() {
|
|||
node_type_save($type);
|
||||
}
|
||||
|
||||
// Insert default user-defined RDF mapping into the database.
|
||||
$rdf_mappings = array(
|
||||
array(
|
||||
'type' => 'node',
|
||||
'bundle' => 'page',
|
||||
'mapping' => array(
|
||||
'rdftype' => array('foaf:Document'),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'node',
|
||||
'bundle' => 'article',
|
||||
'mapping' => array(
|
||||
'rdftype' => array('sioc:Item', 'foaf:Document'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
foreach ($rdf_mappings as $rdf_mapping) {
|
||||
rdf_save_mapping($rdf_mapping);
|
||||
}
|
||||
|
||||
// Default page to not be promoted and have comments disabled.
|
||||
variable_set('node_options_page', array('status'));
|
||||
variable_set('comment_page', COMMENT_NODE_HIDDEN);
|
||||
|
|
Loading…
Reference in New Issue