Personal tools
You are here: Home Documentation How-tos Generate custom unique ids for new objects
Support

Get Help

Join our chat rooms or support forums if you have more specific questions.

Plone Training
Learn how to design, build, and deploy a website in Plone through one of the numerous Plone training sessions around the world.
Find Plone training…
 
Document Actions

Generate custom unique ids for new objects

Warning: This item is marked as outdated.

This How-to applies to: Plone 2.0.x
This How-to is intended for: Developers

When you create a new object in Plone, it is automatically given an id (short name) based on the object's type and the current date. This how-to shows you how to change the way in which this id is generated.

The script portal_skins/plone_scripts/createObject.py is used to create objects when the user selects the relevant type in the add new drop-down. This in turn calls the script portal_skins/plone_scripts/generateUniqueId.py, which generates a unique default id (short name) for new objects based on the object's type, the current date and time, and a random number.

This generated id can be very long, upsetting the navtree (at least until Plone 2.1 comes along and fixes it) and making very unfriendly URLs. Also, in certain circumstances you may wish to have more control over the default id. For instance, in ArchPackage (in the Collective) we needed objects of the type Improvement Proposal, which live exclusively inside an Improvement Proposal container (called Roadmap), to have sequentially numbered ids, so that the first proposal had id 1, the second id 2 etc.

There are three general strategies you may employ.

First, if you are comfortable customising the site-wide generateUniqueId.py, you can do so in your custom folder or a product's skin folder. This gets passed the parameter type_name, which you can use to create type-specific naming schemes. However, you should be aware that if you are trying to create a re-usable product (and in general, you ought to do that anyway), this is a site-wide script used for all types in the site. Thus, another product may ovveride this script again, rendering your customisation ineffective. Another caveat is that you must ensure the id is unique, either by relying on random numbers like the current script does, or checking it explicitly against context.objectIds (), which will return the currently used ids in the folder where the object is being created.

Second, if, like in the case of ArchPackage above, you want to custom-name a type which is only addable inside a container you control (that is, Implicitly addable is turned off in portal_types for the object, and the object is set in the list of allowed content types for some folderish container also part of your product, like the Roadmap container above), you can let acquisition work its magic by defining a method like so on your container class:

  security.declareProtected (ADD_CONTENTS_PERMISSION, 'generateUniqueId')
  def generateUniqueId (self, type_name):
    """Generate a unique ID for sub objects according to the following rules ....
    """

    newId = ""

    ...

    # Set newId to something sensible - it must be unique in the container!
    # You can use "if newId in self.objectIds ()" to test whether it is

    return newId

ADD_CONTENTS_PERMISSION is assumed to be a constant containing the add contents permission for your product. Modify as necessary.

Third, it may be possible to use the manage_afterAdd () hook in your class to rename an object after it has been created. This may be necessary if you need custom ids generated, possibly with the actual id field hidden in your schema, and neither of the above two solutions will work (i.e. you can't customise the default script, and you don't control the parent container so you can't add a method to it). However, I have not seen any examples of this. Anyone with success stories or alternative suggestions, please leave a comment.

by Martin Aspeli last modified February 6, 2006 - 14:38 All content is copyright Plone Foundation and the individual contributors.

Update for Plone 2.1

Posted by Martin Aspeli at February 6, 2006 - 14:34
In Plone 2.1, you can use _rename_after_creation and the _renameAfterCreation() method to achieve the same thing in a factory-safe way. We do this in Poi, for example. This how-to should be updated to show that technique as well.

This worked for me in Plone 2.5

Posted by Ed Eddington at June 6, 2008 - 15:34
Simply add this to your content type class definition to override the method in Archetypes/BaseObject.py :

_at_rename_after_creation = True

def generateNewId(self):
"""Generate random 20 character alphanumeric id for this object.
This id is used when automatically renaming an object after creation.
"""
import string
from random import Random

newname = ''.join( Random().sample(string.letters+string.digits, 20) )
return newname

For any issues with the web site functionality, please file a ticket.

Please consult the policy on plone.org content if you want your content published on this site.

Servers and hosting by