' . t('About') . ''; $output .= '
' . t('The RDF module enriches your content with metadata to let other applications (e.g., search engines, aggregators, and so on) better understand its relationships and attributes. This semantically enriched, machine-readable output for Drupal sites uses the RDFa specification which allows RDF data to be embedded in HTML markup. Other modules can define mappings of their data to RDF terms, and the RDF module makes this RDF data available to the theme. The core Drupal modules define RDF mappings for their data model, and the core Drupal themes output this RDF metadata information along with the human-readable visual information. For more information, see the online handbook entry for RDF module.', array('@rdfa' => 'http://www.w3.org/TR/xhtml-rdfa-primer/', '@rdf' => 'http://drupal.org/documentation/modules/rdf')) . '
'; return $output; } } /** * @defgroup rdf RDF Mapping API * @{ * Functions to describe entities and bundles in RDF. * * The RDF module introduces RDF and RDFa to Drupal. RDF is a W3C standard to * describe structured data. RDF can be serialized as RDFa in XHTML attributes * to augment visual data with machine-readable hints. * @see http://www.w3.org/RDF/ * @see http://www.w3.org/TR/xhtml-rdfa-primer/ * * Modules can provide mappings of their bundles' data and metadata to RDF * classes and properties. This module takes care of injecting these mappings * into variables available to theme functions and templates. All Drupal core * themes are coded to be RDFa compatible. */ /** * Returns the RDF mapping object associated to a bundle. * * The function reads the rdf_mapping object from the current configuration, * or returns a ready-to-use empty one if no configuration entry exists yet for * this bundle. This streamlines the manipulation of mapping objects by always * returning a consistent object that reflects the current state of the * configuration. * * Example usage: * -Map the 'article' bundle to 'sioc:Post' and the 'title' field to 'dc:title'. * @code * rdf_get_mapping('node', 'article') * ->setBundleMapping(array( * 'types' => array('sioc:Post'), * )) * ->setFieldMapping('title', array( * 'properties' => array('dc:title') * )) * ->save(); * @endcode * * @param string $entity_type * The entity type. * @param string $bundle * The bundle. * * @return \Drupal\rdf\Plugin\Core\Entity\RdfMapping * The RdfMapping object. */ function rdf_get_mapping($entity_type, $bundle) { // Try loading the mapping from configuration. $mapping = entity_load('rdf_mapping', $entity_type . '.' . $bundle); // If not found, create a fresh mapping object. if (!$mapping) { $mapping = entity_create('rdf_mapping', array( 'targetEntityType' => $entity_type, 'bundle' => $bundle, )); } return $mapping; } /** * Implements hook_rdf_namespaces(). */ function rdf_rdf_namespaces() { return array( 'content' => 'http://purl.org/rss/1.0/modules/content/', 'dc' => 'http://purl.org/dc/terms/', 'foaf' => 'http://xmlns.com/foaf/0.1/', 'og' => 'http://ogp.me/ns#', 'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#', 'sioc' => 'http://rdfs.org/sioc/ns#', 'sioct' => 'http://rdfs.org/sioc/types#', 'skos' => 'http://www.w3.org/2004/02/skos/core#', 'xsd' => 'http://www.w3.org/2001/XMLSchema#', ); } /** * Retrieves RDF namespaces. * * Invokes hook_rdf_namespaces() and collects RDF namespaces from modules that * implement it. */ function rdf_get_namespaces() { $namespaces = array(); // In order to resolve duplicate namespaces by using the earliest defined // namespace, do not use module_invoke_all(). foreach (module_implements('rdf_namespaces') as $module) { $function = $module . '_rdf_namespaces'; if (function_exists($function)) { $namespaces = NestedArray::mergeDeep($function(), $namespaces); } } return $namespaces; } /** * @} End of "defgroup rdf". */ /** * @addtogroup rdf * @{ */ /** * Builds an array of RDFa attributes for a given mapping. * * This array will typically be passed through Drupal\Core\Template\Attribute * to create the attributes variables that are available to template files. * These include $attributes, $title_attributes, $content_attributes and the * field-specific $item_attributes variables. * * @param array $mapping * An array containing a mandatory 'properties' key and optional 'datatype', * 'datatype_callback' and 'type' keys. For example: * @code * array( * 'properties' => array('dc:created'), * 'datatype' => 'xsd:dateTime', * 'datatype_callback' => 'date_iso8601', * ), * ); * @endcode * @param mixed $data * (optional) A value that needs to be converted by the provided callback * function. * * @return array * RDFa attributes suitable for Drupal\Core\Template\Attribute. * * @see theme_rdf_template_variable_wrapper() */ function rdf_rdfa_attributes($mapping, $data = NULL) { $attributes = array(); // The type of mapping defaults to 'property'. $type = isset($mapping['mapping_type']) ? $mapping['mapping_type'] : 'property'; switch ($type) { // The mapping expresses the relationship between two resources. case 'rel': case 'rev': $attributes[$type] = $mapping['properties']; break; // The mapping expresses the relationship between a resource and some // literal text. case 'property': if (!empty($mapping['properties'])) { $attributes['property'] = $mapping['properties']; // Convert $data to a specific format as per the callback function. if (isset($data) && !empty($mapping['datatype_callback'])) { $callback = $mapping['datatype_callback']; $attributes['content'] = $callback($data); } if (isset($mapping['datatype'])) { $attributes['datatype'] = $mapping['datatype']; } break; } } return $attributes; } /** * @} End of "addtogroup rdf". */ /** * Implements hook_comment_load(). */ function rdf_comment_load($comments) { foreach ($comments as $comment) { // Pages with many comments can show poor performance. This information // isn't needed until rdf_preprocess_comment() is called, but set it here // to optimize performance for websites that implement an entity cache. $created_mapping = rdf_get_mapping('comment', $comment->bundle()) ->getPreparedFieldMapping('created'); $comment->rdf_data['date'] = rdf_rdfa_attributes($created_mapping, $comment->created->value); $comment->rdf_data['nid_uri'] = url('node/' . $comment->nid->target_id); if ($comment->pid->target_id) { $comment->rdf_data['pid_uri'] = url('comment/' . $comment->pid->target_id); } } } /** * Implements hook_theme(). */ function rdf_theme() { return array( 'rdf_template_variable_wrapper' => array( 'variables' => array('content' => NULL, 'attributes' => array(), 'context' => array(), 'inline' => TRUE), ), 'rdf_metadata' => array( 'variables' => array('metadata' => array()), ), ); } /** * Implements MODULE_process(). * * Template process function for adding extra tags to hold RDFa attributes. * * Since template files already have built-in support for $attributes, * $title_attributes, and $content_attributes, and field templates have support * for $item_attributes, we try to leverage those as much as possible. However, * in some cases additional attributes are needed not covered by these. We deal * with those here. */ function rdf_process(&$variables, $hook) { // Handles attributes needed for content not covered by title, content, and // field items. It does this by adjusting the variable sent to the template // so that the template doesn't have to worry about it. See // theme_rdf_template_variable_wrapper(). if (!empty($variables['rdf_template_variable_attributes'])) { foreach ($variables['rdf_template_variable_attributes'] as $variable_name => $attributes) { $context = array( 'hook' => $hook, 'variable_name' => $variable_name, 'variables' => $variables, ); $rdf_template_variable_wrapper = array( '#theme' => 'rdf_template_variable_wrapper', '#content' => $variables[$variable_name], '#attributes' => $attributes, '#context' => $context, ); $variables[$variable_name] = drupal_render($rdf_template_variable_wrapper); } } // Handles additional attributes about a template entity that for RDF parsing // reasons, can't be placed into that template's $attributes variable. This // is "meta" information that is related to particular content, so render it // close to that content. if (!empty($variables['rdf_metadata_attributes'])) { if (!isset($variables['content']['#prefix'])) { $variables['content']['#prefix'] = ''; } $rdf_metadata = array( '#theme' => 'rdf_metadata', '#metadata' => $variables['rdf_metadata_attributes'], ); $variables['content']['#prefix'] = drupal_render($rdf_metadata) . $variables['content']['#prefix']; } } /** * Implements hook_preprocess_HOOK() for html.tpl.php. */ function rdf_preprocess_html(&$variables) { // Adds RDF namespace prefix bindings in the form of an RDFa 1.1 prefix // attribute inside the html element. $prefixes = array(); if (!isset($variables['html_attributes']['prefix'])) { $variables['html_attributes']['prefix'] = array(); } foreach(rdf_get_namespaces() as $prefix => $uri) { $variables['html_attributes']['prefix'][] = $prefix . ': ' . $uri . "\n"; } } /** * Implements hook_preprocess_HOOK() for node.html.twig. */ function rdf_preprocess_node(&$variables) { // Adds 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 (e.g., foaf:Document, sioc:Person, and so // on.) $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']['typeof'] = empty($bundle_mapping['types']) ? NULL : $bundle_mapping['types']; // Adds RDFa markup to the title of the node. Because the RDFa markup is // added to the