--- url\url.module 2012-09-16 03:21:01.144530000 +0200
+++ link\link.module 2012-09-16 19:48:03.613652100 +0200
@@ -2,18 +2,18 @@
/**
* @file
- * Provides a URL field type that stores external links with optional titles.
+ * Defines simple link field types.
*/
/**
* Implements hook_help().
*/
-function url_help($path, $arg) {
+function link_help($path, $arg) {
switch ($path) {
- case 'admin/help#url':
+ case 'admin/help#link':
$output = '';
$output .= '
' . t('About') . '
';
- $output .= '' . t('The URL module defines a simple link field type for the Field module. Links are external URLs, can have an optional title for each link, and they can be formatted when displayed. See the Field module help page for more information about fields.', array('@field-help' => url('admin/help/field'))) . '
';
+ $output .= '' . t('The Link module defines a simple link field type for the Field module. Links are external URLs, can have an optional title for each link, and they can be formatted when displayed. See the Field module help page for more information about fields.', array('@field-help' => url('admin/help/field'))) . '
';
return $output;
}
}
@@ -21,46 +21,40 @@ function url_help($path, $arg) {
/**
* Implements hook_field_info().
*/
-function url_field_info() {
- $info['url'] = array(
- 'label' => t('URL'),
- 'description' => t('This field stores URLs with an optional title.'),
+function link_field_info() {
+ $types['link'] = array(
+ 'label' => t('Link'),
+ 'description' => t('Stores a URL string, optional varchar title, and optional blob of attributes to assemble a link.'),
'instance_settings' => array(
- 'title_field' => 0,
- 'title_fetch' => 0,
+ 'title' => DRUPAL_OPTIONAL,
),
- 'default_widget' => 'url_external',
- 'default_formatter' => 'url_default',
+ 'default_widget' => 'link_default',
+ 'default_formatter' => 'link',
);
-
- return $info;
+ return $types;
}
/**
* Implements hook_field_instance_settings_form().
*/
-function url_field_instance_settings_form($field, $instance) {
- $settings = $instance['settings'];
-
- $form['title_field'] = array(
- '#type' => 'checkbox',
- '#title' => t('Enable Title field'),
- '#default_value' => $settings['title_field'],
- '#description' => t('The title attribute is displayed when the link is displayed.'),
- );
- $form['title_fetch'] = array(
- '#type' => 'checkbox',
- '#title' => t('Attempt to fetch the title value from the URL if the Title field is empty.'),
- '#default_value' => $settings['title_fetch'],
+function link_field_instance_settings_form($field, $instance) {
+ $form['title'] = array(
+ '#type' => 'radios',
+ '#title' => t('Allow link title'),
+ '#default_value' => isset($instance['settings']['title']) ? $instance['settings']['title'] : DRUPAL_OPTIONAL,
+ '#options' => array(
+ DRUPAL_DISABLED => t('Disabled'),
+ DRUPAL_OPTIONAL => t('Optional'),
+ DRUPAL_REQUIRED => t('Required'),
+ ),
);
-
return $form;
}
/**
* Implements hook_field_load().
*/
-function url_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
+function link_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
foreach ($entities as $id => $entity) {
foreach ($items[$id] as $delta => &$item) {
// Unserialize the attributes into an array. The value stored in the
@@ -78,27 +72,17 @@ function url_field_load($entity_type, $e
/**
* Implements hook_field_is_empty().
*/
-function url_field_is_empty($item, $field) {
- return !isset($item['value']) || $item['value'] === '';
+function link_field_is_empty($item, $field) {
+ return !isset($item['url']) || $item['url'] === '';
}
/**
* Implements hook_field_presave().
*/
-function url_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
- $settings = $instance['settings'];
-
+function link_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
foreach ($items as $delta => &$item) {
- // If the link title is empty, and auto-fetching is enabled, then attempt
- // to extract the title from a request to the URL.
- if (!empty($settings['title_fetch']) && !empty($item['value']) && empty($item['title'])) {
- // Parse the URL into a form ready for url().
- $parsed = drupal_parse_url($item['value']);
- $url = url($parsed['path'], array('query' => $parsed['query'], 'fragment' => $parsed['fragment']));
- $item['title'] = url_fetch_title($url);
- }
-
- // Trim any spaces around the URL title.
+ // Trim any spaces around the URL and title.
+ $item['url'] = trim($item['url']);
$item['title'] = trim($item['title']);
// Serialize the attributes array.
@@ -109,92 +93,74 @@ function url_field_presave($entity_type,
/**
* Implements hook_field_widget_info().
*/
-function url_field_widget_info() {
- $info['url_external'] = array(
- 'label' => t('External URL field'),
- 'field types' => array('url'),
- 'settings' => array('size' => 60),
- );
-
- return $info;
-}
-
-/**
- * Implements hook_field_widget_settings_form().
- */
-function url_field_widget_settings_form($field, $instance) {
- $widget = $instance['widget'];
- $settings = $widget['settings'];
-
- $form['size'] = array(
- '#type' => 'number',
- '#title' => t('Size of URL field'),
- '#default_value' => $settings['size'],
- '#required' => TRUE,
- '#min' => 1,
- '#weight' => -1,
+function link_field_widget_info() {
+ $widgets['link_default'] = array(
+ 'label' => 'Link',
+ 'field types' => array('link'),
);
-
- return $form;
+ return $widgets;
}
/**
* Implements hook_field_widget_form().
*/
-function url_field_widget_form($form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
+function link_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$settings = $instance['settings'];
- // Display this element in a fieldset if there is only one value.
- if ($field['cardinality'] == 1) {
- $element['#type'] = 'fieldset';
- }
-
- // URL field value.
- $element['value'] = array(
+ $element['url'] = array(
'#type' => 'url',
'#title' => t('URL'),
- '#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : '',
- '#size' => $instance['widget']['settings']['size'],
+ '#default_value' => isset($items[$delta]['url']) ? $items[$delta]['url'] : NULL,
'#maxlength' => 2048,
- '#required' => !empty($element['#required']),
- '#prefix' => '',
- '#suffix' => '
',
- );
-
- // Title field value.
- if (!empty($settings['title_field'])) {
- $element['title'] = array(
- '#type' => 'textfield',
- '#title' => t('Title'),
- '#default_value' => isset($items[$delta]['title']) ? $items[$delta]['title'] : '',
- '#maxlength' => 1024,
- '#weight' => 10,
- '#prefix' => '',
- '#suffix' => '
',
- );
-
- // Add additional styling to make both fields work together visually.
- $element['#attached']['css'][] = drupal_get_path('module', 'url') . '/url.field.css';
+ '#required' => $element['#required'],
+ );
+ $element['title'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Title'),
+ '#default_value' => isset($items[$delta]['title']) ? $items[$delta]['title'] : NULL,
+ '#maxlength' => 255,
+ '#access' => $settings['title'] != DRUPAL_DISABLED,
+ );
+ // Post-process the title field to make it conditionally required if URL is
+ // non-empty. Omit the validation on the field edit form, since the field
+ // settings cannot be saved otherwise.
+ $is_field_edit_form = ($element['#entity'] === NULL);
+ if (!$is_field_edit_form && $settings['title'] == DRUPAL_REQUIRED) {
+ $element['#element_validate'][] = 'link_field_widget_validate_title';
}
// Exposing the attributes array in the widget is left for alternate and more
// advanced field widgets.
$element['attributes'] = array(
'#type' => 'value',
+ '#tree' => TRUE,
'#value' => !empty($items[$delta]['attributes']) ? $items[$delta]['attributes'] : array(),
+ '#attributes' => array('class' => array('link-field-widget-attributes')),
);
return $element;
}
/**
+ * Form element validation handler for link_field_widget_form().
+ *
+ * Conditionally requires the link title if a URL value was filled in.
+ */
+function link_field_widget_validate_title(&$element, &$form_state, $form) {
+ if ($element['url']['#value'] !== '' && $element['title']['#value'] === '') {
+ $element['title']['#required'] = TRUE;
+ form_error($element['title'], t('!name field is required.', array('!name' => $element['title']['#title'])));
+ }
+}
+
+/**
* Implements hook_field_prepare_view().
*/
-function url_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) {
+function link_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) {
foreach ($entities as $id => $entity) {
foreach ($items[$id] as $delta => &$item) {
// Split out the link into the parts required for url(): path and options.
- $parsed = drupal_parse_url($item['value']);
+ $parsed = drupal_parse_url($item['url']);
$item['path'] = $parsed['path'];
$item['options'] = array(
'query' => $parsed['query'],
@@ -208,39 +174,74 @@ function url_field_prepare_view($entity_
/**
* Implements hook_field_formatter_info().
*/
-function url_field_formatter_info() {
- $info['url_default'] = array(
+function link_field_formatter_info() {
+ $formatters['link'] = array(
'label' => t('Link'),
- 'field types' => array('url'),
+ 'field types' => array('link'),
'settings' => array(
'trim_length' => 80,
- 'nofollow' => FALSE,
+ 'rel' => NULL,
+ 'target' => NULL,
+ 'url_only' => FALSE,
+ 'url_plain' => FALSE,
),
);
-
- return $info;
+ $formatters['link_separate'] = array(
+ 'label' => t('Separate title and URL'),
+ 'field types' => array('link'),
+ 'settings' => array(
+ 'trim_length' => 80,
+ 'rel' => NULL,
+ 'target' => NULL,
+ ),
+ );
+ return $formatters;
}
/**
* Implements hook_field_formatter_settings_form().
*/
-function url_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
+function link_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$element['trim_length'] = array(
'#type' => 'number',
- '#title' => t('Trim the link text to certain number of characters'),
- '#description' => t('To leave long link text alone, leave blank.'),
+ '#title' => t('Trim link text length'),
+ '#field_suffix' => t('characters'),
'#default_value' => $settings['trim_length'],
'#min' => 1,
+ '#description' => t('Leave blank to allow unlimited link text lengths.'),
);
-
- $element['nofollow'] = array(
+ $element['url_only'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('URL only'),
+ '#default_value' => $settings['url_only'],
+ '#access' => $display['type'] == 'link',
+ );
+ $element['url_plain'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Show URL as plain text'),
+ '#default_value' => $settings['url_plain'],
+ '#access' => $display['type'] == 'link',
+ '#states' => array(
+ 'visible' => array(
+ ':input[name*="url_only"]' => array('checked' => TRUE),
+ ),
+ ),
+ );
+ $element['rel'] = array(
'#type' => 'checkbox',
- '#title' => t('Add rel="nofollow" to all links'),
+ '#title' => t('Add rel="nofollow" to links'),
+ '#return_value' => 'nofollow',
'#default_value' => $settings['nofollow'],
);
+ $element['target'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Open link in new window'),
+ '#return_value' => '_blank',
+ '#default_value' => $settings['target'],
+ );
return $element;
}
@@ -248,21 +249,31 @@ function url_field_formatter_settings_fo
/**
* Implements hook_field_formatter_settings_form().
*/
-function url_field_formatter_settings_summary($field, $instance, $view_mode) {
+function link_field_formatter_settings_summary($field, $instance, $view_mode) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$summary = array();
if (!empty($settings['trim_length'])) {
- $summary[] = t('Link text trimmed to @char characters.', array('@char' => $settings['trim_length']));
+ $summary[] = t('Link text trimmed to @limit characters', array('@limit' => $settings['trim_length']));
}
else {
- $summary[] = t('Link text not trimmed.');
+ $summary[] = t('Link text not trimmed');
}
-
- if (!empty($settings['nofollow'])) {
- $summary[] = t('Add rel="nofollow"');
+ if (!empty($settings['url_only'])) {
+ if (!empty($settings['url_plain'])) {
+ $summary[] = t('Show URL only as plain-text');
+ }
+ else {
+ $summary[] = t('Show URL only');
+ }
+ }
+ if (!empty($settings['rel'])) {
+ $summary[] = t('Add rel="@rel"', array('@rel' => $settings['rel']));
+ }
+ if (!empty($settings['target'])) {
+ $summary[] = t('Open link in new window');
}
return implode('
', $summary);
@@ -271,15 +282,18 @@ function url_field_formatter_settings_su
/**
* Implements hook_field_formatter_prepare_view().
*/
-function url_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
+function link_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
foreach ($entities as $id => $entity) {
$settings = $displays[$id]['settings'];
foreach ($items[$id] as $delta => &$item) {
- // If the formatter is configured to add rel="nofollow" to links, then
- // add them here.
- if (!empty($settings['nofollow'])) {
- $item['options']['attributes']['rel'] = 'nofollow';
+ // Add optional 'rel' attribute to link options.
+ if (!empty($settings['rel'])) {
+ $item['options']['attributes']['rel'] = $settings['rel'];
+ }
+ // Add optional 'target' attribute to link options.
+ if (!empty($settings['target'])) {
+ $item['options']['attributes']['target'] = $settings['target'];
}
}
}
@@ -288,17 +302,16 @@ function url_field_formatter_prepare_vie
/**
* Implements hook_field_formatter_view().
*/
-function url_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
+function link_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
- $intance_settings = $instance['settings'];
$settings = $display['settings'];
foreach ($items as $delta => $item) {
// By default use the full URL as the link title.
- $link_title = $item['value'];
+ $link_title = $item['url'];
// If the title field value is available, use it for the link title.
- if (!empty($item['title'])) {
+ if (empty($settings['url_only']) && !empty($item['title'])) {
// Unsanitizied token replacement here because $options['HTML'] is FALSE
// by default in theme_link().
$link_title = token_replace($item['title'], array($entity_type => $entity), array('sanitize' => FALSE, 'clear' => TRUE));
@@ -309,32 +322,55 @@ function url_field_formatter_view($entit
$link_title = truncate_utf8($link_title, $settings['trim_length'], FALSE, TRUE);
}
- $element[$delta] = array(
- '#type' => 'link',
- '#title' => $link_title,
- '#href' => $item['path'],
- '#options' => $item['options'],
- );
+ if ($display['type'] == 'link') {
+ if (!empty($settings['url_only']) && !empty($settings['url_plain'])) {
+ $element[$delta] = array(
+ '#type' => 'markup',
+ '#markup' => check_plain($link_title),
+ );
+ }
+ else {
+ $element[$delta] = array(
+ '#type' => 'link',
+ '#title' => $link_title,
+ '#href' => $item['path'],
+ '#options' => $item['options'],
+ );
+ }
+ }
+ elseif ($display['type'] == 'link_separate') {
+ $element[$delta] = array(
+ '#theme' => 'link_formatter_link_separate',
+ '#title' => $link_title,
+ '#href' => $item['path'],
+ '#options' => $item['options'],
+ );
+ }
}
-
return $element;
}
/**
- * Return the HTML title from an URL.
- *
- * @param string $url
- * An URL to request with drupal_http_request().
- *
- * @return string
- * The HTML title of the URL if found.
+ * Implements hook_theme().
*/
-function url_fetch_title($url) {
- $request = drupal_http_request($url);
- if (empty($request->error) && $request->code == 200 && !empty($request->data)) {
- if (preg_match('!(.*?)!i', $request->data, $matches)) {
- // Title tags should be encoded, but we want the raw value.
- return decode_entities($matches[1]);
- }
- }
+function link_theme() {
+ return array(
+ 'link_formatter_link_separate' => array(
+ 'variables' => array('title' => NULL, 'href' => NULL, 'options' => array()),
+ ),
+ );
+}
+
+/**
+ * Formats a link as separate title and URL elements.
+ */
+function theme_link_formatter_link_separate($vars) {
+ $output = '';
+ $output .= '';
+ if (!empty($vars['title'])) {
+ $output .= '
' . check_plain($vars['title']) . '
';
+ }
+ $output .= '
' . l($vars['href'], $vars['href'], $vars['options']) . '
';
+ $output .= '
';
+ return $output;
}