When adding nodes to Drupal using a node-add form (the normal way), there is no restriction on having two identical node titles.
However - in the node definition (importexportapi_node.inc) the node title is an alternative key of nid, which makes the creation of identical node titles to impossible:

$def['title'] = array(
    '#title' => t('Title'),
    '#alt_key_for' => 'nid'
  );

Is it realy the wanted behaviour? I don't think so. I suggest changing it to NULL:

$def['title'] = array(
    '#title' => t('Title'),
    '#alt_key_for' => NULL
  );

Comments

moshe weitzman’s picture

FWIW, I don't think this is proper default behavior either. alternative keys are a great feature, but not usually desired here.

Jaza’s picture

Title: unexpected behaviour when importing nodes, or: wrong node definition » Node title should not be an alt key of nid

I know that node titles are not unique in Drupal, but having them as alternate keys for node entities is very useful in the importexportapi. The node title is the only field that is a suitable candidate for being an alternate key of the nid field. With no alternate keys, doing a 'keyless' import (i.e. an import where all key fields are regenerated by the DB) with nodes is more of a pain (but still perfectly possible).

Because of this, I would prefer to leave the node title field as an alternate key for now. If you want/need to stop it from being an alternate key field, then you can override the definition by using importexportapi_set_def() in your modules, or (this is not the recommended method) you can simply remove it by hacking the definition.

z.stolar’s picture

Indeed, I realized the necessity of it when I uploaded keyless nodes, and wanted to attach files to them. I then saw that the title is used to create the relation between the nodes and the files, and all db IDs were created properly.
However, since this is not the default behaviour for Drupal, it might be better not to use
'#alt_key_for' => 'nid'
by default, but make it clear that when using keyless imports/exports, this option should be used. This will prevent some confusion.
Alternatively - make it clearer in the documentation (should the 'component' field for this issue change from 'code' to 'documentation'?)

One question that arrises (it's more suitable for the forum, but, since you've mentioned it...) is: why do you suggest using set_def and not def_alter?

Jaza’s picture

One question that arrises (it's more suitable for the forum, but, since you've mentioned it...) is: why do you suggest using set_def and not def_alter?

_set_def() will only alter the definition for the current request, whereas _def_alter() will alter it permanently. Thus, using _def_alter() is really not that different to hacking the definition itself. Also, in this case you would use _node_def_alter() instead of _def_alter().

jamesJonas’s picture

I'm afraid use of the title as an alt key will only work for small data sets. Duplicate titles are very common. Within my data set for locations in the US the average is 2 places per title across the nation. Many titles are repeated across several hundred locations, with a some titles reused by a few several thousand locations.

A better method would be to allow the import to define an Alternate Key field. One example of a strong candidate would be a the concat() of the Source Key and Source ID. The Source Key (singe row from a source) and Source ID (name or ID of the source data) provide a reference back to original data source. These Source fields enable could enable syncronization over time. A Source Key and a Source ID should be persisted in the Target (drupal) along with the Alternate Key.

Anonymous’s picture

Version: master » 6.x-1.x-dev
Priority: Minor » Normal
Anonymous’s picture

Status: Active » Postponed
djbobbydrake’s picture

I tried setting the alternate key to NULL for the node title, but that didn't work. I had to add this also to the hook_node_def_alter() in order to make things work (i.e. to be able to add different nodes with the same title):

    $def['revisions']['title_revision'] = array(
      '#title' => t('Title'),
      '#alt_key_for' => NULL,
      '#db_field_unaliased' => 'title'
    );