Commit 0d8515de authored by webchick's avatar webchick

#552478 by pwolanin, samj, dropcube, and sun: Improve link/header API and...

#552478 by pwolanin, samj, dropcube, and sun: Improve link/header API and support on node/comment pages rel=canonical and rel=shortlink standards.
parent 3b2d24af
......@@ -149,6 +149,12 @@ Drupal 7.0, xxxx-xx-xx (development version)
* Modules can specify how their data structure maps to RDF.
* Added support for RDFa export of nodes, comments, terms, users, etc. and
their fields.
- Search engine optimization and web linking:
* Added a rel="canonical" link on node and comment pages to prevent
duplicate content indexing by search engines.
* Added a default rel="shortlink" link on node and comment pages that
advertises a short link as an alternative URL to third-party services.
* Meta information is now alterable by all modules before rendering.
- Field API:
* Custom data fields may be attached to nodes, users, comments and taxonomy
terms.
......
......@@ -215,7 +215,14 @@ function _batch_progress_page_nojs() {
$batch['url_options']['query']['op'] = $new_op;
$url = url($batch['url'], $batch['url_options']);
drupal_add_html_head('<meta http-equiv="Refresh" content="0; URL=' . $url . '">');
$element = array(
'#tag' => 'meta',
'#attributes' => array(
'http-equiv' => 'Refresh',
'content' => '0; URL=' . $url,
),
);
drupal_add_html_head($element, 'batch_progress_meta_refresh');
return theme('progress_bar', array('percent' => $percentage, 'message' => $message));
}
......
This diff is collapsed.
......@@ -1878,6 +1878,48 @@ function theme_feed_icon($variables) {
}
}
/**
* Generate the output for a generic HTML tag with attributes.
*
* This theme function should be used for tags appearing in the HTML HEAD of a
* document (specified via the #tag property in the passed $element):
*
* @param $variables
* An associative array containing:
* - element: An associative array describing the tag:
* - #tag: The tag name to output. Typical tags added to the HTML HEAD:
* - meta: To provide meta information, such as a page refresh.
* - link: To refer to stylesheets and other contextual information.
* - script: To load JavaScript.
* - #attributes: (optional) An array of HTML attributes to apply to the
* tag.
* - #value: (optional) A string containing tag content, such as inline CSS.
* - #value_prefix: (optional) A string to prepend to #value, e.g. a CDATA
* wrapper prefix.
* - #value_suffix: (optional) A string to append to #value, e.g. a CDATA
* wrapper suffix.
*
* @ingroup themeable
*/
function theme_html_tag($variables) {
$element = $variables['element'];
if (!isset($element['#value'])) {
return '<' . $element['#tag'] . drupal_attributes($element['#attributes']) . " />\n";
}
else {
$output = '<' . $element['#tag'] . drupal_attributes($element['#attributes']) . '>';
if (isset($element['#value_prefix'])) {
$output .= $element['#value_prefix'];
}
$output .= $element['#value'];
if (isset($element['#value_suffix'])) {
$output .= $element['#value_suffix'];
}
$output .= '</' . $element['#tag'] . ">\n";
return $output;
}
}
/**
* Returns code that emits the 'more' link used on blocks.
*
......@@ -2181,7 +2223,7 @@ function template_preprocess_html(&$variables) {
if (theme_get_setting('toggle_favicon')) {
$favicon = theme_get_setting('favicon');
$type = theme_get_setting('favicon_mimetype');
drupal_add_html_head('<link rel="shortcut icon" href="' . check_url($favicon) . '" type="' . check_plain($type) . '" />');
drupal_add_html_head_link(array('rel' => 'shortcut icon', 'href' => check_url($favicon), 'type' => $type));
}
// Construct page title.
......@@ -2350,7 +2392,7 @@ function template_preprocess_maintenance_page(&$variables) {
if (theme_get_setting('toggle_favicon')) {
$favicon = theme_get_setting('favicon');
$type = theme_get_setting('favicon_mimetype');
drupal_add_html_head('<link rel="shortcut icon" href="' . check_url($favicon) . '" type="' . check_plain($type) . '" />');
drupal_add_html_head_link(array('rel' => 'shortcut icon', 'href' => check_url($favicon), 'type' => $type));
}
global $theme;
......
......@@ -940,21 +940,21 @@ function template_preprocess_book_navigation(&$variables) {
if ($prev = book_prev($book_link)) {
$prev_href = url($prev['href']);
drupal_add_link(array('rel' => 'prev', 'href' => $prev_href));
drupal_add_html_head_link(array('rel' => 'prev', 'href' => $prev_href));
$variables['prev_url'] = $prev_href;
$variables['prev_title'] = check_plain($prev['title']);
}
if ($book_link['plid'] && $parent = book_link_load($book_link['plid'])) {
$parent_href = url($parent['href']);
drupal_add_link(array('rel' => 'up', 'href' => $parent_href));
drupal_add_html_head_link(array('rel' => 'up', 'href' => $parent_href));
$variables['parent_url'] = $parent_href;
$variables['parent_title'] = check_plain($parent['title']);
}
if ($next = book_next($book_link)) {
$next_href = url($next['href']);
drupal_add_link(array('rel' => 'next', 'href' => $next_href));
drupal_add_html_head_link(array('rel' => 'next', 'href' => $next_href));
$variables['next_url'] = $next_href;
$variables['next_title'] = check_plain($next['title']);
}
......
......@@ -362,9 +362,6 @@ function comment_permalink($comment) {
$_GET['q'] = 'node/' . $node->nid;
$_GET['page'] = $page;
// Set the node path as the canonical URL to prevent duplicate content.
drupal_add_link(array('rel' => 'canonical', 'href' => url('node/' . $node->nid)));
// Return the node view, this will show the correct comment in context.
return menu_execute_active_handler('node/' . $node->nid, FALSE);
}
......
......@@ -2152,6 +2152,10 @@ function node_page_view(stdClass $node) {
if (isset($return['nodes'][$node->nid]['title'])) {
drupal_set_title($return['nodes'][$node->nid]['title']['items'][0]['#item']['value']);
}
// Set the node path as the canonical URL to prevent duplicate content.
drupal_add_html_head_link(array('rel' => 'canonical', 'href' => url('node/' . $node->nid)), TRUE);
// Set the non-aliased path as a default shortlink.
drupal_add_html_head_link(array('rel' => 'shortlink', 'href' => url('node/' . $node->nid, array('alias' => TRUE))), TRUE);
return $return;
}
......
......@@ -97,7 +97,14 @@ function openid_test_yadis_x_xrds_location() {
* Menu callback; regular HTML page with <meta> element.
*/
function openid_test_yadis_http_equiv() {
drupal_add_html_head('<meta http-equiv="X-XRDS-Location" content="' . url('openid-test/yadis/xrds', array('absolute' => TRUE)) . '" />');
$element = array(
'#tag' => 'meta',
'#attributes' => array(
'http-equiv' => 'X-XRDS-Location',
'content' => url('openid-test/yadis/xrds', array('absolute' => TRUE)),
),
);
drupal_add_html_head($element, 'openid_test_yadis_http_equiv');
return t('This page includes a &lt;meta equiv=...&gt; element containing the URL of an XRDS document.');
}
......@@ -105,7 +112,7 @@ function openid_test_yadis_http_equiv() {
* Menu callback; regular HTML page with OpenID 1.0 <link> element.
*/
function openid_test_html_openid1() {
drupal_add_html_head('<link rel="openid.server" href="' . url('openid-test/endpoint', array('absolute' => TRUE)) . '" />');
drupal_add_html_head_link(array('rel' => 'openid.server', 'href' => url('openid-test/endpoint', array('absolute' => TRUE))));
return t('This page includes a &lt;link rel=...&gt; element containing the URL of an OpenID Provider Endpoint.');
}
......@@ -113,7 +120,7 @@ function openid_test_html_openid1() {
* Menu callback; regular HTML page with OpenID 2.0 <link> element.
*/
function openid_test_html_openid2() {
drupal_add_html_head('<link rel="openid2.provider" href="' . url('openid-test/endpoint', array('absolute' => TRUE)) . '" />');
drupal_add_html_head_link(array('rel' => 'openid2.provider', 'href' => url('openid-test/endpoint', array('absolute' => TRUE))));
return t('This page includes a &lt;link rel=...&gt; element containing the URL of an OpenID Provider Endpoint.');
}
......
......@@ -384,10 +384,17 @@ function rdf_preprocess_node(&$variables) {
// 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) . ' />');
$element = array(
'#tag' => 'meta',
'#attributes' => array(
'content' => $variables['node_title'],
'about' => $variables['node_url'],
),
);
if (!empty($variables['node']->rdf_mapping['title']['predicates'])) {
$element['#attributes']['property'] = $variables['node']->rdf_mapping['title']['predicates'];
}
drupal_add_html_head($element, 'rdf_node');
}
// Adds RDFa markup for the date.
......
......@@ -57,7 +57,14 @@ function browser_test_print_post_form_submit($form, &$form_state) {
function browser_test_refresh_meta() {
if (!isset($_GET['refresh'])) {
$url = url('browser_test/refresh/meta', array('absolute' => TRUE, 'query' => array('refresh' => 'true')));
drupal_add_html_head('<meta http-equiv="Refresh" content="0; URL=' . $url . '">');
$element = array(
'#tag' => 'meta',
'#attributes' => array(
'http-equiv' => 'Refresh',
'content' => '0; URL=' . $url,
),
);
drupal_add_html_head($element, 'browser_test_refresh_meta');
return '';
}
echo 'Refresh successful';
......
......@@ -530,7 +530,7 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
$css_preprocessed = '<style type="text/css">' . drupal_load_stylesheet_content($css, TRUE) . '</style>';
drupal_add_css($css, 'inline');
$styles = drupal_get_css();
$this->assertEqual($styles, "\n" . $css_preprocessed, t('Rendering preprocessed inline CSS adds it to the page.'));
$this->assertEqual($styles, "\n" . $css_preprocessed . "\n", t('Rendering preprocessed inline CSS adds it to the page.'));
}
/**
......
......@@ -2281,6 +2281,27 @@ function hook_drupal_goto_alter(&$path, &$options, &$http_response_code) {
$http_response_code = 500;
}
/**
* Alter XHTML HEAD tags before they are rendered by drupal_get_html_head().
*
* Elements available to be altered are only those added using
* drupal_add_html_head_link() or drupal_add_html_head(). CSS and JS files
* are handled using drupal_add_css() and drupal_add_js(), so the head links
* for those files will not appear in the $head_elements array.
*
* @param $head_elements
* An array of renderable elements. Generally the values of the #attributes
* array will be the most likely target for changes.
*/
function hook_html_head_alter(&$head_elements) {
foreach($head_elements as $key => $element) {
if (isset($element['#attributes']['rel']) && $element['#attributes']['rel'] == 'canonical') {
// I want a custom canonical url.
$head_elements[$key]['#attributes']['href'] = mymodule_canonical_url();
}
}
}
/**
* Alter the full list of installation tasks.
*
......
......@@ -179,12 +179,6 @@ function system_theme() {
'system_powered_by' => array(
'variables' => array(),
),
'meta_generator_html' => array(
'variables' => array('version' => NULL),
),
'meta_generator_header' => array(
'variables' => array('version' => NULL),
),
'system_compact_link' => array(
'variables' => array(),
),
......@@ -318,6 +312,12 @@ function system_element_info() {
'#ajax_commands' => array(),
);
$types['html_tag'] = array(
'#theme' => 'html_tag',
'#attributes' => array(),
'#value' => NULL,
);
// Input elements.
$types['submit'] = array(
'#input' => TRUE,
......@@ -1717,22 +1717,6 @@ function system_init() {
}
}
/**
* Implement MODULE_preprocess_HOOK().
*/
function system_preprocess_page(&$variables) {
// Get the major version
list($version, ) = explode('.', VERSION);
// Emit the META tag in the HTML HEAD section
theme('meta_generator_html', array('version' => $version));
// Emit the HTTP Header too
theme('meta_generator_header', array('version' => $version));
$variables['head'] = drupal_get_html_head();
}
/**
* Implement hook_form_FORM_ID_alter().
*/
......@@ -2973,24 +2957,6 @@ function theme_system_compact_link() {
return $output;
}
/**
* Send Drupal and the major version number in the META GENERATOR HTML.
*
* @ingroup themeable
*/
function theme_meta_generator_html($variables) {
drupal_add_html_head('<meta name="Generator" content="Drupal ' . $variables['version'] . ' (http://drupal.org)" />');
}
/**
* Send Drupal and the major version number in the HTTP headers.
*
* @ingroup themeable
*/
function theme_meta_generator_header($variables) {
drupal_add_http_header('X-Generator', 'Drupal ' . $variables['version'] . ' (http://drupal.org)');
}
/**
* Implement hook_image_toolkits().
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment