View source  
  <?php
$freelinking['nodetitle'] = array(
  'indicator' => '/nt$|nodetitle|title/A',
  'callback' => 'freelinking_nodetitle_callback',
  'tip' => t('Link to a local node by title'),
  'run on view' => TRUE,
);
function freelinking_nodetitle_callback($target, $plugin) {
  $node = freelinking_nodetitle_nid_from_title($target);
  
  if (!$node) {
    $target['target'] = check_plain($target['target']);
    $target['dest'] = check_plain($target['dest']);
    return _freelinking_nodetitle_failure($target);
  }
  
  $title = $target['text'] ? $target['text'] : $node->title;
  $title = check_plain($title);
  if (!$target['tooltip']) {
    $target['tooltip'] = freelinking_internal_tooltip('node', $node->nid);
  }
  
  return array(
    $title,
    'node/' . $node->nid,
    array(
      'attributes' => array(
        'title' => $target['tooltip'],
      ),
      'language' => $node->language,
    ),
  );
}
function freelinking_nodetitle_settings() {
  $extra_description = '';
  
  $form['freelinking_nodetitle_searchcontenttype'] = array(
    '#title' => t('Restrict freelinks to this content type'),
    '#type' => 'select',
    '#options' => array_merge(array(
      'none' => t('No restriction'),
    ), node_get_types('names')),
    '#default_value' => variable_get('freelinking_nodetitle_searchcontenttype', 'none'),
    '#description' => t('Lookup by title to find a freelink will be restricted to this content type only.'),
  );
  $failover_option['none'] = t('Do nothing');
  $failover_option['showtext'] = t('Show text (remove markup)');
  
  if (module_exists('freelinking_prepopulate')) {
    $failover_option['create'] = t('Add a link to create content. (Without Permission: Access Denied)');
  }
  else {
    $extra_description = '<br />' . t('Note: Enable the <strong>Freelinking Prepopulate</strong> submodule to add a content creation failover option.');
  }
  
  if (module_exists('search')) {
    $failover_option['search'] = t('Add a link to Search Content');
  }
  else {
    $extra_description .= '<br /><strong>' . t('Note: Enable the %module module for internal search option.', array(
      '%module' => 'Search',
    )) . '</strong>';
    
    if (($search_plugin = variable_get('freelinking_search_failover', 'error')) != 'error') {
      $failover_option['search'] = t('Add a link to %search Search Content.', array(
        '%search' => drupal_ucfirst($search_plugin),
      ));
    }
  }
  $failover_option['error'] = t('Insert an error message');
  $form['freelinking_nodetitle_failover'] = array(
    '#title' => t('If a suitable content is not found'),
    '#type' => 'select',
    '#options' => $failover_option,
    '#default_value' => variable_get('freelinking_nodetitle_failover', _freelinking_nodetitle_default_failover()),
    '#description' => t('What should freelinking do when the page is not found?') . $extra_description,
  );
  return $form;
}
function freelinking_nodetitle_nid_from_title(&$target) {
  $params['title'] = $target['dest'];
  $default_type = variable_get('freelinking_nodetitle_searchcontenttype', 'none');
  if (isset($target['type'])) {
    $params['type'] = $target['type'];
  }
  elseif ($default_type != 'none') {
    $params['type'] = $default_type;
  }
  $set = node_load($params);
  if (is_object($set)) {
    $set = array(
      $set,
    );
  }
  if (empty($set)) {
    return NULL;
  }
  
  $language = array(
    language_default('language'),
    '',
  );
  if (module_exists('locale')) {
    if ($target['language']) {
      array_unshift($language, $target['language']);
    }
    foreach ($language as $priority) {
      foreach ($set as $node) {
        if ($priority == $node->language) {
          $retn = $node;
          break 2;
        }
      }
    }
  }
  else {
    $retn = $set[0];
  }
  if (node_access('view', $retn)) {
    return $retn;
  }
}
function _freelinking_nodetitle_failure($target) {
  $failover = variable_get('freelinking_nodetitle_failover', _freelinking_nodetitle_default_failover());
  switch ($failover) {
    case 'create':
      return array(
        'failover' => 'createnode',
        'target' => $target,
      );
    case 'showtext':
      return array(
        'failover' => 'showtext',
        'target' => $target,
      );
    case 'search':
      return array(
        'failover' => 'search',
        'target' => $target,
      );
    case 'error':
      return array(
        'failover' => 'error',
        'message' => t('%title not found', array(
          '%title' => $target['dest'],
        )),
      );
  }
  
  return FALSE;
}
function _freelinking_nodetitle_default_failover() {
  if (module_exists('freelinking_create')) {
    return 'create node';
  }
  elseif (module_exists('search')) {
    return 'search';
  }
  return 'none';
}