[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/ed_readmore/ -> ed_readmore.module (source)

   1  <?php
   2  // $Id: ed_readmore.module,v 1.5.8.2.2.11.2.13 2009/11/24 06:51:46 toddnienkerk Exp $
   3  
   4  /**
   5   * @file
   6   * Customize the "Read more" link shown in teasers.
   7   *
   8   * Project homepage:
   9   * http://drupal.org/project/ed_readmore
  10   *
  11   * This provides the customization described at:
  12   * http://www.angrydonuts.com/the_nuisance_of_the_read_more_fl
  13   *
  14   * Conversion from 4.7 to 5.x done by themoebius (zacwitte@gmail.com)
  15   * Conversion from 5.x to 6.x done by Exodus Development and tomaszx
  16   *   (tomaszx provided initial conversion and patches -- thanks!)
  17   * 6.x bug fixes, UI/theme improvements, and added functionality by Four Kitchens
  18   *
  19   * Exodus Development
  20   * http://exodusdev.com
  21   * exodusdev@gmail.com
  22   *
  23   * Four Kitchens
  24   * http://fourkitchens.com
  25   * shout@fourkitchens.com
  26   */
  27  
  28  
  29  define('ED_READMORE_PLACEMENT_DEFAULT', 'inline');
  30  define('ED_READMORE_TEXT_DEFAULT', t('<strong>Read more &raquo;</strong>'));
  31  define('ED_READMORE_TITLE_DEFAULT', t('Read the whole post'));
  32  define('ED_READMORE_SEPARATOR_DEFAULT', '');
  33  
  34  
  35  /**
  36   * Implementation of hook_menu().
  37   */
  38  function ed_readmore_menu() {
  39    $items['admin/settings/ed_readmore'] = array(
  40      'title' => 'Read More link',
  41      'description' => 'Configures the <strong>Read More</strong> link that appears in node teasers.',
  42      'page callback' => 'drupal_get_form',
  43      'page arguments' => array('ed_readmore_admin_settings'),
  44      'access arguments' => array('administer site configuration'),
  45      'type' => MENU_NORMAL_ITEM,
  46    );
  47    return $items;
  48  }
  49  
  50  
  51  /**
  52   * Displays the settings form.
  53   */
  54  function ed_readmore_admin_settings() {
  55    $form = array();
  56  
  57    $elements = array(
  58      'address'    => '<address>',
  59      'blockquote' => '<blockquote>',
  60      'cite'       => '<cite>',
  61      'div'        => '<div>',
  62      'h1'         => '<h1>',
  63      'h2'         => '<h2>',
  64      'h3'         => '<h3>',
  65      'h4'         => '<h4>',
  66      'h5'         => '<h5>',
  67      'h6'         => '<h6>',
  68      'p'          => '<p>',
  69      'span'       => '<span>',
  70    );
  71  
  72    $form['ed_readmore_display'] = array(
  73      '#type' => 'fieldset',
  74      '#title' => t('Read More link display options'),
  75      '#collapsible' => FALSE,
  76    );
  77      $form['ed_readmore_display']['ed_readmore_remove'] = array(
  78        '#type' => 'checkbox',
  79        '#title' => t('Remove Read More link from links section'),
  80        '#default_value' => variable_get('ed_readmore_remove', TRUE),
  81        '#description' => t('Enabling this option will remove Drupal\'s default Read More link from the node links (the <code>$links</code> output).'),
  82      );
  83      $form['ed_readmore_display']['ed_readmore_placement'] = array(
  84        '#type' => 'radios',
  85        '#title' => t('Link placement'),
  86        '#options' => array(
  87          'inline'  => t('Inline: Try to add the Read More link after the last word of the teaser. If this fails, add the link on a new line after the teaser.'),
  88          'after'   => t('On a new line: Add the Read More link on a new line after the teaser.'),
  89          'disable' => t('Disable the link: Do not add a Read More link to the teaser.'),
  90        ),
  91        '#default_value' => variable_get('ed_readmore_placement', ED_READMORE_PLACEMENT_DEFAULT),
  92        '#description' => t('The inline option will attempt to add the Read More link after the last word of the teaser and before any CCK fields. The HTML elements into which the Read More link may be inserted can be chosen in the "Advanced options for inline placement" interface below.'),
  93      );
  94      $form['ed_readmore_display']['ed_readmore_placement_advanced'] = array(
  95        '#type' => 'fieldset',
  96        '#title' => t('Advanced options for inline placement'),
  97        '#collapsible' => TRUE,
  98        '#collapsed' => TRUE,
  99      );
 100        $form['ed_readmore_display']['ed_readmore_placement_advanced']['ed_readmore_elements'] = array(
 101          '#type' => 'select',
 102          '#title' => t('Elements eligible for inline placement'),
 103          '#description' => t('Select the elements into which the Read More link may be inserted. The "Inline" placement option must be selected above.'),
 104          '#multiple' => TRUE,
 105          '#options' => $elements,
 106          '#default_value' => variable_get('ed_readmore_elements', array('p')),
 107          '#size' => 10,
 108        );
 109  
 110    $form['ed_readmore_formatting'] = array(
 111      '#type' => 'fieldset',
 112      '#title' => t('Read More link formatting and attributes'),
 113      '#collapsible' => FALSE,
 114    );
 115      $form['ed_readmore_formatting']['ed_readmore_text'] = array(
 116        '#type' => 'textfield',
 117        '#title' =>  t('Link text'),
 118        '#default_value' => variable_get('ed_readmore_text', ED_READMORE_TEXT_DEFAULT),
 119        '#description' => t('Enter the text you wish to display in the Read More link. The following HTML is allowed: <code>em</code>, <code>i</code>, <code>strong</code>, <code>b</code>, <code>cite</code>, <code>code</code>, <code>span</code>, <code>font</code>. Special characters should be encoded (like %raquo or %amp). Spaces will be changed to non-breaking spaces (%nbsp).', array('%raquo' => '&raquo;', '%amp' => '&amp;', '%nbsp' => '&nbsp;')),
 120        '#required' => TRUE,
 121      );
 122      $form['ed_readmore_formatting']['ed_readmore_title'] = array(
 123        '#type' => 'textfield',
 124        '#title' => t('Link title'),
 125        '#default_value' => variable_get('ed_readmore_title', ED_READMORE_TITLE_DEFAULT),
 126        '#description' => t('Enter the text you wish to be used as the title for the Read More link (the value of the %title attribute). It is used for accessibility and search engine optimization purposes and appears as a tooltip in some browsers.', array('%title' => 'title=""')),
 127        '#required' => FALSE,
 128      );
 129      if (module_exists('token')) {
 130        $form['ed_readmore_formatting']['tokens'] = array(
 131          '#type' => 'fieldset',
 132          '#collapsible' => TRUE,
 133          '#collapsed' => TRUE,
 134          '#title' => t('Placeholder tokens'),
 135          '#description' => t('The following placeholder tokens can be used in the Read More link text and title. They will be replaced with the appropriate values.'),
 136        );
 137        $form['ed_readmore_formatting']['tokens']['ed_readmore_tokens'] = array(
 138          '#type' => 'checkbox',
 139          '#title' => t('Enable placeholder tokens'),
 140          '#default_value' => variable_get('ed_readmore_tokens', TRUE),
 141          '#description' => t('This option will allow you to use the placeholder tokens listed below.'),
 142        );
 143        $form['ed_readmore_formatting']['tokens']['help'] = array(
 144          '#value' => theme('token_help', 'node'),
 145        );
 146        // Add Token-specific help text
 147        $token_description = t('<a href="@tokens">Tokens</a> are supported if you enable them below.', array('@tokens' => url('http://drupal.org/project/token')));
 148        $form['ed_readmore_formatting']['ed_readmore_text']['#description'] .= ' ' . $token_description;
 149        $form['ed_readmore_formatting']['ed_readmore_title']['#description'] .= ' ' . $token_description;
 150      }
 151      $form['ed_readmore_formatting']['ed_readmore_nofollow'] = array(
 152        '#type' => 'checkbox',
 153        '#title' => t('Make link nofollow'),
 154        '#default_value' => variable_get('ed_readmore_nofollow', TRUE),
 155        '#description' => t('Adds %nofollow to the link\'s attributes. Often used for search engine optimization purposes.', array('%nofollow' => 'rel="nofollow"')),
 156      );
 157      $form['ed_readmore_formatting']['ed_readmore_separator'] = array(
 158        '#type' => 'textfield',
 159        '#title' => t('Separator'),
 160        '#description' => t('Enter the text you wish to be inserted between the teaser and the Read More link when the link is displayed inline. If you enter nothing, the link will be separated using a space character. May contain HTML. Special characters should be encoded (like %nbsp or %raquo). ', array('%nbsp' => '&nbsp;', '%raquo' => '&raquo;')),
 161        '#default_value' => variable_get('ed_readmore_separator', ED_READMORE_SEPARATOR_DEFAULT),
 162      );
 163  
 164    return system_settings_form($form);
 165  }
 166  
 167  
 168  /**
 169   * Implementation of hook_link_alter().
 170   */
 171  function ed_readmore_link_alter(&$links, $node) {
 172    // Remove the link from the node's $links output if the option is enabled
 173    if (variable_get('ed_readmore_remove', TRUE)) {
 174      unset($links['node_read_more']);
 175    }
 176  }
 177  
 178  
 179  /**
 180   * Implementation of template_preprocess_node().
 181   */
 182  function ed_readmore_preprocess_node(&$variables) {
 183    $display = variable_get('ed_readmore_placement', ED_READMORE_PLACEMENT_DEFAULT);
 184  
 185    // Don't do anything if placing the link is disabled
 186    if ($display != 'disable') {
 187      // Check to make sure that this is a teaser and there's actually more to read
 188      if ($variables['teaser'] && $variables['readmore']) {
 189        $variables['content'] = ed_readmore_link_place($variables['content'], $variables['node'], $display);
 190      }
 191    }
 192  }
 193  
 194  
 195  /**
 196   * Place the "Read more" link in the correct location in the teaser.
 197   *
 198   * @param $teaser
 199   *   The teaser to place the "Read more" link into.
 200   * @param $link
 201   *   The node containing information necessary to generate a link.
 202   * @param $display
 203   *   Link display mode: inline, after, or disable.
 204   *   If 'inline,' try to insert into teaser. If 'added,' just add after the teaser.
 205   */
 206  function ed_readmore_link_place($teaser, $node, $display) {
 207    if ($display == 'inline') {
 208      $elements_array = variable_get('ed_readmore_elements', array('p'));
 209      $elements = '(?:'. implode('|', $elements_array) .')';
 210  
 211      // Get last position of the last closing marker in teaser
 212      if (preg_match('!</?'. $elements .'[^>]*>$!i', $node->content['body']['#value'], $match, PREG_OFFSET_CAPTURE)) {
 213        // Recalculate the position in $teaser. We do this because there may be extra CCK fields appended to the teaser.
 214        $insert_point = strpos($teaser, $node->content['body']['#value']) + $match[0][1];
 215        // Insert the link
 216        $teaser = substr_replace($teaser, ed_readmore_link_render($node, $display), $insert_point, 0);
 217      }
 218      else {
 219        $display = 'after';
 220        $teaser .= ed_readmore_link_render($node, $display); // Not found, so just append it
 221      }
 222    }
 223    else {
 224      $teaser .= ed_readmore_link_render($node, $display); // Not inline, so just append it
 225    }
 226  
 227    return $teaser;
 228  }
 229  
 230  
 231  /**
 232   * Prepares the link for theming and returns a rendered link.
 233   *
 234   * XSS checking and other safety measures are performed here to prevent
 235   * themers from omitting them.
 236   */
 237  function ed_readmore_link_render($node, $display = 'inline') {
 238    // Filter link text for cross-site scripting (XSS)
 239    // Replace spaces with non-breaking entities to prevent a wrapping in the link
 240    $allowed_tags = array('em', 'i', 'strong', 'b', 'cite', 'code', 'span', 'font');
 241    $link_text = t(filter_xss(variable_get('ed_readmore_text', ED_READMORE_TEXT_DEFAULT), $allowed_tags));
 242  
 243    // Make sure the text is plain
 244    $link_title = t(check_plain(variable_get('ed_readmore_title', ED_READMORE_TITLE_DEFAULT)));
 245  
 246    // Replace tokens with values if the Token module and the token options are enabled
 247    if (module_exists('token') && variable_get('ed_readmore_tokens', TRUE)) {
 248      $link_text = token_replace($link_text, 'node', $node);
 249      $link_title = token_replace($link_title, 'node', $node);
 250    }
 251  
 252    // Replace double quotes with single quotes to prevent breaking of the title attribute
 253    $link_title = str_replace('"', '\'', $link_title);
 254  
 255    // Build link options array
 256    $link_options = array(
 257      'attributes' => array(
 258        'title' => $link_title,
 259      ),
 260      'html' => TRUE,
 261    );
 262  
 263    // Add rel="nofollow" to link if the option is enabled
 264    if (variable_get('ed_readmore_nofollow', TRUE)) {
 265      $link_options['attributes']['rel'] = 'nofollow';
 266    }
 267  
 268    // Filter separator for cross-site scripting (XSS)
 269    $separator = filter_xss(variable_get('ed_readmore_separator', ED_READMORE_SEPARATOR_DEFAULT));
 270  
 271    // Send prepared data to the theme function
 272    return theme('ed_readmore_link', $node, $link_text, $link_options, $separator, $display);
 273  }
 274  
 275  
 276  /**
 277   * Implementation of hook_theme().
 278   */
 279  function ed_readmore_theme($existing, $type, $theme, $path) {
 280    return array(
 281      'ed_readmore_link' => array(
 282        'arguments' => array(
 283          'link_text' => NULL,
 284          'link_destination' => NULL,
 285          'link_options' => NULL,
 286          'display' => NULL,
 287        ),
 288      ),
 289    );
 290  }
 291  
 292  
 293  /**
 294   * Theme function that wraps the rendered link.
 295   */
 296  function theme_ed_readmore_link($node, $link_text, $link_options, $separator, $display) {
 297    // Use a <div> (block-level) element for links appended after the teaser
 298    if ($display == 'after') {
 299      $element = 'div';
 300      $separator = '';
 301    }
 302    else {
 303      // Use a <span> (inline) element for links that appear inside the teaser
 304      $element = 'span';
 305      if (empty($separator)) {
 306        $separator = ' ';
 307      }
 308    }
 309  
 310    return $separator . '<' . $element . ' class="read-more">' . l($link_text, 'node/'. $node->nid, $link_options) . '</' . $element . '>';
 311  }


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7