Back to index

plone3  3.1.7
nextprevious.py
Go to the documentation of this file.
00001 from zope.interface import implements
00002 from zope.component import adapts
00003 
00004 from plone.app.layout.nextprevious.interfaces import INextPreviousProvider
00005 from Products.ATContentTypes.interface.folder import IATFolder
00006 
00007 from plone.memoize.instance import memoize
00008 
00009 from Acquisition import aq_base
00010 from Products.CMFCore.utils import getToolByName
00011 
00012 class ATFolderNextPrevious(object):
00013     """Let a folder act as a next/previous provider. This will be 
00014     automatically found by the @@plone_nextprevious_view and viewlet.
00015     """
00016 
00017     implements(INextPreviousProvider)
00018     adapts(IATFolder)
00019 
00020     def __init__(self, context):
00021         self.context  = context
00022         
00023         sp = getToolByName(self.context, 'portal_properties').site_properties
00024         self.view_action_types = sp.getProperty('typesUseViewActionInListings', ())
00025 
00026     def getNextItem(self, obj):
00027         relatives = self.itemRelatives(obj.getId())
00028         return relatives["next"]
00029         
00030     def getPreviousItem(self, obj):
00031         relatives = self.itemRelatives(obj.getId())
00032         return relatives["previous"]
00033 
00034     @property
00035     def enabled(self):
00036         return self.context.getNextPreviousEnabled()
00037 
00038     @memoize
00039     def itemRelatives(self, oid):
00040         """Get the relative next and previous items
00041         """
00042         folder   = self.context
00043         catalog  = getToolByName(self.context, 'portal_catalog')
00044         position = folder.getObjectPosition(oid)
00045 
00046         previous = None
00047         next     = None
00048 
00049         # Get the previous item
00050         if position - 1 >= 0:
00051             prev_brain = catalog(self.buildNextPreviousQuery(position   = position - 1,
00052                                                              range      = 'max',
00053                                                              sort_order = 'reverse'))
00054             if prev_brain and len(prev_brain) > 0:
00055                 previous = self.buildNextPreviousItem(prev_brain[0])
00056 
00057 
00058         # Get the next item
00059         if (position + 1) < len(folder._objects):
00060             next_brain = catalog(self.buildNextPreviousQuery(position   = position + 1,
00061                                                              range      = 'min'))
00062             
00063             if next_brain and len(next_brain) > 0:
00064                 next   = self.buildNextPreviousItem(next_brain[0])
00065 
00066 
00067         nextPrevious = {
00068             'next'      : next,
00069             'previous'  : previous,
00070             }
00071 
00072         return nextPrevious
00073         
00074     def buildNextPreviousQuery(self, position, range, sort_order = None):
00075         sort_on                  = 'getObjPositionInParent'
00076         
00077         query                    = {}
00078         query['sort_on']         = sort_on
00079         query['sort_limit']      = 1
00080         query['path']            = dict(query = '/'.join(self.context.getPhysicalPath()),
00081                                         depth = 1)
00082                 
00083         # Query the position using a range
00084         if position == 0:
00085             query[sort_on]       = 0
00086         else:
00087             query[sort_on]       = dict(query = position, range = range)
00088 
00089         # Filters on content
00090         query['is_default_page'] = False
00091         query['is_folderish']    = False
00092 
00093         # Should I sort in any special way ?
00094         if sort_order:
00095             query['sort_order']  = sort_order
00096 
00097         return query
00098 
00099 
00100     def buildNextPreviousItem(self, brain):
00101         return {'id'          : brain.getId,
00102                 'url'         : self.getViewUrl(brain),
00103                 'title'       : brain.Title,
00104                 'description' : brain.Description,
00105                 'portal_type' : brain.portal_type,
00106                 }
00107 
00108     def getViewUrl(self, brain):
00109         """create link and support contents that requires /view 
00110         """
00111         item_url = brain.getURL()
00112     
00113         if brain.portal_type in self.view_action_types:
00114             item_url += '/view'
00115     
00116         return item_url