2010/11/29

Title-to-Id Behavior

title-to-id 是 Plone 的行為特色,在建立文件的過程,會把 title 欄位的值,轉換成 URL 的值。事實上,也可以事後轉換,例如寫成 External Method 來批次執行

Archetypes 預設就使用 title-to-id 機制,相關的程式碼片段整理如下:

Products/Archetypes/BaseObject.py
# Import conditionally, so we don't introduce a hard dependency
try:
from plone.i18n.normalizer.interfaces import IUserPreferredURLNormalizer
from plone.i18n.normalizer.interfaces import IURLNormalizer
URL_NORMALIZER = True
except ImportError:
URL_NORMALIZER = False

class BaseObject(Referenceable):
...
def generateNewId(self):
"""Suggest an id for this object.
This id is used when automatically renaming an object after creation.
"""
title = self.Title()
# Can't work w/o a title
if not title:
return None

# Don't do anything without the plone.i18n package
if not URL_NORMALIZER:
return None

if not isinstance(title, unicode):
charset = self.getCharset()
title = unicode(title, charset)

request = getattr(self, 'REQUEST', None)
if request is not None:
return IUserPreferredURLNormalizer(request).normalize(title)

return queryUtility(IURLNormalizer).normalize(title)

def _renameAfterCreation(self, check_auto_id=False):
"""Renames an object like its normalized title.
"""
old_id = self.getId()
if check_auto_id and not self._isIDAutoGenerated(old_id):
# No auto generated id
return False

new_id = self.generateNewId()
plone/i18n/normalizer/__init__.py
class URLNormalizer(object):
...
def normalize(self, text, locale=None, max_length=MAX_URL_LENGTH):
...
text = baseNormalize(text)
base = text # use text.lower() to make it lower-case

把原本 base = text.lower() 改成 base = text。

另外,Dexterity 則利用 Name From Title 的行為設定來啟用,參考 plone.app.content 裡 interfaces.py 的 INameFromTitle。

No comments: