Back to index

plone3  3.1.7
Public Member Functions | Static Public Attributes | Private Member Functions | Static Private Attributes
CMFPlone.PloneTool.PloneTool Class Reference
Inheritance diagram for CMFPlone.PloneTool.PloneTool:
Inheritance graph
[legend]
Collaboration diagram for CMFPlone.PloneTool.PloneTool:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def setMemberProperties
def getSiteEncoding
def portal_utf8
def utf8_portal
def getMailHost
def sendto
def validateSingleNormalizedEmailAddress
def validateSingleEmailAddress
def validateEmailAddresses
def editMetadata
def contentEdit
def availableMIMETypes
def getWorkflowChainFor
def getIconFor
def getReviewStateTitleFor
def getDiscussionThread
def setDefaultSkin
def setCurrentSkin
def changeOwnershipOf
def urlparse
def urlunparse
def exceptionString
def logException
def createSitemap
def typesToList
def createNavTree
def createBreadCrumbs
def good_id
def bad_chars
def getInheritedLocalRoles
def isDefaultPage
def getDefaultPage
def addPortalMessage
def showPortalMessages
def browserDefault
def isTranslatable
def isStructuralFolder
def acquireLocalRoles
def isLocalRoleAcquired
def getOwnerName
def normalizeString
def listMetaTags
def getUserFriendlyTypes
def reindexOnReorder
def isIDAutoGenerated
def getEmptyTitle
def pretty_title_or_id
def getMethodAliases
def deleteObjectsByPaths
def transitionObjectsByPaths
def renameObjectsByPaths

Static Public Attributes

string id = 'plone_utils'
 meta_type = ToolNames.UtilsTool
string toolicon = 'skins/plone_images/site_icon.gif'
tuple security = ClassSecurityInfo()
int plone_tool = 1
string field_prefix = 'field_'
tuple changeOwnershipOf = postonly(changeOwnershipOf)
tuple acquireLocalRoles = postonly(acquireLocalRoles)
tuple deleteObjectsByPaths = postonly(deleteObjectsByPaths)
tuple transitionObjectsByPaths = postonly(transitionObjectsByPaths)
tuple renameObjectsByPaths = postonly(renameObjectsByPaths)

Private Member Functions

def _renameObject
def _makeTransactionNote
def _addToNavTreeResult

Static Private Attributes

tuple __implements__

Detailed Description

Various utility methods.

Definition at line 83 of file PloneTool.py.


Member Function Documentation

def CMFPlone.PloneTool.PloneTool._addToNavTreeResult (   self,
  result,
  data 
) [private]
Adds a piece of content to the result tree.

Definition at line 532 of file PloneTool.py.

00532 
00533     def _addToNavTreeResult(self, result, data):
00534         """Adds a piece of content to the result tree.
00535         """
00536         return utils.addToNavTreeResult(result, data)

def CMFPlone.PloneTool.PloneTool._makeTransactionNote (   self,
  obj,
  msg = '' 
) [private]

Definition at line 301 of file PloneTool.py.

00301 
00302     def _makeTransactionNote(self, obj, msg=''):
00303         #TODO Why not aq_parent()?
00304         relative_path = '/'.join(getToolByName(self, 'portal_url').getRelativeContentPath(obj)[:-1])
00305         charset = self.getSiteEncoding()
00306         if not msg:
00307             msg = relative_path + '/' + obj.title_or_id() + ' has been modified.'
00308         if isinstance(msg, UnicodeType):
00309             # Convert unicode to a regular string for the backend write IO.
00310             # UTF-8 is the only reasonable choice, as using unicode means
00311             # that Latin-1 is probably not enough.
00312             msg = msg.encode(charset)
00313         if not transaction.get().description:
00314             transaction_note(msg)

Here is the call graph for this function:

Here is the caller graph for this function:

def CMFPlone.PloneTool.PloneTool._renameObject (   self,
  obj,
  id 
) [private]

Definition at line 292 of file PloneTool.py.

00292 
00293     def _renameObject(self, obj, id):
00294         if not id:
00295             REQUEST = self.REQUEST
00296             id = REQUEST.get('id', '')
00297             id = REQUEST.get(self.field_prefix + 'id', '')
00298         if id != obj.getId():
00299             parent = aq_parent(aq_inner(obj))
00300             parent.manage_renameObject(obj.getId(), id)

Here is the caller graph for this function:

def CMFPlone.PloneTool.PloneTool.acquireLocalRoles (   self,
  obj,
  status = 1,
  REQUEST = None 
)
If status is 1, allow acquisition of local roles (regular behaviour).

If it's 0, prohibit it (it will allow some kind of local role
blacklisting).

Definition at line 910 of file PloneTool.py.

00910 
00911     def acquireLocalRoles(self, obj, status = 1, REQUEST=None):
00912         """If status is 1, allow acquisition of local roles (regular behaviour).
00913 
00914         If it's 0, prohibit it (it will allow some kind of local role
00915         blacklisting).
00916         """
00917         mt = getToolByName(self, 'portal_membership')
00918         if not mt.checkPermission(ModifyPortalContent, obj):
00919             raise Unauthorized
00920 
00921         # Set local role status...
00922         # set the variable (or unset it if it's defined)
00923         if not status:
00924             obj.__ac_local_roles_block__ = 1
00925         else:
00926             if getattr(obj, '__ac_local_roles_block__', None):
00927                 obj.__ac_local_roles_block__ = None
00928 
00929         # Reindex the whole stuff.
        obj.reindexObjectSecurity()

Here is the call graph for this function:

def CMFPlone.PloneTool.PloneTool.addPortalMessage (   self,
  message,
  type = 'info',
  request = None 
)
\
Call this once or more to add messages to be displayed at the
top of the web page.

Examples:

>>> ptool = self.portal.plone_utils

>>> ptool.addPortalMessage(u'A random warning message', 'warning')

If no type is given it defaults to 'info'
>>> ptool.addPortalMessage(u'A random info message')

The arguments are:
    message:   a string, with the text message you want to show,
       or a HTML fragment (see type='structure' below)
    type:      optional, defaults to 'info'. The type determines how
       the message will be rendered, as it is used to select
       the CSS class for the message. Predefined types are:
       'info' - for informational messages
       'warning' - for warning messages
       'error' - for messages about restricted access or errors.

Portal messages are by default rendered by the global_statusmessage.pt
page template.

It is also possible to add messages from page templates, as
long as they are processed before the portal_message macro is
called by the main template. Example:

  <tal:block tal:define="temp python:putils.addPortalMessage('A random info message')" />

Definition at line 658 of file PloneTool.py.

00658 
00659     def addPortalMessage(self, message, type='info', request=None):
00660         """\
00661         Call this once or more to add messages to be displayed at the
00662         top of the web page.
00663 
00664         Examples:
00665 
00666         >>> ptool = self.portal.plone_utils
00667 
00668         >>> ptool.addPortalMessage(u'A random warning message', 'warning')
00669 
00670         If no type is given it defaults to 'info'
00671         >>> ptool.addPortalMessage(u'A random info message')
00672 
00673         The arguments are:
00674             message:   a string, with the text message you want to show,
00675                        or a HTML fragment (see type='structure' below)
00676             type:      optional, defaults to 'info'. The type determines how
00677                        the message will be rendered, as it is used to select
00678                        the CSS class for the message. Predefined types are:
00679                        'info' - for informational messages
00680                        'warning' - for warning messages
00681                        'error' - for messages about restricted access or errors.
00682 
00683         Portal messages are by default rendered by the global_statusmessage.pt
00684         page template.
00685 
00686         It is also possible to add messages from page templates, as
00687         long as they are processed before the portal_message macro is
00688         called by the main template. Example:
00689 
00690           <tal:block tal:define="temp python:putils.addPortalMessage('A random info message')" />
00691         """
00692         if request is None:
00693             request = self.REQUEST
00694         IStatusMessage(request).addStatusMessage(message, type=type)

Here is the call graph for this function:

Returns a map of mimetypes.

Requires mimetype registry from Archetypes >= 1.3.

Definition at line 328 of file PloneTool.py.

00328 
00329     def availableMIMETypes(self):
00330         """Returns a map of mimetypes.
00331 
00332         Requires mimetype registry from Archetypes >= 1.3.
00333         """
00334         mtr = getToolByName(self, 'mimetypes_registry')
00335         return mtr.list_mimetypes()

Here is the call graph for this function:

def CMFPlone.PloneTool.PloneTool.bad_chars (   self,
  id 
)
Returns a list of the Bad characters.

Definition at line 566 of file PloneTool.py.

00566 
00567     def bad_chars(self, id):
00568         """Returns a list of the Bad characters."""
00569         return BAD_CHARS(id)

Sets default so we can return whatever we want instead of index_html.

This method is complex, and interacts with mechanisms such as
IBrowserDefault (implemented in CMFDynamicViewFTI), LinguaPlone and
various mechanisms for setting the default page.

The method returns a tuple (obj, [path]) where path is a path to
a template or other object to be acquired and displayed on the object.
The path is determined as follows:

0. If we're coming from WebDAV, make sure we don't return a contained
    object "default page" ever
1. If there is an index_html attribute (either a contained object or
    an explicit attribute) on the object, return that as the
    "default page". Note that this may be used by things like
    File and Image to return the contents of the file, for example,
    not just content-space objects created by the user.
2. If the object implements IBrowserDefault, query this for the
    default page.
3. If the object has a property default_page set and this gives a list
    of, or single, object id, and that object is is found in the
    folder or is the name of a skin template, return that id
4. If the property default_page is set in site_properties and that
    property contains a list of ids of which one id is found in the
    folder, return that id
5. If the object implements IBrowserDefault, try to get the selected
    layout.
6. If the type has a 'folderlisting' action and no default page is
    set, use this action. This permits folders to have the default
    'view' action be 'string:${object_url}/' and hence default to
    a default page when clicking the 'view' tab, whilst allowing the
    fallback action to be specified TTW in portal_types (this action
    is typically hidden)
7. If nothing else is found, fall back on the object's 'view' action.
8. If this is not found, raise an AttributeError

If the returned path is an object, it is checked for ITranslatable. An
object which supports translation will then be translated before return.

Definition at line 710 of file PloneTool.py.

00710 
00711     def browserDefault(self, obj):
00712         """Sets default so we can return whatever we want instead of index_html.
00713 
00714         This method is complex, and interacts with mechanisms such as
00715         IBrowserDefault (implemented in CMFDynamicViewFTI), LinguaPlone and
00716         various mechanisms for setting the default page.
00717 
00718         The method returns a tuple (obj, [path]) where path is a path to
00719         a template or other object to be acquired and displayed on the object.
00720         The path is determined as follows:
00721 
00722         0. If we're coming from WebDAV, make sure we don't return a contained
00723             object "default page" ever
00724         1. If there is an index_html attribute (either a contained object or
00725             an explicit attribute) on the object, return that as the
00726             "default page". Note that this may be used by things like
00727             File and Image to return the contents of the file, for example,
00728             not just content-space objects created by the user.
00729         2. If the object implements IBrowserDefault, query this for the
00730             default page.
00731         3. If the object has a property default_page set and this gives a list
00732             of, or single, object id, and that object is is found in the
00733             folder or is the name of a skin template, return that id
00734         4. If the property default_page is set in site_properties and that
00735             property contains a list of ids of which one id is found in the
00736             folder, return that id
00737         5. If the object implements IBrowserDefault, try to get the selected
00738             layout.
00739         6. If the type has a 'folderlisting' action and no default page is
00740             set, use this action. This permits folders to have the default
00741             'view' action be 'string:${object_url}/' and hence default to
00742             a default page when clicking the 'view' tab, whilst allowing the
00743             fallback action to be specified TTW in portal_types (this action
00744             is typically hidden)
00745         7. If nothing else is found, fall back on the object's 'view' action.
00746         8. If this is not found, raise an AttributeError
00747 
00748         If the returned path is an object, it is checked for ITranslatable. An
00749         object which supports translation will then be translated before return.
00750         """
00751 
00752         # WebDAV in Zope is odd it takes the incoming verb eg: PROPFIND
00753         # and then requests that object, for example for: /, with verb PROPFIND
00754         # means acquire PROPFIND from the folder and call it
00755         # its all very odd and WebDAV'y
00756         request = getattr(self, 'REQUEST', None)
00757         if request and request.has_key('REQUEST_METHOD'):
00758             if request['REQUEST_METHOD'] not in  ['GET', 'POST']:
00759                 return obj, [request['REQUEST_METHOD']]
00760         # Now back to normal
00761 
00762         portal = getToolByName(self, 'portal_url').getPortalObject()
00763         wftool = getToolByName(self, 'portal_workflow')
00764 
00765         # Looking up translatable is done several places so we make a
00766         # method for it.
00767         def returnPage(obj, page):
00768             # Only look up for untranslated folderish content,
00769             # in translated containers we assume the container has default page
00770             # in the correct language.
00771             implemented = ITranslatable.isImplementedBy(obj)
00772             if not implemented or implemented and not obj.isTranslation():
00773                 pageobj = getattr(obj, page, None)
00774                 if pageobj is not None and ITranslatable.isImplementedBy(pageobj):
00775                     translation = pageobj.getTranslation()
00776                     if translation is not None and \
00777                        (not wftool.getChainFor(pageobj) or\
00778                            wftool.getInfoFor(pageobj, 'review_state') == wftool.getInfoFor(translation, 'review_state')):
00779                         if ids.has_key(translation.getId()):
00780                             return obj, [translation.getId()]
00781                         else:
00782                             return translation, ['view']
00783             return obj, [page]
00784 
00785         # The list of ids where we look for default
00786         ids = {}
00787 
00788         # If we are not dealing with a folder, then leave this empty
00789         if obj.isPrincipiaFolderish:
00790             # For BTreeFolders we just use has_key, otherwise build a dict
00791             if base_hasattr(obj, 'has_key'):
00792                 ids = obj
00793             else:
00794                 for id in obj.objectIds():
00795                     ids[id] = 1
00796 
00797         #
00798         # 1. Get an attribute or contained object index_html
00799         #
00800 
00801         # Note: The base PloneFolder, as well as ATCT's ATCTOrderedFolder
00802         # defines a method index_html() which returns a ReplaceableWrapper.
00803         # This is needed for WebDAV to work properly, and to avoid implicit
00804         # acquisition of index_html's, which are generally on-object only.
00805         # For the purposes of determining a default page, we don't want to
00806         # use this index_html(), nor the ComputedAttribute which defines it.
00807 
00808         if not isinstance(getattr(obj, 'index_html', None), ReplaceableWrapper):
00809             index_obj = getattr(aq_base(obj), 'index_html', None)
00810             if index_obj is not None and not isinstance(index_obj, ComputedAttribute):
00811                 return returnPage(obj, 'index_html')
00812 
00813         #
00814         # 2. Look for a default_page managed by an IBrowserDefault-implementing
00815         #    object
00816         #
00817         # 3. Look for a default_page property on the object
00818         #
00819         # 4. Try the default sitewide default_page setting
00820         #
00821 
00822         if obj.isPrincipiaFolderish:
00823             defaultPage = self.getDefaultPage(obj)
00824             if defaultPage is not None:
00825                 if ids.has_key(defaultPage):
00826                     return returnPage(obj, defaultPage)
00827                 # Avoid infinite recursion in the case that the page id == the
00828                 # object id
00829                 elif defaultPage != obj.getId() and \
00830                      defaultPage != '/'.join(obj.getPhysicalPath()):
00831                     # For the default_page property, we may get things in the
00832                     # skin layers or with an explicit path - split this path
00833                     # to comply with the __browser_default__() spec
00834                     return obj, defaultPage.split('/')
00835 
00836         # 5. If there is no default page, try IBrowserDefault.getLayout()
00837 
00838         browserDefault = IBrowserDefault(obj, None)
00839         if browserDefault is not None:
00840             layout = browserDefault.getLayout()
00841             if layout is None:
00842                 raise AttributeError(
00843                     "%s has no assigned layout, perhaps it needs an FTI"%obj)
00844             else:
00845                 return obj, [layout]
00846 
00847         #
00848         # 6. If the object has a 'folderlisting' action, use this
00849         #
00850 
00851         # This allows folders to determine in a flexible manner how they are
00852         # displayed when there is no default page, whilst still using
00853         # browserDefault() to show contained objects by default on the 'view'
00854         # action (this applies to old-style folders only, IBrowserDefault is
00855         # managed explicitly above)
00856 
00857         try:
00858             # XXX: This isn't quite right since it assumes the action
00859             # starts with ${object_url}.  Should we raise an error if
00860             # it doesn't?
00861             act = obj.getTypeInfo().getActionInfo('folder/folderlisting')['url'].split('/')[-1]
00862             return obj, [act]
00863         except ValueError:
00864             pass
00865 
00866         #
00867         # 7. Fall back on the 'view' action
00868         #
00869 
00870         try:
00871             # XXX: This isn't quite right since it assumes the action
00872             # starts with ${object_url}.  Should we raise an error if
00873             # it doesn't?
00874             act = obj.getTypeInfo().getActionInfo('object/view')['url'].split('/')[-1]
00875             return obj, [act]
00876         except ValueError:
00877             pass
00878 
00879         #
00880         # 8. If we can't find this either, raise an exception
00881         #
00882 
00883         raise AttributeError, "Failed to get a default page or view_action for %s" % (obj.absolute_url,)

Here is the call graph for this function:

def CMFPlone.PloneTool.PloneTool.changeOwnershipOf (   self,
  object,
  userid,
  recursive = 0,
  REQUEST = None 
)
Changes the ownership of an object.

Definition at line 432 of file PloneTool.py.

00432 
00433     def changeOwnershipOf(self, object, userid, recursive=0, REQUEST=None):
00434         """Changes the ownership of an object."""
00435         membership = getToolByName(self, 'portal_membership')
00436         acl_users = getattr(self, 'acl_users')
00437         user = acl_users.getUserById(userid)
00438         if user is None:
00439             # The user could be in the top level acl_users folder in
00440             # the Zope root, in which case this should find him:
00441             user = membership.getMemberById(userid)
00442             if user is None:
00443                 raise KeyError, 'Only retrievable users in this site can be made owners.'
00444         object.changeOwnership(user, recursive)
00445 
00446         def fixOwnerRole(object, user_id):
00447             # Get rid of all other owners
00448             owners = object.users_with_local_role('Owner')
00449             for o in owners:
00450                 roles = list(object.get_local_roles_for_userid(o))
00451                 roles.remove('Owner')
00452                 if roles:
00453                     object.manage_setLocalRoles(o, roles)
00454                 else:
00455                     object.manage_delLocalRoles([o])
00456             # Fix for 1750
00457             roles = list(object.get_local_roles_for_userid(user_id))
00458             roles.append('Owner')
00459             object.manage_setLocalRoles(user_id, roles)
00460 
00461         fixOwnerRole(object, user.getId())
00462         if base_hasattr(object, 'reindexObject'):
00463             object.reindexObject()
00464 
00465         if recursive:
00466             catalog_tool = getToolByName(self, 'portal_catalog')
00467             purl = getToolByName(self, 'portal_url')
00468             _path = purl.getRelativeContentURL(object)
00469             subobjects = [b.getObject() for b in \
00470                          catalog_tool(path={'query':_path,'level':1})]
00471             for obj in subobjects:
00472                 fixOwnerRole(obj, user.getId())
00473                 if base_hasattr(obj, 'reindexObject'):
                    obj.reindexObject()

Here is the call graph for this function:

def CMFPlone.PloneTool.PloneTool.contentEdit (   self,
  obj,
  kwargs 
)
Encapsulates how the editing of content occurs.

Definition at line 316 of file PloneTool.py.

00316 
00317     def contentEdit(self, obj, **kwargs):
00318         """Encapsulates how the editing of content occurs."""
00319         try:
00320             self.editMetadata(obj, **kwargs)
00321         except AttributeError, msg:
00322             log('Failure editing metadata at: %s.\n%s\n' %
00323                 (obj.absolute_url(), msg))
00324         if kwargs.get('id', None) is not None:
00325             self._renameObject(obj, id=kwargs['id'].strip())
00326         self._makeTransactionNote(obj)

Here is the call graph for this function:

def CMFPlone.PloneTool.PloneTool.createBreadCrumbs (   self,
  context,
  request = None 
)
Returns a structure for the portal breadcumbs.

Definition at line 550 of file PloneTool.py.

00550 
00551     def createBreadCrumbs(self, context, request=None):
00552         """Returns a structure for the portal breadcumbs.
00553         """
00554         if request is None:
00555             request = self.REQUEST
00556         return utils.createBreadCrumbs(context, request)

def CMFPlone.PloneTool.PloneTool.createNavTree (   self,
  context,
  sitemap = None,
  request = None 
)
Returns a structure that can be used by navigation_tree_slot.

Definition at line 542 of file PloneTool.py.

00542 
00543     def createNavTree(self, context, sitemap=None, request=None):
00544         """Returns a structure that can be used by navigation_tree_slot.
00545         """
00546         if request is None:
00547             request = self.REQUEST
00548         return utils.createNavTree(context, request)

def CMFPlone.PloneTool.PloneTool.createSitemap (   self,
  context,
  request = None 
)
Returns a sitemap navtree structure.

Definition at line 525 of file PloneTool.py.

00525 
00526     def createSitemap(self, context, request=None):
00527         """Returns a sitemap navtree structure.
00528         """
00529         if request is None:
00530             request = self.REQUEST
00531         return utils.createSiteMap(context, request)

def CMFPlone.PloneTool.PloneTool.deleteObjectsByPaths (   self,
  paths,
  handle_errors = True,
  REQUEST = None 
)

Definition at line 1207 of file PloneTool.py.

01207 
01208     def deleteObjectsByPaths(self, paths, handle_errors=True, REQUEST=None):
01209         failure = {}
01210         success = []
01211         # use the portal for traversal in case we have relative paths
01212         portal = getToolByName(self, 'portal_url').getPortalObject()
01213         traverse = portal.restrictedTraverse
01214         for path in paths:
01215             # Skip and note any errors
01216             if handle_errors:
01217                 sp = transaction.savepoint(optimistic=True)
01218             try:
01219                 obj = traverse(path)
01220                 obj_parent = aq_parent(aq_inner(obj))
01221                 obj_parent.manage_delObjects([obj.getId()])
01222                 success.append('%s (%s)' % (obj.title_or_id(), path))
01223             except ConflictError:
01224                 raise
01225             except LinkIntegrityNotificationException:
01226                 raise
01227             except Exception, e:
01228                 if handle_errors:
01229                     sp.rollback()
01230                     failure[path]= e
01231                 else:
01232                     raise
01233         transaction_note('Deleted %s' % (', '.join(success)))
        return success, failure

Here is the call graph for this function:

def CMFPlone.PloneTool.PloneTool.editMetadata (   self,
  obj,
  allowDiscussion = None,
  title = None,
  subject = None,
  description = None,
  contributors = None,
  effective_date = None,
  expiration_date = None,
  format = None,
  language = None,
  rights = None,
  kwargs 
)
Responsible for setting metadata on a content object.

We assume the obj implements IDublinCoreMetadata.

Definition at line 211 of file PloneTool.py.

00211 
00212                      ,  **kwargs):
00213         """Responsible for setting metadata on a content object.
00214 
00215         We assume the obj implements IDublinCoreMetadata.
00216         """
00217         mt = getToolByName(self, 'portal_membership')
00218         if not mt.checkPermission(ModifyPortalContent, obj):
00219             # FIXME: Some scripts rely on this being string?
00220             raise Unauthorized
00221 
00222         REQUEST = self.REQUEST
00223         pfx = self.field_prefix
00224 
00225         def getfield(request, name, default=None, pfx=pfx):
00226             return request.form.get(pfx + name, default)
00227 
00228         def tuplify(value):
00229             return tuple(filter(None, value))
00230 
00231         if DublinCore.isImplementedBy(obj):
00232             if title is None:
00233                 title = getfield(REQUEST, 'title')
00234             if description is None:
00235                 description = getfield(REQUEST, 'description')
00236             if subject is None:
00237                 subject = getfield(REQUEST, 'subject')
00238             if subject is not None:
00239                 subject = tuplify(subject)
00240             if contributors is None:
00241                 contributors = getfield(REQUEST, 'contributors')
00242             if contributors is not None:
00243                 contributors = tuplify(contributors)
00244             if effective_date is None:
00245                 effective_date = getfield(REQUEST, 'effective_date')
00246             if effective_date == '':
00247                 effective_date = 'None'
00248             if expiration_date is None:
00249                 expiration_date = getfield(REQUEST, 'expiration_date')
00250             if expiration_date == '':
00251                 expiration_date = 'None'
00252 
00253         if Discussable.isImplementedBy(obj) or \
00254             getattr(obj, '_isDiscussable', None):
00255             disc_tool = getToolByName(self, 'portal_discussion')
00256             if allowDiscussion is None:
00257                 allowDiscussion = disc_tool.isDiscussionAllowedFor(obj)
00258                 if not safe_hasattr(obj, 'allow_discussion'):
00259                     allowDiscussion = None
00260                 allowDiscussion = REQUEST.get('allowDiscussion', allowDiscussion)
00261             if type(allowDiscussion) == StringType:
00262                 allowDiscussion = allowDiscussion.lower().strip()
00263             if allowDiscussion == 'default':
00264                 allowDiscussion = None
00265             elif allowDiscussion == 'off':
00266                 allowDiscussion = 0
00267             elif allowDiscussion == 'on':
00268                 allowDiscussion = 1
00269             disc_tool.overrideDiscussionFor(obj, allowDiscussion)
00270 
00271         if MutableDublinCore.isImplementedBy(obj):
00272             if title is not None:
00273                 obj.setTitle(title)
00274             if description is not None:
00275                 obj.setDescription(description)
00276             if subject is not None:
00277                 obj.setSubject(subject)
00278             if contributors is not None:
00279                 obj.setContributors(contributors)
00280             if effective_date is not None:
00281                 obj.setEffectiveDate(effective_date)
00282             if expiration_date is not None:
00283                 obj.setExpirationDate(expiration_date)
00284             if format is not None:
00285                 obj.setFormat(format)
00286             if language is not None:
00287                 obj.setLanguage(language)
00288             if rights is not None:
00289                 obj.setRights(rights)
00290             # Make the catalog aware of changes
00291             obj.reindexObject()

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 507 of file PloneTool.py.

00507 
00508     def exceptionString(self):
00509         # Don't assign the traceback to s
00510         # (otherwise will generate a circular reference)
00511         s = sys.exc_info()[:2]
00512         if s[0] == None:
00513             return None
00514         if type(s[0]) == type(''):
00515             return s[0]
00516         return str(s[1])

def CMFPlone.PloneTool.PloneTool.getDefaultPage (   self,
  obj,
  request = None 
)
Given a folderish item, find out if it has a default-page using
the following lookup rules:

    1. A content object called 'index_html' wins
    2. If the folder implements IBrowserDefault, query this
    3. Else, look up the property default_page on the object
- Note that in this case, the returned id may *not* be of an
  object in the folder, since it could be acquired from a
  parent folder or skin layer
    4. Else, look up the property default_page in site_properties for
magic ids and test these

The id of the first matching item is then used to lookup a translation
and if found, its id is returned. If no default page is set, None is
returned. If a non-folderish item is passed in, return None always.

Definition at line 636 of file PloneTool.py.

00636 
00637     def getDefaultPage(self, obj, request=None):
00638         """Given a folderish item, find out if it has a default-page using
00639         the following lookup rules:
00640 
00641             1. A content object called 'index_html' wins
00642             2. If the folder implements IBrowserDefault, query this
00643             3. Else, look up the property default_page on the object
00644                 - Note that in this case, the returned id may *not* be of an
00645                   object in the folder, since it could be acquired from a
00646                   parent folder or skin layer
00647             4. Else, look up the property default_page in site_properties for
00648                 magic ids and test these
00649 
00650         The id of the first matching item is then used to lookup a translation
00651         and if found, its id is returned. If no default page is set, None is
00652         returned. If a non-folderish item is passed in, return None always.
00653         """
00654         if request is None:
00655             request = self.REQUEST
00656         return utils.getDefaultPage(obj, request)

Here is the caller graph for this function:

def CMFPlone.PloneTool.PloneTool.getDiscussionThread (   self,
  discussionContainer 
)
Given a discussionContainer, return the thread it is in, upwards,
including the parent object that is being discussed.

Definition at line 400 of file PloneTool.py.

00400 
00401     def getDiscussionThread(self, discussionContainer):
00402         """Given a discussionContainer, return the thread it is in, upwards,
00403         including the parent object that is being discussed.
00404         """
00405         if safe_hasattr(discussionContainer, 'parentsInThread'):
00406             thread = discussionContainer.parentsInThread()
00407             if discussionContainer.portal_type == 'Discussion Item':
00408                 thread.append(discussionContainer)
00409         else:
00410             if discussionContainer.id=='talkback':
00411                 thread=[discussionContainer._getDiscussable()]
00412             else:
00413                 thread = [discussionContainer]
00414         return thread

Here is the call graph for this function:

def CMFPlone.PloneTool.PloneTool.getEmptyTitle (   self,
  translated = True 
)
Returns string to be used for objects with no title or id.

>>> ptool = self.portal.plone_utils

>>> ptool.getEmptyTitle(translated=False) == u'[\xb7\xb7\xb7]'
True

Definition at line 1174 of file PloneTool.py.

01174 
01175     def getEmptyTitle(self, translated=True):
01176         """ Returns string to be used for objects with no title or id.
01177 
01178         >>> ptool = self.portal.plone_utils
01179 
01180         >>> ptool.getEmptyTitle(translated=False) == u'[\xb7\xb7\xb7]'
01181         True
01182         """
01183         return utils.getEmptyTitle(self, translated)

def CMFPlone.PloneTool.PloneTool.getIconFor (   self,
  category,
  id,
  default = _marker 
)
Cache point for actionicons.getActionIcon call.

Also we want to allow for a default icon id to be passed in.

Definition at line 352 of file PloneTool.py.

00352 
00353     def getIconFor(self, category, id, default=_marker):
00354         """Cache point for actionicons.getActionIcon call.
00355 
00356         Also we want to allow for a default icon id to be passed in.
00357         """
00358         # Short circuit the lookup
00359         if (category, id) in _icons.keys():
00360             return _icons[(category, id)]
00361         try:
00362             actionicons = getToolByName(self, 'portal_actionicons')
00363             iconinfo = actionicons.getActionIcon(category, id)
00364             icon = _icons.setdefault((category, id), iconinfo)
00365         except KeyError:
00366             if default is not _marker:
00367                 icon = default
00368             else:
00369                 raise
00370         # We want to return the actual object
00371         return icon

Here is the call graph for this function:

Returns a tuple with the acquired local roles.

Definition at line 571 of file PloneTool.py.

00571 
00572     def getInheritedLocalRoles(self, here):
00573         """Returns a tuple with the acquired local roles."""
00574         portal = getToolByName(here, 'portal_url').getPortalObject()
00575         result = []
00576         cont = 1
00577         if portal != here:
00578             parent = here.aq_parent
00579             while cont:
00580                 if not getattr(parent, 'acl_users', False):
00581                     break
00582                 userroles = parent.acl_users._getLocalRolesForDisplay(parent)
00583                 for user, roles, role_type, name in userroles:
00584                     # Find user in result
00585                     found = 0
00586                     for user2, roles2, type2, name2 in result:
00587                         if user2 == user:
00588                             # Check which roles must be added to roles2
00589                             for role in roles:
00590                                 if not role in roles2:
00591                                     roles2.append(role)
00592                             found = 1
00593                             break
00594                     if found == 0:
00595                         # Add it to result and make sure roles is a list so
00596                         # we may append and not overwrite the loop variable
00597                         result.append([user, list(roles), role_type, name])
00598                 if parent == portal:
00599                     cont = 0
00600                 elif not self.isLocalRoleAcquired(parent):
00601                     # Role acquired check here
00602                     cont = 0
00603                 else:
00604                     parent = parent.aq_parent
00605 
00606         # Tuplize all inner roles
00607         for pos in range(len(result)-1,-1,-1):
00608             result[pos][1] = tuple(result[pos][1])
00609             result[pos] = tuple(result[pos])
00610 
00611         return tuple(result)

Here is the call graph for this function:

Gets the MailHost.

>>> ptool = self.portal.plone_utils

>>> ptool.getMailHost()
<SecureMailHost ...>

Definition at line 145 of file PloneTool.py.

00145 
00146     def getMailHost(self):
00147         """ Gets the MailHost.
00148 
00149         >>> ptool = self.portal.plone_utils
00150 
00151         >>> ptool.getMailHost()
00152         <SecureMailHost ...>
00153         """
00154         return getattr(aq_parent(self), 'MailHost')

Here is the call graph for this function:

Here is the caller graph for this function:

def CMFPlone.PloneTool.PloneTool.getMethodAliases (   self,
  typeInfo 
)
Given an FTI, return the dict of method aliases defined on that
FTI. If there are no method aliases (i.e. this FTI doesn't support it),
return None

Definition at line 1193 of file PloneTool.py.

01193 
01194     def getMethodAliases(self, typeInfo):
01195         """Given an FTI, return the dict of method aliases defined on that
01196         FTI. If there are no method aliases (i.e. this FTI doesn't support it),
01197         return None"""
01198         getMethodAliases = getattr(typeInfo, 'getMethodAliases', None)
01199         if getMethodAliases is not None and utils.safe_callable(getMethodAliases):
01200             return getMethodAliases()
01201         else:
01202             return None

def CMFPlone.PloneTool.PloneTool.getOwnerName (   self,
  obj 
)
Returns the userid of the owner of an object.

>>> ptool = self.portal.plone_utils
>>> from Products.PloneTestCase.PloneTestCase import default_user

>>> ptool.getOwnerName(self.folder) == default_user
True

Definition at line 943 of file PloneTool.py.

00943 
00944     def getOwnerName(self, obj):
00945         """ Returns the userid of the owner of an object.
00946 
00947         >>> ptool = self.portal.plone_utils
00948         >>> from Products.PloneTestCase.PloneTestCase import default_user
00949 
00950         >>> ptool.getOwnerName(self.folder) == default_user
00951         True
00952         """
00953         mt = getToolByName(self, 'portal_membership')
00954         if not mt.checkPermission(View, obj):
00955             raise Unauthorized
00956         return obj.getOwner().getId()

Here is the call graph for this function:

Utility method that gets the workflow state title for the
object's review_state.

Returns None if no review_state found.

>>> ptool = self.portal.plone_utils

>>> ptool.getReviewStateTitleFor(self.folder).lower()
'public draft'

Definition at line 373 of file PloneTool.py.

00373 
00374     def getReviewStateTitleFor(self, obj):
00375         """Utility method that gets the workflow state title for the
00376         object's review_state.
00377 
00378         Returns None if no review_state found.
00379 
00380         >>> ptool = self.portal.plone_utils
00381 
00382         >>> ptool.getReviewStateTitleFor(self.folder).lower()
00383         'public draft'
00384         """
00385         wf_tool = getToolByName(self, 'portal_workflow')
00386         wfs = ()
00387         review_states = ()
00388         objstate = None
00389         try:
00390             objstate = wf_tool.getInfoFor(obj, 'review_state')
00391             wfs = wf_tool.getWorkflowsFor(obj)
00392         except WorkflowException, e:
00393             pass
00394         if wfs:
00395             for w in wfs:
00396                 if w.states.has_key(objstate):
00397                     return w.states[objstate].title or objstate
00398         return None

Here is the call graph for this function:

Get the default_charset or fallback to utf8.

>>> ptool = self.portal.plone_utils

>>> ptool.getSiteEncoding()
'utf-8'

Definition at line 108 of file PloneTool.py.

00108 
00109     def getSiteEncoding(self):
00110         """ Get the default_charset or fallback to utf8.
00111 
00112         >>> ptool = self.portal.plone_utils
00113 
00114         >>> ptool.getSiteEncoding()
00115         'utf-8'
00116         """
00117         return utils.getSiteEncoding(self)

Here is the caller graph for this function:

def CMFPlone.PloneTool.PloneTool.getUserFriendlyTypes (   self,
  typesList = [] 
)
Get a list of types which are considered "user friendly" for search
and selection purposes.

This is the list of types available in the portal, minus those defines
in the types_not_searched property in site_properties, if it exists.

If typesList is given, this is used as the base list; else all types
from portal_types are used.

Definition at line 1113 of file PloneTool.py.

01113 
01114     def getUserFriendlyTypes(self, typesList=[]):
01115         """Get a list of types which are considered "user friendly" for search
01116         and selection purposes.
01117 
01118         This is the list of types available in the portal, minus those defines
01119         in the types_not_searched property in site_properties, if it exists.
01120 
01121         If typesList is given, this is used as the base list; else all types
01122         from portal_types are used.
01123         """
01124 
01125         ptool = getToolByName(self, 'portal_properties')
01126         siteProperties = getattr(ptool, 'site_properties')
01127         blacklistedTypes = siteProperties.getProperty('types_not_searched', [])
01128 
01129         ttool = getToolByName(self, 'portal_types')
01130         types = typesList or ttool.listContentTypes()
01131 
01132         friendlyTypes = []
01133         for t in types:
01134             if not t in blacklistedTypes and not t in friendlyTypes:
01135                 friendlyTypes.append(t)
01136 
01137         return friendlyTypes

Here is the call graph for this function:

Proxy the request for the chain to the workflow tool, as
this method is private there.

Definition at line 337 of file PloneTool.py.

00337 
00338     def getWorkflowChainFor(self, object):
00339         """Proxy the request for the chain to the workflow tool, as
00340         this method is private there.
00341         """
00342         wftool = getToolByName(self, 'portal_workflow')
00343         wfs = ()
00344         try:
00345             wfs = wftool.getChainFor(object)
00346         except ConflictError:
00347             raise
00348         except:
00349             pass
00350         return wfs

Here is the call graph for this function:

def CMFPlone.PloneTool.PloneTool.good_id (   self,
  id 
)
Exposes ObjectManager's bad_id test to skin scripts.

Definition at line 558 of file PloneTool.py.

00558 
00559     def good_id(self, id):
00560         """Exposes ObjectManager's bad_id test to skin scripts."""
00561         m = bad_id(id)
00562         if m is not None:
00563             return 0
00564         return 1

def CMFPlone.PloneTool.PloneTool.isDefaultPage (   self,
  obj,
  request = None 
)
Finds out if the given obj is the default page in its parent folder.

Only considers explicitly contained objects, either set as index_html,
with the default_page property, or using IBrowserDefault.

Definition at line 625 of file PloneTool.py.

00625 
00626     def isDefaultPage(self, obj, request=None):
00627         """Finds out if the given obj is the default page in its parent folder.
00628 
00629         Only considers explicitly contained objects, either set as index_html,
00630         with the default_page property, or using IBrowserDefault.
00631         """
00632         if request is None:
00633             request = self.REQUEST
00634         return utils.isDefaultPage(obj, request)

Determine if an id is autogenerated

Definition at line 1169 of file PloneTool.py.

01169 
01170     def isIDAutoGenerated(self, id):
01171         """Determine if an id is autogenerated"""
01172         return utils.isIDAutoGenerated(self, id)

Returns local role acquisition blocking status.

True if normal, false if blocked.

Definition at line 933 of file PloneTool.py.

00933 
00934     def isLocalRoleAcquired(self, obj):
00935         """Returns local role acquisition blocking status.
00936 
00937         True if normal, false if blocked.
00938         """
00939         if getattr(obj, '__ac_local_roles_block__', None):
00940             return False
00941         return True

Here is the caller graph for this function:

Checks if a given object is a "structural folder".

That is, a folderish item which does not explicitly implement
INonStructuralFolder to declare that it doesn't wish to be treated
as a folder by the navtree, the tab generation etc.

>>> ptool = self.portal.plone_utils

>>> ptool.isStructuralFolder(self.folder)
True

Definition at line 890 of file PloneTool.py.

00890 
00891     def isStructuralFolder(self, obj):
00892         """Checks if a given object is a "structural folder".
00893 
00894         That is, a folderish item which does not explicitly implement
00895         INonStructuralFolder to declare that it doesn't wish to be treated
00896         as a folder by the navtree, the tab generation etc.
00897 
00898         >>> ptool = self.portal.plone_utils
00899 
00900         >>> ptool.isStructuralFolder(self.folder)
00901         True
00902         """
00903         if not obj.isPrincipiaFolderish:
00904             return False
00905         elif INonStructuralFolder.providedBy(obj):
00906             return False
00907         else:
00908             return True

Checks if a given object implements the ITranslatable interface.

Definition at line 885 of file PloneTool.py.

00885 
00886     def isTranslatable(self, obj):
00887         """Checks if a given object implements the ITranslatable interface."""
00888         return ITranslatable.isImplementedBy(obj)

def CMFPlone.PloneTool.PloneTool.listMetaTags (   self,
  context 
)
Lists meta tags helper.

Creates a mapping of meta tags -> values for the listMetaTags script.

Definition at line 1029 of file PloneTool.py.

01029 
01030     def listMetaTags(self, context):
01031         """Lists meta tags helper.
01032 
01033         Creates a mapping of meta tags -> values for the listMetaTags script.
01034         """
01035         result = {}
01036         site_props = getToolByName(self, 'portal_properties').site_properties
01037         use_all = site_props.getProperty('exposeDCMetaTags', None)
01038 
01039         if not use_all:
01040             metadata_names = {'Description': METADATA_DCNAME['Description']}
01041         else:
01042             metadata_names = METADATA_DCNAME
01043 
01044         for accessor, key in metadata_names.items():
01045             method = getattr(aq_inner(context).aq_explicit, accessor, None)
01046             if not callable(method):
01047                 continue
01048 
01049             # Catch AttributeErrors raised by some AT applications
01050             try:
01051                 value = method()
01052             except AttributeError:
01053                 value = None
01054 
01055             if not value:
01056                 # No data
01057                 continue
01058             if accessor == 'Publisher' and value == 'No publisher':
01059                 # No publisher is hardcoded (TODO: still?)
01060                 continue
01061             if isinstance(value, (list, tuple)):
01062                 # convert a list to a string
01063                 value = ', '.join(value)
01064 
01065             # Special cases
01066             if accessor == 'Description':
01067                 result['description'] = value
01068             elif accessor == 'Subject':
01069                 result['keywords'] = value
01070 
01071             if use_all:
01072                 result[key] = value
01073 
01074         if use_all:
01075             created = context.CreationDate()
01076 
01077             try:
01078                 effective = context.EffectiveDate()
01079                 if effective == 'None':
01080                     effective = None
01081                 if effective:
01082                     effective = DateTime(effective)
01083             except AttributeError:
01084                 effective = None
01085 
01086             try:
01087                 expires = context.ExpirationDate()
01088                 if expires == 'None':
01089                     expires = None
01090                 if expires:
01091                     expires = DateTime(expires)
01092             except AttributeError:
01093                 expires = None
01094 
01095             # Filter out DWIMish artifacts on effective / expiration dates
01096             if effective is not None and \
01097                effective > FLOOR_DATE and \
01098                effective != created:
01099                 eff_str = effective.Date()
01100             else:
01101                 eff_str = ''
01102 
01103             if expires is not None and expires < CEILING_DATE:
01104                 exp_str = expires.Date()
01105             else:
01106                 exp_str = ''
01107 
01108             if exp_str or exp_str:
01109                 result['DC.date.valid_range'] = '%s - %s' % (eff_str, exp_str)
01110 
01111         return result

Here is the call graph for this function:

Dumps most recent exception to the log.

Definition at line 519 of file PloneTool.py.

00519 
00520     def logException(self):
00521         """Dumps most recent exception to the log.
00522         """
00523         log_exc()

def CMFPlone.PloneTool.PloneTool.normalizeString (   self,
  text,
  relaxed = False 
)
Normalizes a title to an id.

normalizeString() converts a whole string to a normalized form that
should be safe to use as in a url, as a css id, etc.

If relaxed=True, only those characters that are illegal as URLs and
leading or trailing whitespace is stripped.

>>> ptool = self.portal.plone_utils

>>> ptool.normalizeString("Foo bar")
'foo-bar'

>>> ptool.normalizeString("Foo bar", relaxed=True)
'Foo bar'

>>> ptool.normalizeString("Some!_are allowed, others&?:are not")
'some-_are-allowed-others-are-not'

>>> ptool.normalizeString("Some!_are allowed, others&?:are not")
'some-_are-allowed-others-are-not'

all punctuation and spacing is removed and replaced with a '-':

>>> ptool.normalizeString("a string with spaces")
'a-string-with-spaces'

>>> ptool.normalizeString("p.u,n;c(t)u!a@t#i$o%n")
'p-u-n-c-t-u-a-t-i-o-n'

strings are lowercased:

>>> ptool.normalizeString("UppERcaSE")
'uppercase'

punctuation, spaces, etc. are trimmed and multiples are reduced to just
one:

>>> ptool.normalizeString(" a string    ")
'a-string'
>>> ptool.normalizeString(">here's another!")
'heres-another'

>>> ptool.normalizeString("one with !@#$!@#$ stuff in the middle")
'one-with-stuff-in-the-middle'

the exception to all this is that if there is something that looks like a
filename with an extension at the end, it will preserve the last period.

>>> ptool.normalizeString("this is a file.gif")
'this-is-a-file.gif'

>>> ptool.normalizeString("this is. also. a file.html")
'this-is-also-a-file.html'

normalizeString() uses normalizeUnicode() to convert stray unicode
characters. it will attempt to transliterate many of the accented
letters to rough ASCII equivalents for characters that we can't
transliterate, we just return the hex codes of the byte(s) in the
character. not pretty, but about the best we can do.

>>> ptool.normalizeString(u"\u9ad8\u8054\u5408 Chinese")
'9ad880545408-chinese'

>>> ptool.normalizeString(u"\uc774\ubbf8\uc9f1 Korean")
'c774bbf8c9f1-korean'

Definition at line 958 of file PloneTool.py.

00958 
00959     def normalizeString(self, text, relaxed=False):
00960         """Normalizes a title to an id.
00961 
00962         normalizeString() converts a whole string to a normalized form that
00963         should be safe to use as in a url, as a css id, etc.
00964         
00965         If relaxed=True, only those characters that are illegal as URLs and
00966         leading or trailing whitespace is stripped.
00967 
00968         >>> ptool = self.portal.plone_utils
00969 
00970         >>> ptool.normalizeString("Foo bar")
00971         'foo-bar'
00972 
00973         >>> ptool.normalizeString("Foo bar", relaxed=True)
00974         'Foo bar'
00975         
00976         >>> ptool.normalizeString("Some!_are allowed, others&?:are not")
00977         'some-_are-allowed-others-are-not'
00978 
00979         >>> ptool.normalizeString("Some!_are allowed, others&?:are not")
00980         'some-_are-allowed-others-are-not'
00981 
00982         all punctuation and spacing is removed and replaced with a '-':
00983 
00984         >>> ptool.normalizeString("a string with spaces")
00985         'a-string-with-spaces'
00986 
00987         >>> ptool.normalizeString("p.u,n;c(t)u!a@t#i$o%n")
00988         'p-u-n-c-t-u-a-t-i-o-n'
00989 
00990         strings are lowercased:
00991 
00992         >>> ptool.normalizeString("UppERcaSE")
00993         'uppercase'
00994 
00995         punctuation, spaces, etc. are trimmed and multiples are reduced to just
00996         one:
00997 
00998         >>> ptool.normalizeString(" a string    ")
00999         'a-string'
01000         >>> ptool.normalizeString(">here's another!")
01001         'heres-another'
01002 
01003         >>> ptool.normalizeString("one with !@#$!@#$ stuff in the middle")
01004         'one-with-stuff-in-the-middle'
01005 
01006         the exception to all this is that if there is something that looks like a
01007         filename with an extension at the end, it will preserve the last period.
01008 
01009         >>> ptool.normalizeString("this is a file.gif")
01010         'this-is-a-file.gif'
01011 
01012         >>> ptool.normalizeString("this is. also. a file.html")
01013         'this-is-also-a-file.html'
01014 
01015         normalizeString() uses normalizeUnicode() to convert stray unicode
01016         characters. it will attempt to transliterate many of the accented
01017         letters to rough ASCII equivalents for characters that we can't
01018         transliterate, we just return the hex codes of the byte(s) in the
01019         character. not pretty, but about the best we can do.
01020 
01021         >>> ptool.normalizeString(u"\u9ad8\u8054\u5408 Chinese")
01022         '9ad880545408-chinese'
01023 
01024         >>> ptool.normalizeString(u"\uc774\ubbf8\uc9f1 Korean")
01025         'c774bbf8c9f1-korean'
01026         """
01027         return utils.normalizeString(text, context=self, relaxed=relaxed)

def CMFPlone.PloneTool.PloneTool.portal_utf8 (   self,
  str,
  errors = 'strict' 
)
Transforms an string in portal encoding to utf8.

>>> ptool = self.portal.plone_utils
>>> text = u'Eksempel \xe6\xf8\xe5'
>>> sitetext = text.encode(ptool.getSiteEncoding())

>>> ptool.portal_utf8(sitetext) == text.encode('utf-8')
True

Definition at line 119 of file PloneTool.py.

00119 
00120     def portal_utf8(self, str, errors='strict'):
00121         """ Transforms an string in portal encoding to utf8.
00122 
00123         >>> ptool = self.portal.plone_utils
00124         >>> text = u'Eksempel \xe6\xf8\xe5'
00125         >>> sitetext = text.encode(ptool.getSiteEncoding())
00126 
00127         >>> ptool.portal_utf8(sitetext) == text.encode('utf-8')
00128         True
00129         """
00130         return utils.portal_utf8(self, str, errors)

def CMFPlone.PloneTool.PloneTool.pretty_title_or_id (   self,
  obj,
  empty_value = _marker 
)
Return the best possible title or id of an item, regardless
of whether obj is a catalog brain or an object, but returning an
empty title marker if the id is not set (i.e. it's auto-generated).

Definition at line 1185 of file PloneTool.py.

01185 
01186     def pretty_title_or_id(self, obj, empty_value=_marker):
01187         """Return the best possible title or id of an item, regardless
01188         of whether obj is a catalog brain or an object, but returning an
01189         empty title marker if the id is not set (i.e. it's auto-generated).
01190         """
01191         return utils.pretty_title_or_id(self, obj, empty_value=empty_value)

def CMFPlone.PloneTool.PloneTool.reindexOnReorder (   self,
  parent 
)
Catalog ordering support 

Definition at line 1139 of file PloneTool.py.

01139 
01140     def reindexOnReorder(self, parent):
01141         """ Catalog ordering support """
01142 
01143         # For now we will just reindex all objects in the folder. Later we may
01144         # optimize to only reindex the objs that got moved. Ordering is more
01145         # for humans than machines, therefore the fact that this won't scale
01146         # well for btrees isn't a huge issue, since btrees are more for
01147         # machines than humans.
01148         mtool = getToolByName(self, 'portal_membership')
01149         if not mtool.checkPermission(ModifyPortalContent, parent):
01150             return
01151         cat = getToolByName(self, 'portal_catalog')
01152         cataloged_objs = cat(path = {'query':'/'.join(parent.getPhysicalPath()),
01153                                      'depth': 1})
01154         for brain in cataloged_objs:
01155             # Don't crash when the catalog contains a stale entry
01156             try:
01157                 obj = brain.getObject()
01158             except KeyError: # getObject raises since Zope 2.8
01159                 obj = None
01160 
01161             if obj is not None:
01162                 cat.reindexObject(obj,['getObjPositionInParent'],
01163                                                     update_metadata=0)
01164             else:
01165                 # Perhaps we should remove the bad entry as well?
01166                 log('Object in catalog no longer exists, cannot reindex: %s.'%
01167                                     brain.getPath())

Here is the call graph for this function:

def CMFPlone.PloneTool.PloneTool.renameObjectsByPaths (   self,
  paths,
  new_ids,
  new_titles,
  handle_errors = True,
  REQUEST = None 
)

Definition at line 1275 of file PloneTool.py.

01275 
01276                              handle_errors=True, REQUEST=None):
01277         failure = {}
01278         success = {}
01279         # use the portal for traversal in case we have relative paths
01280         portal = getToolByName(self, 'portal_url').getPortalObject()
01281         traverse = portal.restrictedTraverse
01282         for i, path in enumerate(paths):
01283             new_id = new_ids[i]
01284             new_title = new_titles[i]
01285             if handle_errors:
01286                 sp = transaction.savepoint(optimistic=True)
01287             try:
01288                 obj = traverse(path, None)
01289                 obid = obj.getId()
01290                 title = obj.Title()
01291                 change_title = new_title and title != new_title
01292                 changed = False
01293                 if change_title:
01294                     obj.setTitle(new_title)
01295                     changed = True
01296                 if new_id and obid != new_id:
01297                     parent = aq_parent(aq_inner(obj))
01298                     parent.manage_renameObjects((obid,), (new_id,))
01299                     changed = True
01300                 elif change_title:
01301                     # the rename will have already triggered a reindex
01302                     obj.reindexObject()
01303                 if changed:
01304                     success[path]=(new_id,new_title)
01305             except ConflictError:
01306                 raise
01307             except Exception, e:
01308                 if handle_errors:
01309                     # skip this object but continue with sub-objects.
01310                     sp.rollback()
01311                     failure[path]= e
01312                 else:
01313                     raise
01314         transaction_note('Renamed %s' % str(success.keys()))
        return success, failure

Here is the call graph for this function:

def CMFPlone.PloneTool.PloneTool.sendto (   self,
  send_to_address,
  send_from_address,
  comment,
  subject = 'Plone',
  kwargs 
)
Sends a link of a page to someone.

Definition at line 157 of file PloneTool.py.

00157 
00158                subject='Plone', **kwargs):
00159         """Sends a link of a page to someone."""
00160         host = self.getMailHost()
00161         template = getattr(self, 'sendto_template')
00162         portal = getToolByName(self, 'portal_url').getPortalObject()
00163         encoding = portal.getProperty('email_charset')
00164         if 'envelope_from' in kwargs:
00165             envelope_from = kwargs['envelope_from']
00166         else:
00167             envelope_from = send_from_address
00168         # Cook from template
00169         message = template(self, send_to_address=send_to_address,
00170                            send_from_address=send_from_address,
00171                            comment=comment, subject=subject, **kwargs)
00172         result = host.secureSend(message, send_to_address,
00173                                  envelope_from, subject=subject,
00174                                  subtype='plain', charset=encoding,
00175                                  debug=False, From=send_from_address)

Here is the call graph for this function:

Here is the caller graph for this function:

def CMFPlone.PloneTool.PloneTool.setCurrentSkin (   self,
  skin_name 
)
Sets the current skin.

Definition at line 426 of file PloneTool.py.

00426 
00427     def setCurrentSkin(self, skin_name):
00428         """Sets the current skin."""
00429         portal = getToolByName(self, 'portal_url').getPortalObject()
00430         portal.changeSkin(skin_name)

Here is the call graph for this function:

def CMFPlone.PloneTool.PloneTool.setDefaultSkin (   self,
  default_skin 
)
Sets the default skin.

Definition at line 418 of file PloneTool.py.

00418 
00419     def setDefaultSkin(self, default_skin):
00420         """Sets the default skin."""
00421         st = getToolByName(self, 'portal_skins')
00422         st.default_skin = default_skin

Here is the call graph for this function:

def CMFPlone.PloneTool.PloneTool.setMemberProperties (   self,
  member,
  REQUEST = None,
  properties 
)

Definition at line 100 of file PloneTool.py.

00100 
00101     def setMemberProperties(self, member, REQUEST=None, **properties):
00102         pas = getToolByName(self, 'acl_users')
00103         if safe_hasattr(member, 'getId'):
00104             member = member.getId()
00105         user = pas.getUserById(member)
00106         user.setProperties(**properties)

Here is the call graph for this function:

def CMFPlone.PloneTool.PloneTool.showPortalMessages (   self,
  request = None 
)
\
Return portal status messages that will be displayed when the
response web page is rendered. Portal status messages are by default
rendered by the global_statusmessage.pt page template. They will be
removed after they have been shown.

See addPortalMessages for examples.

Definition at line 696 of file PloneTool.py.

00696 
00697     def showPortalMessages(self, request=None):
00698         """\
00699         Return portal status messages that will be displayed when the
00700         response web page is rendered. Portal status messages are by default
00701         rendered by the global_statusmessage.pt page template. They will be
00702         removed after they have been shown.
00703         
00704         See addPortalMessages for examples.
00705         """
00706         if request is None:
00707             request = self.REQUEST
00708         return IStatusMessage(request).showStatusMessages()

def CMFPlone.PloneTool.PloneTool.transitionObjectsByPaths (   self,
  workflow_action,
  paths,
  comment = '',
  expiration_date = None,
  effective_date = None,
  include_children = False,
  handle_errors = True,
  REQUEST = None 
)

Definition at line 1240 of file PloneTool.py.

01240 
01241                                  REQUEST=None):
01242         failure = {}
01243         # use the portal for traversal in case we have relative paths
01244         portal = getToolByName(self, 'portal_url').getPortalObject()
01245         traverse = portal.restrictedTraverse
01246         for path in paths:
01247             if handle_errors:
01248                 sp = transaction.savepoint(optimistic=True)
01249             try:
01250                 o = traverse(path, None)
01251                 if o is not None:
01252                     o.content_status_modify(workflow_action,
01253                                             comment,
01254                                             effective_date=effective_date,
01255                                             expiration_date=expiration_date)
01256             except ConflictError:
01257                 raise
01258             except Exception, e:
01259                 if handle_errors:
01260                     # skip this object but continue with sub-objects.
01261                     sp.rollback()
01262                     failure[path]= e
01263                 else:
01264                     raise
01265             if getattr(o, 'isPrincipiaFolderish', None) and include_children:
01266                 subobject_paths = ["%s/%s" % (path, id) for id in o.objectIds()]
01267                 self.transitionObjectsByPaths(workflow_action, subobject_paths,
01268                                               comment, expiration_date,
01269                                               effective_date, include_children,
01270                                               handle_errors)
        return failure

Here is the call graph for this function:

Definition at line 538 of file PloneTool.py.

00538 
00539     def typesToList(self):
00540         return utils.typesToList(self)

def CMFPlone.PloneTool.PloneTool.urlparse (   self,
  url 
)
Returns the pieces of url in a six-part tuple.

See Python standard library urlparse.urlparse:
http://python.org/doc/lib/module-urlparse.html

>>> ptool = self.portal.plone_utils

>>> ptool.urlparse('http://dev.plone.org/plone/query?milestone=2.1#foo')
('http', 'dev.plone.org', '/plone/query', '', 'milestone=2.1', 'foo')

Definition at line 477 of file PloneTool.py.

00477 
00478     def urlparse(self, url):
00479         """Returns the pieces of url in a six-part tuple.
00480 
00481         See Python standard library urlparse.urlparse:
00482         http://python.org/doc/lib/module-urlparse.html
00483 
00484         >>> ptool = self.portal.plone_utils
00485 
00486         >>> ptool.urlparse('http://dev.plone.org/plone/query?milestone=2.1#foo')
00487         ('http', 'dev.plone.org', '/plone/query', '', 'milestone=2.1', 'foo')
00488         """
00489         return urlparse.urlparse(url)

def CMFPlone.PloneTool.PloneTool.urlunparse (   self,
  url_tuple 
)
Puts a url back together again, in the manner that
urlparse breaks it.

See also Python standard library: urlparse.urlunparse:
http://python.org/doc/lib/module-urlparse.html

>>> ptool = self.portal.plone_utils

>>> ptool.urlunparse(('http', 'plone.org', '/support', '', '', 'users'))
'http://plone.org/support#users'

Definition at line 491 of file PloneTool.py.

00491 
00492     def urlunparse(self, url_tuple):
00493         """Puts a url back together again, in the manner that
00494         urlparse breaks it.
00495 
00496         See also Python standard library: urlparse.urlunparse:
00497         http://python.org/doc/lib/module-urlparse.html
00498 
00499         >>> ptool = self.portal.plone_utils
00500 
00501         >>> ptool.urlunparse(('http', 'plone.org', '/support', '', '', 'users'))
00502         'http://plone.org/support#users'
00503         """
00504         return urlparse.urlunparse(url_tuple)

def CMFPlone.PloneTool.PloneTool.utf8_portal (   self,
  str,
  errors = 'strict' 
)
Transforms an utf8 string to portal encoding.

>>> ptool = self.portal.plone_utils
>>> text = u'Eksempel \xe6\xf8\xe5'
>>> utf8text = text.encode('utf-8')

>>> ptool.utf8_portal(utf8text) == text.encode(ptool.getSiteEncoding())
True

Definition at line 132 of file PloneTool.py.

00132 
00133     def utf8_portal(self, str, errors='strict'):
00134         """ Transforms an utf8 string to portal encoding.
00135 
00136         >>> ptool = self.portal.plone_utils
00137         >>> text = u'Eksempel \xe6\xf8\xe5'
00138         >>> utf8text = text.encode('utf-8')
00139 
00140         >>> ptool.utf8_portal(utf8text) == text.encode(ptool.getSiteEncoding())
00141         True
00142         """
00143         return utils.utf8_portal(self, str, errors)

def CMFPlone.PloneTool.PloneTool.validateEmailAddresses (   self,
  addresses 
)
Validate a list of possibly several email addresses, see also
validateSingleEmailAddress.

Definition at line 191 of file PloneTool.py.

00191 
00192     def validateEmailAddresses(self, addresses):
00193         """Validate a list of possibly several email addresses, see also
00194         validateSingleEmailAddress.
00195         """
00196         host = self.getMailHost()
00197         return host.validateEmailAddresses(addresses)

Here is the call graph for this function:

Validate a single email address, see also validateEmailAddresses.

Definition at line 185 of file PloneTool.py.

00185 
00186     def validateSingleEmailAddress(self, address):
00187         """Validate a single email address, see also validateEmailAddresses."""
00188         host = self.getMailHost()
00189         return host.validateSingleEmailAddress(address)

Here is the call graph for this function:

Lower-level function to validate a single normalized email address,
see validateEmailAddress.

Definition at line 177 of file PloneTool.py.

00177 
00178     def validateSingleNormalizedEmailAddress(self, address):
00179         """Lower-level function to validate a single normalized email address,
00180         see validateEmailAddress.
00181         """
00182         host = self.getMailHost()
00183         return host.validateSingleNormalizedEmailAddress(address)

Here is the call graph for this function:


Member Data Documentation

Initial value:
(PloneBaseTool.__implements__,
                      SimpleItem.__implements__, )

Definition at line 96 of file PloneTool.py.

Definition at line 930 of file PloneTool.py.

Definition at line 474 of file PloneTool.py.

Definition at line 1234 of file PloneTool.py.

string CMFPlone.PloneTool.PloneTool.field_prefix = 'field_' [static]

Definition at line 92 of file PloneTool.py.

string CMFPlone.PloneTool.PloneTool.id = 'plone_utils' [static]

Definition at line 86 of file PloneTool.py.

Definition at line 87 of file PloneTool.py.

Definition at line 90 of file PloneTool.py.

Definition at line 1315 of file PloneTool.py.

tuple CMFPlone.PloneTool.PloneTool.security = ClassSecurityInfo() [static]

Definition at line 89 of file PloneTool.py.

string CMFPlone.PloneTool.PloneTool.toolicon = 'skins/plone_images/site_icon.gif' [static]

Definition at line 88 of file PloneTool.py.

Definition at line 1271 of file PloneTool.py.


The documentation for this class was generated from the following file: