Changeset 1039
- Timestamp:
- 02/05/08 08:43:01
- Files:
-
- SimpleBlog/trunk (modified) (1 prop)
- SimpleBlog/trunk/Extensions/migration.py (copied) (copied from SimpleBlog/branches/optimizations/Extensions/migration.py)
- SimpleBlog/trunk/SimpleBlogTool.py (modified) (22 diffs)
- SimpleBlog/trunk/content/blog.py (modified) (8 diffs)
- SimpleBlog/trunk/content/blogentry.py (modified) (10 diffs)
- SimpleBlog/trunk/content/blogfolder.py (modified) (3 diffs)
- SimpleBlog/trunk/docs/readme.txt (modified) (1 diff)
- SimpleBlog/trunk/skins/SimpleBlog/SimpleBlog_macros.pt (modified) (3 diffs)
- SimpleBlog/trunk/skins/SimpleBlog/blog_navigation_macros.pt (copied) (copied from SimpleBlog/branches/optimizations/skins/SimpleBlog/blog_navigation_macros.pt)
- SimpleBlog/trunk/skins/SimpleBlog/simpleblog_portlet_macros.pt (modified) (3 diffs)
- SimpleBlog/trunk/skins/SimpleBlog/simpleblog_standalone.pt (deleted)
- SimpleBlog/trunk/skins/SimpleBlog/simpleblog_view.pt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
SimpleBlog/trunk
- Property svnmerge-integrated changed from /SimpleBlog/branches/optimizations:1-814 to /SimpleBlog/branches/optimizations:1-1037
SimpleBlog/trunk/SimpleBlogTool.py
r694 r1039 18 18 meta_type= 'SimpleBlog manager' 19 19 plone_tool = 1 20 20 21 21 manage_options=PropertyManager.manage_options 22 22 23 23 security = ClassSecurityInfo() 24 24 calendar_types=['BlogEntry'] 25 25 use_session="" 26 26 27 27 def __init__(self): 28 28 self.manage_addProperty('publishedState', 'published', 'string') … … 76 76 except: 77 77 return [] 78 78 79 79 def _getCreatePortletOnBlogCreation(self): 80 80 try: … … 100 100 101 101 self.globalCategories=value 102 102 103 103 security.declarePublic('getPublishedState') 104 104 def getPublishedState(self): 105 105 return self._getState() 106 107 106 108 107 security.declarePublic('getMaxItemsInPortlet') 109 108 def getMaxItemsInPortlet(self): 110 109 return self._getMaxItemsInPortlet() 111 110 112 111 security.declarePublic('getFrontPage') 113 112 def getFrontPage(self, context): … … 127 126 break 128 127 parent=parent.aq_parent 129 128 130 129 if found==1: 131 130 return parent … … 142 141 """ 143 142 plone_utils = getToolByName(context, 'plone_utils') 144 143 145 144 startpoint = self.getFrontPage(context) 146 145 if not startpoint: … … 152 151 else: 153 152 return startpoint 154 153 155 154 security.declarePublic('getAvailableCategories') 156 155 def getAvailableCategories(self, context, startpoint=None): … … 162 161 # if we are higher in the tree than any Blog then we will end up in the portalobject itself 163 162 # in that case we just search for categories starting in context. 164 165 163 if not startpoint: 166 164 startpoint = self.getStartpoint(context, fromHere=0) 167 168 # now we have the starting point for our search 169 170 result = startpoint.portal_catalog.searchResults(meta_type=['BlogFolder', 'Blog'], path={'query':self.getObjectPath(startpoint),'level':0}) 171 172 # now fetch all the available categories 173 categories=[] 174 for o in result: 175 obj=o.getObject() 176 cats = obj.getCategories() 177 for c in cats: 178 if not c in categories: 179 categories.append(c) 180 181 # add the global categories 182 for c in self.getGlobalCategories(): 183 if not c in categories: 184 categories.append(c) 185 165 categories = context.portal_catalog.uniqueValuesFor('EntryCategory') 166 path = self.getObjectPath(startpoint) 167 186 168 # now we have a list of unique categories available from startpoint and deeper in tree 187 169 # next step is to count the number of entries for each category 188 170 rescats={} 189 for c in categories: 190 result = startpoint.portal_catalog.searchResults(review_state=self._getState(), meta_type='BlogEntry', EntryCategory=c, path={'query':self.getObjectPath(startpoint),'level':0}) 191 rescats[c]=len(result) 171 [rescats.update({c:0}) for c in categories] 172 result = startpoint.portal_catalog.searchResults(review_state=self._getState(), meta_type='BlogEntry', path={'query':path,'level':0}) 173 174 for r in result: 175 for c in r.EntryCategory: rescats[c] = rescats[c]+1 176 for c,n in rescats.items(): 177 if n==0: del rescats[c] 192 178 return rescats 193 179 194 180 security.declarePublic('getSortedKeys') 195 181 def getSortedKeys(self, dict): … … 197 183 keys.sort() 198 184 return keys 199 185 200 186 security.declarePublic('getGlobalCategories') 201 187 def getGlobalCategories(self): 202 188 return self._getGlobalCategories() 203 189 204 190 security.declarePublic('getStartpoint') 205 191 def getStartpoint(self, context, fromHere=0): … … 216 202 break 217 203 parent=parent.aq_parent 218 204 219 205 if found==1: 220 206 startpoint=parent … … 228 214 229 215 return startpoint 230 216 231 217 security.declarePublic('searchForEntries') 232 218 def searchForEntries(self, context, category=None, maxResults=None, fromHere=0, filterState=1, **kwargs): … … 234 220 # leave it to None to get the max from the properties 235 221 # set fromHere=1 to search from the current location. Is used for BlogFolders 236 222 237 223 # first, get the context right 238 224 # when inside a Blog: search for the frontpage 239 225 # when outside a Blog: use context (or its container) 240 226 241 227 #filterState controls whether you want to return only published entries 242 228 243 229 startpoint = self.getStartpoint(context, fromHere) 244 # now we have the starting point for our search245 246 230 query=kwargs 247 248 231 publishedState = self._getState() 249 250 232 if category!=None: 251 233 query['EntryCategory']=category 252 234 253 query['getAlwaysOnTop']=1254 255 235 if filterState: 256 236 query['review_state']=publishedState 257 237 258 259 resultsTop = startpoint.portal_catalog.searchResults(query, meta_type='BlogEntry', path={'query':self.getObjectPath(startpoint),'level':0}, sort_order='reverse', sort_on='effective') 260 261 query['getAlwaysOnTop']=0 262 resultsNoTop = startpoint.portal_catalog.searchResults(query, meta_type='BlogEntry', path={'query':self.getObjectPath(startpoint),'level':0}, sort_order='reverse', sort_on='effective') 263 264 results = resultsTop + resultsNoTop 265 266 if maxResults==0: 238 results = startpoint.portal_catalog.searchResults(query, meta_type='BlogEntry', 239 path={'query':self.getObjectPath(startpoint),'level':0}, sort_order='reverse', 240 sort_on='effective', sort_limit=maxResults and maxResults or None) 241 242 if maxResults==0: 267 243 return results 268 244 elif maxResults==None: … … 271 247 return results[:maxResults] 272 248 273 274 security.declarePublic('searchForEntries')275 def collectEntries(self, context, category=None, maxResults=None, filterState=1, allBlogs=0, **kwargs):276 # first get all the blogs277 if allBlogs:278 query = {'meta_type':'Blog',279 'path':{'query':self.getObjectPath(context),'level':0}280 } # used meta_type because for some reason, syndication objects also show up.281 blogs = [b.getObject() for b in self.portal_catalog.searchResults(query)]282 onTop=[]283 atBottom=[]284 # now collect all the entries285 for blog in blogs:286 tmpTop, tmpBottom = blog.getEntries(category=category, maxResults=maxResults, filterState = filterState, sort=0, **kwargs)287 onTop = onTop+tmpTop288 atBottom = atBottom+tmpBottom289 #sort290 onTop.sort((lambda x,y:cmp(y.effective(), x.effective())))291 atBottom.sort((lambda x,y:cmp(y.effective(), x.effective())))292 293 results = onTop+atBottom294 else:295 results = context.getEntries(category=category, maxResults=maxResults, filterState = filterState, sort=0, join=1, skipOnTop=1, **kwargs)296 297 298 if maxResults==0:299 return results300 elif maxResults==None:301 return results[:self._getMaxItemsInPortlet()]302 else:303 return results[:maxResults]304 249 305 250 security.declarePublic('searchForDay') … … 371 316 lst.append(states[s].id) 372 317 return lst 373 318 374 319 security.declareProtected(CMFCorePermissions.ManagePortal,'getEntryWorkflowStates') 375 320 def getEntryWorkflowStates(self, context): … … 381 326 if not states[s].id in lst: 382 327 lst.append(states[s].id) 383 328 384 329 return lst 385 330 … … 387 332 def getObjectPath(self, object): 388 333 return os.path.join(*object.getPhysicalPath()).replace('\\', '/') 389 334 390 335 # ====================================================== 391 336 # calendar stuff, copied from CMFCalender … … 406 351 """ Returns a list of days with the correct start day first """ 407 352 return calendar.weekheader(2).split() 408 353 409 354 security.declarePublic('getWeeksList') 410 355 def getWeeksList(self, month='1', year='2002'): … … 419 364 # [28, 29, 30, 31, 0, 0, 0]] 420 365 daysByWeek=calendar.monthcalendar(year, month) 421 366 422 367 return daysByWeek 423 368 … … 437 382 daysByWeek=calendar.monthcalendar(year, month) 438 383 weeks=[] 439 384 440 385 events=self.catalog_getevents(context, year, month) 441 386 442 387 for week in daysByWeek: 443 388 days=[] … … 447 392 else: 448 393 days.append({'day': day, 'event': 0, 'eventslist':[]}) 449 394 450 395 weeks.append(days) 451 396 452 397 return weeks 453 398 454 399 security.declarePublic('catalog_getevents') 455 400 def catalog_getevents(self, context, year, month): … … 461 406 ## last_date=DateTime(str(month)+'/'+str(last_day)+'/'+str(year)) 462 407 last_date=first_date + last_day 463 408 464 409 # get the starting point for our search. This is where we depart from the standard catalog_tool: 465 410 startpoint = self.getStartpoint(context, fromHere=0) 466 411 467 412 query=self.portal_catalog(portal_type=self.calendar_types, 468 413 review_state=self._getState(), … … 473 418 path={'query':self.getObjectPath(startpoint),'level':0}, 474 419 sort_on='start') 475 420 476 421 # compile a list of the days that have events 477 422 eventDays={} … … 523 468 # end calendar stuff 524 469 # ================== 525 526 527 470 528 471 InitializeClass(SimpleBlogManager) SimpleBlog/trunk/content/blog.py
r694 r1039 16 16 from Products.Archetypes.utils import unique 17 17 18 from Products.ATContentTypes.content.base import ATCTFolder 19 20 schema = ATCTFolder.schema.copy() + Schema(( 18 from Products.ATContentTypes.content.base import ATCTBTreeFolder, ATCTFolder 19 from Products.ATContentTypes.lib.constraintypes import ConstrainTypesMixinSchema 20 21 schema = ConstrainTypesMixinSchema.copy() + ATCTFolder.schema.copy() + Schema(( 21 22 StringField('description', 22 23 isMetadata=1, … … 38 39 visible={'view' : 'invisible', 'edit':'invisible'}), 39 40 default='descriptionOnly'), 40 IntegerField('displayItems', 41 IntegerField('displayItems', 41 42 widget=IntegerWidget(label='BlogEntries to display', 42 43 label_msgid="label_display_items", … … 197 198 condition="python:%s" % ENABLE_ADSENSE)), 198 199 )) 199 200 # hide relatedItems201 200 schema['relatedItems'].widget.visible={'view' : 'invisible', 'edit':'invisible'} 202 201 203 class Blog(ATCT Folder):202 class Blog(ATCTBTreeFolder,ATCTFolder): 204 203 """Blog""" 205 204 … … 224 223 RPCAuth = self.simpleblog_tool.findRPCAuth(self) 225 224 226 # Setup the MetaWeblog API227 225 self.metaWeblog = MetaWeblogAPI.MetaWeblogAPI().__of__(self) 228 226 self.metaWeblog.setupRPCAuth(RPCAuth) 229 230 # Setup the Blogger API231 227 self.blogger = BloggerAPI.BloggerAPI().__of__(self) 232 228 self.blogger.setupRPCAuth(RPCAuth) 233 234 # Setup the MovableTypeAPI API235 229 self.mt = MovableTypeAPI.MovableTypeAPI().__of__(self) 236 230 self.mt.setupRPCAuth(RPCAuth) … … 246 240 247 241 def synContentValues(self): 248 # get brains for items that are published within the context of this blog. 249 entries = self.simpleblog_tool.searchForEntries(self, maxResults=0) 250 251 # convert to objects 242 syn_tool = getToolByName(self, 'portal_syndication') 243 limit = int(syn_tool.getMaxItems(self)) 244 entries = self.getEntries(maxResults=limit)[1] 252 245 objs = [e.getObject() for e in entries] 253 246 return objs … … 256 249 cats=self.getCategories() 257 250 258 # add the global categories259 251 for c in self.simpleblog_tool.getGlobalCategories(): 260 252 if not c in cats: … … 268 260 return [f for f in self.getBRefs('AppearsIn') if self.portal_membership.checkPermission('View', f)] 269 261 270 def getEntries(self, category=None, maxResults=None, fromHere=0, filterState=1, sort=1, join=0, addCrossPostInfo=0, skipOnTop=0, **kwargs): 262 def buildBatch(self, b_start, query, notlimited_len): 263 """Return batch for navigation""" 264 #if 'getAlwaysOnTop' in query.keys(): 265 #query['getAlwaysOnTop']=1 266 #len1 = len(self.portal_catalog(**query)) 267 #query['getAlwaysOnTop']=0 268 if 'sort_limit' in query.keys(): 269 del query['sort_limit'] 270 total_len = len(self.portal_catalog(**query)) 271 else: 272 total_len = notlimited_len 273 ditems = self.getDisplayItems() 274 275 batch = [] 276 if total_len > ditems: 277 max_pages = total_len/ditems + (total_len%ditems and 1 or 0) 278 vis_middle = 3 # max number of pages in one of the side around current 279 curr_num = b_start/ditems >= max_pages and max_pages or b_start/ditems+1 280 # first page (when current page far from 1st page) 281 first = [] 282 if curr_num-vis_middle > 2: 283 first = [1,"b_start=0"] 284 batch.append(first) 285 # last page (when current page far from terminal page) 286 last = [] 287 if max_pages-curr_num > vis_middle+1: 288 last = [max_pages,"b_start=%d" % ((max_pages-1)*ditems)] 289 batch.append(last) 290 # form batch around current page 291 lft_bound = curr_num-vis_middle > 2 and curr_num-vis_middle or 1 292 rght_bound = max_pages-curr_num > vis_middle+1 and curr_num+vis_middle or max_pages 293 lst = [] 294 for p in range(lft_bound, rght_bound+1): 295 q = p!=curr_num and "b_start=%d" % ((p-1)*ditems) or "" 296 lst.append([p,q]) 297 batch.append(lst) 298 return batch 299 300 def getStart(self): 301 """ Validate b_start from request and return right value.""" 302 request = self.REQUEST 303 try: 304 b_start = int(request.get('b_start', 0)) or 0 305 except: 306 b_start = 0 307 if b_start < 0: 308 b_start = 0 309 return b_start 310 311 def getEntries(self, category=None, maxResults=None, b_start=0, filterState=1, join=0, skipOnTop=0, mode="", **kwargs): 271 312 """ Return all the contained published entries, real objects, not the brains """ 272 # see simpleblog_tool.searchForEntries for API description273 313 query=kwargs 274 314 publishedState = self.simpleblog_tool.getPublishedState() … … 278 318 query['review_state']=publishedState 279 319 if maxResults: 280 query['sort_limit'] = maxResults 281 query['path'] = {'query':self.simpleblog_tool.getObjectPath(self),'level':0} 320 query['sort_limit'] = maxResults + 1 # need to if the last page riched 321 if not query.has_key('path'): 322 query['path'] = {'query':self.simpleblog_tool.getObjectPath(self),'level':0} 282 323 query['sort_order'] = 'reverse' 283 324 query['sort_on'] = 'effective' 284 325 query['meta_type'] = 'BlogEntry' 285 if not skipOnTop: 326 onTop = [] 327 if not skipOnTop and b_start==0: 286 328 query['getAlwaysOnTop']=1 287 # first the items that need to be listed on top 288 localOnTop = self.portal_catalog.searchResults(query) 289 localOnTop = [r.getObject() for r in localOnTop ] 290 # then the other items 329 onTop = list(self.portal_catalog.searchResults(query)) 291 330 query['getAlwaysOnTop']=0 292 else: 293 localOnTop = [] 294 localNoTop = self.portal_catalog.searchResults(query) 295 localNoTop= [r.getObject() for r in localNoTop] 296 297 onTop = localOnTop 298 onBottom = localNoTop 331 332 onBottom = list(self.portal_catalog.searchResults(query)) 333 #### cut the b_start when it is tooo large 334 itemsPerPage = self.getDisplayItems() 335 last = 0 336 if len(onBottom) < maxResults + 1: #last page 337 last = 1 338 elif len(onBottom) == maxResults + 1: #not last page yet 339 onBottom = onBottom[:-1] 340 if len(onBottom) < b_start: # too large b_start given 341 b_start = (len(onBottom)/itemsPerPage)*itemsPerPage 299 342 if join: 300 343 results = onTop+onBottom 301 if maxResults==0: 302 return results 303 elif maxResults==None: 304 return results[:self.simpleblog_tool.getMaxItemsInPortlet()] 305 else: 306 return results[:maxResults] 344 batch = 'navigation' in query.keys() and self.buildBatch(b_start, query, len(results)) or [] 345 if b_start > 0: 346 if len(onBottom) == b_start: 347 b_start = b_start-(maxResults-b_start) 348 last = 1 349 results = results[b_start:] 350 return (results,last,batch) 307 351 else: 308 return (onTop, onBottom) 352 batch = 'navigation' in query.keys() and self.buildBatch(b_start, query, len(onBottom)) or [] 353 return (onTop, onBottom, batch) 309 354 310 355 def getAdminEmail(self): SimpleBlog/trunk/content/blogentry.py
r695 r1039 78 78 accessor='EntryCategory', 79 79 edit_accessor='EntryCategory', 80 index='KeywordIndex ',80 index='KeywordIndex:schema', 81 81 vocabulary='listCategories', 82 82 widget=MultiSelectionWidget(format='select', … … 124 124 )) 125 125 126 # Finalise the schema according to ATContentTypes standards. This basically127 # moves the Related items and Allow discussion fields to the bottom of the128 # form. See ATContentTypes.content.schemata for details.129 126 finalizeATCTSchema(schema) 130 131 127 132 128 class BlogEntry(parentClass): … … 134 130 A BlogEntry can exist inside a SimpleBlog Folder or an EntryFolder 135 131 """ 136 # Standard content type setup137 132 portal_type = meta_type = 'BlogEntry' 138 133 archetype_name = 'Blog Entry' … … 145 140 immediate_view = 'blogentry_view' 146 141 147 # Make sure we get title-to-id generation when an object is created148 142 _at_rename_after_creation = True 149 143 150 144 if ENTRY_IS_FOLDERISH: 151 145 filter_content_types=1 152 allowed_content_types=('TrackBack') #('Link', 'Image', 'File', 'TrackBack') 153 146 allowed_content_types=('TrackBack') 154 147 155 148 def canSetDefaultPage(self): 156 149 return False 157 158 150 159 151 def getAlwaysOnTop(self): … … 165 157 else: 166 158 return 0 167 159 168 160 def getIcon(self, relative_to_portal=0): 169 161 try: … … 174 166 except: 175 167 return 'entry_icon.gif' 176 168 177 169 def listCategories(self): 178 # traverse upwards in the tree to collect all the available categories 179 # stop collecting when a SimpleBlog object is reached 180 170 """ Traverse upwards in the tree to collect all the available categories.""" 181 171 cats=[] 182 172 parent=self.aq_parent 183 173 portal=self.portal_url.getPortalObject() 184 174 185 175 while parent!=portal: 186 176 if parent.portal_type=='Blog' or parent.portal_type=='BlogFolder': 187 # add cats188 177 pcats=parent.getCategories() 189 178 for c in pcats: … … 193 182 break 194 183 parent=parent.aq_parent 195 196 # add the global categories 184 197 185 for c in self.simpleblog_tool.getGlobalCategories(): 198 186 if not c in cats: 199 cats.append(c) 187 cats.append(c) 200 188 cats.sort() 201 189 return tuple(cats) … … 203 191 def start(self): 204 192 return self.getEffectiveDate() 205 193 206 194 def end(self): 207 """ 208 return the same data as start() since an entry is not an event but an item that is published on a specific 209 date. We want the entries in the calendar to appear on only one day. 195 """ Return the same data as start() since an entry is not an event but an item that is 196 published on a specific date. We want the entries in the calendar to appear on only one day. 210 197 """ 211 198 return self.getEffectiveDate() 212 199 213 214 215 216 # =============================217 218 #function for sending ping219 200 def sendTrackBack(self): 220 201 message = "TrackBack sent" … … 241 222 242 223 def getTrackbacks(self): 243 """ """244 224 return self.listFolderContents(spec="TrackBack") 245 225 … … 276 256 277 257 def getBody(self): 278 return self.getField('body').get(self)258 return self.getField('body').get(self) 279 259 280 260 registerType(BlogEntry) SimpleBlog/trunk/content/blogfolder.py
r694 r1039 5 5 from Products.CMFCore import CMFCorePermissions 6 6 7 from Products.ATContentTypes.content.base import ATCTFolder 7 from Products.ATContentTypes.content.base import ATCTBTreeFolder, ATCTFolder 8 from Products.ATContentTypes.lib.constraintypes import ConstrainTypesMixinSchema 8 9 9 10 import Products.SimpleBlog.Permissions 10 11 11 12 12 schema = ATCTFolder.schema.copy() + Schema((13 schema = ConstrainTypesMixinSchema.copy() + ATCTFolder.schema.copy() + Schema(( 13 14 StringField('description', 14 15 isMetadata=1, … … 34 35 35 36 36 class BlogFolder(ATCT Folder):37 class BlogFolder(ATCTBTreeFolder, ATCTFolder): 37 38 """ 38 39 A folder object to store BlogEntries in … … 57 58 58 59 def getInheritedCategories(self): 59 # traverse upwards in the tree to collect all the available categories 60 # stop collecting when a SimpleBlog object is reached 61 62 cats=[] 63 parent=self.aq_parent 64 portal=self.portal_url.getPortalObject() 65 categories='<ul>' 66 while parent!=portal: 67 if parent.portal_type=='Blog' or parent.portal_type=='BlogFolder': 68 # add cats 69 pcats=parent.getCategories() 70 for c in pcats: 71 if c not in cats: 72 categories=categories + '<li>' + c + '</li>' 73 cats.append(c) 74 if parent.portal_type=='Blog': 75 break 76 parent=parent.aq_parent 77 categories = categories + '</li>' 78 if len(cats)==0: 79 return '-' 80 else: 81 return categories 60 """ Traverse upwards in the tree to collect all the available categories.""" 61 cats=[] 62 parent=self.aq_parent 63 portal=self.portal_url.getPortalObject() 64 categories='<ul>' 65 while parent!=portal: 66 if parent.portal_type=='Blog' or parent.portal_type=='BlogFolder': 67 # add cats 68 pcats=parent.getCategories() 69 for c in pcats: 70 if c not in cats: 71 categories=categories + '<li>' + c + '</li>' 72 cats.append(c) 73 if parent.portal_type=='Blog': 74 break 75 parent=parent.aq_parent 76 categories = categories + '</li>' 77 if len(cats)==0: 78 return '-' 79 else: 80 return categories 82 81 83 82 def getEntries(self, maxResults=None, **kwargs): 84 83 """ Return all the contained published entries, real objects, not the brains """ 85 # see simpleblog_tool.searchForEntries for API description 84 blog = self.simpleblog_tool.getFrontPage(self) 85 kwargs.update({'path':{'query':'/'+'/'.join(self.getPhysicalPath()),'level':0}}) 86 return blog.getEntries(maxResults=maxResults, **kwargs) 86 87 87 query=kwargs88 88 89 publishedState = self.simpleblog_tool.getPublishedState()90 91 query['getAlwaysOnTop']=192 93 # first the items that need to be listed on top94 localOnTop = self.portal_catalog.searchResults(query, meta_type='BlogEntry', path={'query':self.simpleblog_tool.getObjectPath(self),'level':0}, sort_order='reverse', sort_on='effective')95 localOnTop = [r.getObject() for r in localOnTop ]96 97 # then the other items98 query['getAlwaysOnTop']=099 localNoTop = self.portal_catalog.searchResults(query, meta_type='BlogEntry', path={'query':self.simpleblog_tool.getObjectPath(self),'level':0}, sort_order='reverse', sort_on='effective')100 localNoTop= [r.getObject() for r in localNoTop]101 102 results = localOnTop+localNoTop103 104 if maxResults==0:105 return results106 elif maxResults==None:107 return results[:self.simpleblog_tool.getMaxItemsInPortlet()]108 else:109 return results[:maxResults]110 111 89 def synContentValues(self): 112 # get brains for items that are published within the context of this blog.113 90 entries = self.simpleblog_tool.searchForEntries(self, fromHere=1, maxResults=0) 114 115 # convert to objects116 91 objs = [e.getObject() for e in entries] 117 return objs 118 92 return objs 93 119 94 registerType(BlogFolder) SimpleBlog/trunk/docs/readme.txt
r694 r1039 115 115 will be sufficient. 116 116 117 Using SimpleBlog as your homepage in Plone118 119 Inside the skin folder there is a template called **simpleblog_standalone**. First get rid of the current index_html120 in your portal root by deleting it or renaming it. Then create a new Page template in the root and call it index_html.121 Then copy/paste the code from simpleblog_standalone in there and adjust it at will. All this is done in ZMI.122 123 117 Well, that's all you have to know to set up SimpleBlog. Enjoy it. 124 118 SimpleBlog/trunk/skins/SimpleBlog/SimpleBlog_macros.pt
r694 r1039 28 28 <span tal:define="item_type obj/portal_type; 29 29 item_type_class python:'contenttype-' + normalizeString(item_type);" 30 tal:attributes="class string:simpleBlogIcons ${item_type_class}" tal:content="obj/ title"/></a>30 tal:attributes="class string:simpleBlogIcons ${item_type_class}" tal:content="obj/Title"/></a> 31 31 </h2> 32 32 <h2 class="noMargin" tal:condition="not:showIcons"> … … 35 35 </h2> 36 36 <p class="simpleBlogDescription" 37 tal:content="structure python:obj.Description()"37 tal:content="structure obj/Description" 38 38 tal:condition="obj/Description">Description</p> 39 <div tal:replace="structure python:obj.getBody()" class="simpleBlogBody"/>39 <div tal:replace="structure obj/getBody" class="simpleBlogBody"/> 40 40 <tal:tags metal:use-macro="obj/simpleblog_byline/macros/technoratiTags"/> 41 41 <tal:byline tal:condition="showByline"> … … 57 57 </h2> 58 58 <p class="simpleBlogDescription" 59 tal:content="structure python:obj.Description()"59 tal:content="structure obj/Description" 60 60 tal:condition="obj/Description">Description</p> 61 61 <tal:tags metal:use-macro="obj/simpleblog_byline/macros/technoratiTags"/> SimpleBlog/trunk/skins/SimpleBlog/simpleblog_portlet_macros.pt
r694 r1039 24 24 25 25 <!-- macro used by the portlets to compile a list of recent additions --> 26 <div metal:define-macro="portletRecent"> 27 <tal:x tal:condition="maxItems|nothing"><tal:x tal:define="global maxResults maxItems"/> 28 </tal:x><tal:x tal:condition="not: maxItems|nothing"><tal:x tal:define="global maxResults python:0"/> 29 </tal:x><tal:block tal:define="maxResults python:test(maxResults==0,here.simpleblog_tool.getMaxItemsInPortlet(),maxResults); 30 recent python:startpoint.getEntries(maxResults=maxResults,skipOnTop=1, join=1); 31 global showIcons startpoint/getShowIcons;" 32 tal:omit-tag=""><tal:toggle tal:define="global toggle python:1"/> 26 <div metal:define-macro="portletRecent" tal:omit-tag=""><tal:block 27 tal:define="maxResults here/simpleblog_tool/getMaxItemsInPortlet; 28 recent python:startpoint.getEntries(maxResults=maxResults,skipOnTop=1, join=1)[0]; 29 global showIcons startpoint/getShowIcons;"><tal:toggle 30 tal:define="global toggle python:1"/> 33 31 <tal:entries tal:repeat="entry recent"> 34 32 <tal:start tal:condition="python:inBlog and not solo"> … … 36 34 tal:condition="repeat/entry/start" 37 35 tal:attributes="class python:test(toggle, 'portletItem odd','portletItem even')"> 38 <tal:frontpage> 39 <strong i18n:translate="recent_additions">Recent entries:</strong> 40 </tal:frontpage> 36 <strong i18n:translate="recent_additions">Recent entries:</strong> 41 37 </dd></tal:start> 42 38 <dd class="" 43 39 tal:define="oddrow repeat/entry/odd; 44 item_type entry/portal_type; 40 obj entry; 41 item_type obj/portal_type; 45 42 item_type_class python:'contenttype-' + normalizeString(item_type);" 46 43 tal:attributes="class python:test(toggle, 'portletItem even','portletItem odd')"> 47 44 <a href="#" 48 tal:attributes="href entry/absolute_url;"45 tal:attributes="href obj/getURL;" 49 46 title="entry"> 50 <span tal:attributes="class python:showIcons and 'simpleBlogPortletIcons '+item_type_class or ''" tal:content=" entry/title_or_id"/>47 <span tal:attributes="class python:showIcons and 'simpleBlogPortletIcons '+item_type_class or ''" tal:content="obj/Title"/> 51 48 </a><tal:toggle tal:define="global toggle python:test(toggle==1,0,1)"/> 52 49 </dd> … … 56 53 className python:test(solo,'portletFooter', 'portletItem')" 57 54 tal:condition="repeat/entry/end" 58 tal:attributes="class python:test(toggle, className + ' even ', className + ' odd')">59 <a href="#" tal:attributes="href string:${startpoint/absolute_url} /SimpleBlogFullSearch"55 tal:attributes="class python:test(toggle, className + ' even details', className + ' odd details')"> 56 <a href="#" tal:attributes="href string:${startpoint/absolute_url}" 60 57 title="more..." 61 58 i18n:attributes="title box_morelink" SimpleBlog/trunk/skins/SimpleBlog/simpleblog_view.pt
r694 r1039 6 6 <div metal:fill-slot="main"> 7 7 <tal:main-macro metal:define-macro="main" 8 tal:define="displayItems python:here.getDisplayItems(); 9 displayMode displayMode | python:here.getDisplayMode(); 10 results python:here.getEntries(maxResults=0, sort=1, join=1, addCrossPostInfo=1); 8 tal:define="displayMode displayMode | python:here.getDisplayMode(); 9 displayItems python:here.getDisplayItems(); 11 10 b_size python:displayItems; 12 b_start python:0;13 b_start request/b_start | b_start;14 Batch python:modules['Products.CMFPlone'].Batch;">11 b_start here/getStart; 12 results python:here.getEntries(maxResults=b_start+displayItems, sort=1, join=1, b_start=b_start,mode=displayMode,navigation=1); 13 last python:results[1];"> 15 14 <tal:block metal:use-macro="here/SimpleBlog_macros/macros/blogGlobals"/> 16 15 <div metal:use-macro="here/document_actions/macros/document_actions"> … …
