I am thinking that this module should be put or combine together with Pathauto module. Since i'm look that this module have the features functionality of pathauto, it would be great it is integrated into existed module.

Drupal have a very wide and flexible framework. And the power of Drupal is the speed of loading. But once there is a lot of module was installed, it could deteriorate the real performance.

This is just my 2 cents, but i have been installed in my site since it would help me to manage my content more easily.

Comments

dave reid’s picture

I agree. I'd love to see this in Pathauto as well since this would be a great feature for core and we're not far away from getting momentum for Pathauto in core D8.

mlncn’s picture

Issue tags: +#d7ux

I have heard from a reliable source that there is a short window to try to get this directly into core for D7, so I will work on that first and then PathAuto for 6 (?) and this module will have had the shortest, happiest life possible.

In both cases I would love thoughts on the most Drupal way to display this list; the theming and placement currently are "good enough" for a module primarily oriented toward development but feel not quite right for core.

dave reid’s picture

I would prefer a re-usable 'listing' function that takes a db_select() query and applies tablesort, etc and splits out a table. This is what I've done with path_redirect where I can use the same code to put a fieldset on node forms to show redirects pointing to a node, as well as on my admin/build/path-redirect page that lists all redirects.

See the screenshots of the interface at http://drupal.org/node/168877#comment-2310790 and the project page at http://drupal.org/project/path_redirect

This is the general listing function:

function path_redirect_list_redirects(SelectQueryInterface $query = NULL, $conditions = array(), $tableselect = FALSE) {
  // Initialize the query object.
  if (!isset($query)) {
    $query = db_select('path_redirect');
  }

  // Check if this will be a tableselect element.
  $tableselect &= user_access('administer redirects');

  // Set up the header.
  $header = array(
    'source' => array('data' => t('From'), 'field' => 'source', 'sort' => 'asc'),
    'redirect' => array('data' => t('To'), 'field' => 'redirect'),
    'type' => array('data' => t('Type'), 'field' => 'type'),
    'language' => array('data' => t('Language'), 'field' => 'language'),
    'last_used' => array('data' => t('Last used'), 'field' => 'last_used'),
    'operations' => array('data' => t('Operations')),
  );

  // Do not include the language column if locale is disabled.
  if (!module_exists('locale')) {
    unset($header['language']);
  }

  // Remove any columns that are present in the conditions.
  foreach ($conditions as $field => $value) {
    $query->condition($field, $value);
    unset($headers[$field]);
  }

  // Cannot re-use path_redirect_load_multiple() since we need to perform table
  // sorting here.
  $query->fields('path_redirect');
  $query->extend('TableSort')->orderByHeader($header);
  $redirects = $query->execute()->fetchAllAssoc('rid', PDO::FETCH_ASSOC);

  $destination = drupal_get_destination();
  $rows = array();
  $weight = 0;
  foreach ($redirects as $rid => $redirect) {
    $row = array();
    if (isset($header['source'])) {
      $row['source'] = $redirect['source'];
    }
    if (isset($header['redirect'])) {
      $row['redirect'] = $redirect['redirect'];
    }
    if (isset($header['type'])) {
      $row['type'] = $redirect['type'];
    }
    if (isset($header['language'])) {
      $row['language'] = module_invoke('locale', 'language_name', $redirect['language']);
    }
    if (isset($header['last_used'])) {
      $row['last_used'] = format_date($redirect['last_used'], 'short');
    }
    if (isset($header['operations'])) {
      $operations = array();
      $operations['edit'] = array(
        'title' => t('Edit'),
        'href' => 'admin/config/search/path-redirect/edit/' . $rid,
        'query' => $destination,
      );
      $operations['delete'] = array(
        'title' => t('Delete'),
        'href' => 'admin/config/search/path-redirect/delete/' . $rid,
        'query' => $destination,
      );
      $row['operations'] = array(
        'data' => array(
          '#theme' => 'links',
          '#links' => $operations,
          '#attributes' => array('class' => array('links', 'inline')),
        ),
      );
    }
    if ($tableselect) {
      $row['#weight'] = $weight++;
    }
    $rows[(string) $rid] = $row;
  }

  if ($tableselect) {
    return array(
      '#type' => 'tableselect',
      '#header' => $header,
      '#options' => $rows,
      '#empty' => t('No URL redirects available.'),
    );
  }
  else {
    return array(
      '#theme' => 'table',
      '#header' => $header,
      '#rows' => $rows,
      '#empty' => t('No URL redirects available.'), // <-- not yet supported yet for tables, core patch at http://drupal.org/node/648410
    );
  }
}

This is what I use on the node forms:

function path_redirect_form_alter(&$form, $form_state, $form_id) {
  if (!empty($form['#node_edit_form']) && !empty($form['#node']->nid)) {
    $form['path_redirect'] = array(
      '#type' => 'fieldset',
      '#title' => t('URL redirects'),
      '#description' => t('The following are a list of URL redirects that point to this location.'),
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#group' => 'additional_settings',
      '#attached' => array(
        'js' => array(drupal_get_path('module', 'path_redirect') . '/path_redirect.js'),
      ),
      '#access' => user_access('administer redirects'),
      '#weight' => 30,
    );
    $form['path_redirect']['table'] = path_redirect_list_redirects(NULL, array('redirect' => 'node/' . $form['#node']->nid));
  }
}

And here's what I do on my listing page:

function path_redirect_admin_redirects($form, &$form_state) {
  ...
  // Get filter keys.
  $keys = func_get_args();
  $keys = array_splice($keys, 2); // Offset the $form and $form_state parameters.
  $keys = implode('/', $keys);
  ...

  $query = db_select('path_redirect')->extend('PagerDefault')->limit(50);
  path_redirect_filter_query($query, $keys);

  $form['rids'] = path_redirect_list_redirects($query, array(), TRUE);
  $form['pager'] = array(
    '#markup' => theme('pager', array('tags' => NULL)),
  );
  return $form;
}

function path_redirect_filter_query(SelectQueryInterface $query, $keys = '') {
  if ($keys) {
    // Replace wildcards with PDO wildcards.
    $conditions = db_or();
    $wildcard = '%' . preg_replace('!\*+!', '%', $keys) . '%';
    $conditions->condition('source', $wildcard, 'LIKE');
    $conditions->condition('redirect', $wildcard, 'LIKE');
    $conditions->condition('query', $wildcard, 'LIKE');
    $conditions->condition('fragment', $wildcard, 'LIKE');
    $query->condition($conditions);
  }
}

So now if I wanted to throw a listing for all redirects that point to a user's profile, it's easy. I think this same kind of thing would be useful for this/core.