I'm interested in deploying documentation sets using uuid_features. I'd like to be able to manually enter links in the node body, connecting certain nodes to other nodes. On the various sites to which I'll be deploying, nids will not be constant (so I can't just hardcode <a href="/node/42">link to the main doc index</a>), nor will there be consistent aliases (so I can't just hardcode <a href="/doc/index">link to the main doc index</a>). The only constant will be the UUID.

Is there some way I can create a link in the node body by referencing the node's UUID?

If not... If I were to develop an input filter to provide this functionality (i.e., something that would parse [uuid:b8163bc8-9178-11e0-af96-00163e55ae82]link to the main doc index[/uuid] into a l() call), would you be interested in including it in uuid_features?

CommentFileSizeAuthor
#5 1181982-uuid-hookmenu-00.patch1.33 KBsmokris
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

chaps2’s picture

You may be able to use books to build up documentation sets and export them with uuid_features using the patch in #1048470: Book export. All your book navigation links would be re-created correctly.

smokris’s picture

Thanks, @chaps2. Books would solve part of the problem --- it would let me set up a linked hierarchy of pages --- but it won't help with regard to linking specific parts of body text to other pages.

ryan_courtnage’s picture

Rather than develop an input filter, it would make sense to me if there were a menu callback that would display or redirect-to a node based on its uuid. Something like like 'nodeuuid/%nodeuuid', where a nodeuuid_load() function would resolve using node_get_by_uuid() (from uuid.module)

It would also make sense that something like this be included with uuid.module, and not uuid_features.

My 2 cents

RobLoach’s picture

smokris’s picture

Project: UUID Features Integration » Universally Unique IDentifier
Version: 6.x-1.0-alpha1 » 6.x-1.x-dev
Component: uuid_node » User interface
Category: support » feature
Status: Active » Needs review
FileSize
1.33 KB

@ryan_courtnage and @Rob Loach --- thanks for the feedback. Both of those approaches sound reasonable. Since there's already #982818: Make it possible to export URL aliases, I'll convert this issue into a uuid.module feature request.

@uuid.module folks --- attached is a patch adding support for linking to nodes by their UUID (menu path "uuid/%nodeUUID" or "uuid/%nodeRevisionUUID") --- making it easy for documentation nodes to link to each other, without links being broken when the documentation nodes are moved from site to site.

smokris’s picture

Title: How to link between uuid_features exported nodes? » Add menu hook for linking to nodes' UUIDs

(update title)

RobLoach’s picture

Title: Add menu hook for linking to nodes' UUIDs » Add menu hook for linking to UUIDs

I think we need to setup a way to pass in what UUID type we're loading up. We could be wanting any of the following here:

  • node
  • comment
  • taxonomy
  • user
  • etc

So maybe we should have this type of menu system: uuid/%type/%uuid? Then if someone wants to load up a node, they'd use uuid/node/%uuid. For a comment, uuid/comment/%uuid. Taxonomy: uuid/taxonomy_term/%uuid..... Thoughts?

smokris’s picture

@RobLoach: the patch in #5 only handles nodes and node revisions currently, but, yeah, I think we should definitely add support for comments/taxonomy/users.

As for adding another layer to the menu system --- isn't the whole point of a UUID that it's unique? So by just specifying the UUID, the site can figure out whether that UUID corresponds with a node, node revision, comment, taxonomy term, user, or whatever, without requiring the user to specify redundant type data. Less redundancy, shorter URLs, easier to use.

zhangtaihao’s picture

I should mention that I used to actively run a project called UUID Resolver. However, it ran into a design conflict with UUID for Drupal 7, where the old-style lookups have become expensive; see #968328: Review dependency on UUID.

Since there seems to be an active interest in this functionality, I'd be happy to bring in co-maintainers on UUID Resolver and completely rework its architecture to make it usable for Drupal 6 and port it to Drupal 7.

Is anyone interested?

RobLoach’s picture

UUID Resolver sounds very interesting, should that kind of functionality be part of the UUID core module? Hmmmm....

/**
 * Finds the entity id by looking up the UUID.
 *
 * @param $uuid
 *   The uuid to look up.
 * @param $table
 *   (optional) The table to perform the search on. If not provided, will search for the
 *   the given UUID within the available tables.
 * @param $id_column
 *   (optional) The column containing the entity id.
 * @param $uuid_column
 *   (optional) The column containing the UUIDs.
 *
 * @return
 *   The id for the entity or FALSE if not found
 */
function uuid_find($uuid, $table = NULL, $id_column = NULL, $uuid_column = 'uuid') {
  // See if we can find the table.
  if (!isset($table)) {
    $types = array('comment', 'file', 'node', 'role', 'taxonomy_term', 'user');
    foreach ($types as $type) {
      $function = 'uuid_' . $type . '_find';
      $output = function_exists($function) ? $function($uuid) : FALSE;
      if ($output !== FALSE) {
        return $output;
      }
    }
    return FALSE;
  }

  return db_select($table, ' t')
    ->fields('t', array($id_column))
    ->condition($uuid_column, $uuid, '=')
    ->execute()
    ->fetchField();
}

Still need the type though. This is why looking it up without the $type/$table is expensive...

smokris’s picture

@zhangtaihao: Oh, cool, I didn't know that project existed. My preference would be for this to be integrated into the UUID core module.

@RobLoach: Right, it may be more expensive to look it up if the $table is not specified --- but that's an implementation detail that shouldn't be exposed to the end user.

RobLoach’s picture

Right, it may be more expensive to look it up if the $table is not specified --- but that's an implementation detail that shouldn't be exposed to the end user.

Think we should normalize UUIDs into their own table then?

zhangtaihao’s picture

Again, as I've said in #935998: Normalize the UUIDs into one table, I don't think we should normalize UUIDs. I believe the act of looking up a UUID is expensive. The fact is that the process would be much quicker if we stored lookups in a separate cache table. Then, using cache_get() to lookup a previously hit path will dramatically increase the efficiency when the site is using memory-based caching backends.

I'd be happy to rework UUID Resolver to do this, but I think this is something that goes into UUID core.

@skwashd: What do you think?

zhangtaihao’s picture

Actually, how about this: we could work it into UUID 7.x-1.x and then I'll backport the idea into UUID Resolver for Drupal 6.

colan’s picture

Basically, once the design for version 7 is done, we need a uuid_get_path_by_uuid() function. Add support for a UUID reference field needs this as well.

This gets easier if we know the type already: #1042822: Developers need an $entity->entity_type property

Dean Reilly’s picture

Subscribing

zhangtaihao’s picture

Is there a reason we can't engineer an extra 'uuid uri callback' into hook_entity_info()?

David_Rothstein’s picture

This sandbox project I just posted may be of interest:
http://drupal.org/sandbox/drothstein/1545440

It's for a more complicated use case, but half of what it does is directly related to what's being discussed here.

When implementing this, I actually did find it useful to keep the entity type in the URL (e.g., node/[UUID] rather than uuid/[UUID]) and not to do it via separate menu items. The main reason is that it doesn't limit you to using UUIDs on particular paths; you can automatically use them on any path associated with the entity (e.g., node/[UUID]/edit, node/[UUID]/delete, node/[UUID]/webform, or whatever; all of these work automatically).

It's a sandbox project for now, although I'm planning to promote it to a full project at some point. If it's useful for this issue, I'd be happy to discuss moving parts of it either here (or to UUID Resolver if that gets revived for Drupal 7).

The relevant part of the sandbox project to look at is the "Other use cases" section (on the project page) and the hook_menu_get_item_alter() implementation (in the code).

apotek’s picture

So by just specifying the UUID, the site can figure out whether that UUID corresponds with a node, node revision, comment, taxonomy term, user, or whatever, without requiring the user to specify redundant type data. Less redundancy, shorter URLs, easier to use.

Yes, easier to use, but will also require sql query lookups in every uuid_* table until it's found, OR a huge UNION sql query on all those.

It's far cheaper to do /uuid/type/[UUID]. Not that these two approaches are mutually exclusive. I would say the general use case is for a menu hook that looks up by type (so we don't need to fill up an already huge url_alias table) AND what @smokris is suggesting: which is basically a search/query by uuid function.

This would mean two menu hooks: 1: the general uuid/type/[UUID], 2: A uuid/[UUID] querying system.

It would be understood that option 2 is basically a search and is therefore a performance dog, but has it's uses, and that 1 would be the preferred way of creating actually usable links without cluttering the url_alias table with a bunch of rows that may never be used. Url_alias is for SEO and prettifying links, and these links would hardly be "pretty."

( I know other modules (in my opinion unfortunately) also put stuff in url_alias (taxonomy for example), but there's no need to follow established bad precedence :-). )

also, everyone here is discussing 7.x, but the issue is still in the 6.x queue. Maybe this should be split up into two conversations.

I might also say that this is easy to implement as is. I have code like this running in several installations:

In a menu hook:

<?php
  // present content based on uuid
  $items['uuid/%/%'] = array(
    'title' => 'Load by UUID',
    'page arguments' => array(2, 1),
    'page callback' => '_my_module_uuid_load',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
    'description' => 'Redirect content requested by uuid to its corresponding node page',
  );

?>

And then the callback provides a 301 or 302 redirect to the node page. (Can also make it a full node-load style callback, but it means you have to maintain two different scenarios in the node view rather than just redirecting and letting the default behavior take over.).

zhangtaihao’s picture

I would almost have thought that given UUID (for D7) is tied to entity types you could look up entities supporting UUIDs.

Perhaps then wherever "uri callback" exists the hook_menu_alter() could tweak the menu router path such that:

  1. If the wildcard is numeric, the traditional entity_load() is used.
  2. If the wildcard looks like a UUID, entity_uuid_load() is used (and obviously redirected).
skwashd’s picture

Issue summary: View changes
Status: Needs review » Closed (won't fix)

Drupal 6 core is no longer supported. We are no longer supporting 6.x-1.x versions of this module. I am closing this issue as won't fix.