Contents
1. Description
Default category page of Moin using FullSearch macro. It is slow and not good looking. I write a ShowCategory macro, which display a MediaWiki alike category page.
A typical usage: simply write a <<ShowCategory>> in any category page.
2. Snapshot
|
|
|
3. Example
http://pysvnmanager.ossxp.com/CategoryNews (404, a new one is needed)
4. Download
4.1. ShowCategory macro source code
1 new macro ShowCategory: display a MediaWiki style category page
2
3 diff -r 0bfe351fb737 MoinMoin/macro/ShowCategory.py
4 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5 +++ b/MoinMoin/macro/ShowCategory.py Tue Nov 25 10:17:40 2008 +0800
6 @@ -0,0 +1,210 @@
7 +# -*- coding: utf-8 -*-
8 +"""
9 + CategoryList macro
10 +
11 + List Categories in Category.
12 +
13 + @copyright: 2008 Jiang Xin <worldhello.net@gmail.com>
14 + @license: GNU GPL, see COPYING for details.
15 +"""
16 +
17 +from MoinMoin import wikiutil2
18 +from MoinMoin.Page import Page
19 +
20 +_sysmsg = '<p><strong class="%s">%s</strong></p>'
21 +
22 +
23 +def show_category(request, categorylist, column=3, show_cat=True, show_page=True,
24 + show_summary=True, show_capital=True, sort=[], reverse=False,
25 + recursive=False, items=0, skipitems=0, exclude_template=True):
26 + cc = wikiutil2.CategoryCache(request)
27 + _ = request.getText
28 +
29 + if "all" in categorylist:
30 + show_cat = True
31 + show_page = False
32 + recursive = False
33 + summary_of_subcategories = "<h2>" + _("All categories") + "</h2>\n" + \
34 + _("There are %(count)d categories in this wiki.")
35 + summary_of_subpages = ""
36 + else:
37 + summary_of_subcategories = "<h2>" + _("Subcategories of <b>%(category)s</b>") + "</h2>\n" + \
38 + _("This category has the following %(count)d subcategories.")
39 + summary_of_subpages = "<h2>" + _("Pages in category <b>%(category)s</b>") + "</h2>\n" + \
40 + _("There are %(count)d pages are in this category.")
41 +
42 + result = []
43 +
44 + # show sub category
45 + if show_cat:
46 + for category in categorylist:
47 + itemlist = []
48 + for i in sorted( cc.get_sub_categories(category,recursive=recursive, exclude_template=exclude_template) ):
49 + name = i
50 + page = Page(request, name)
51 + entries = []
52 + for s in sort:
53 + if "title".startswith(s):
54 + pagetitle = page.pi.get("pragma_page_title" ,page.page_name)
55 + entries.append( pagetitle )
56 + name = pagetitle
57 + elif "timestamp".startswith(s):
58 + edit_info = page.edit_info()
59 + timestamp = edit_info.get('timestamp', 0)
60 + entries.append(timestamp)
61 + else:
62 + return (_sysmsg % ('error', _('Invalid sort arguments "%s"!')) % (s, ))
63 + linktext = "%s(%d/%d)" % ( name, len(cc.catcatdict.get(i,[])), len(cc.catpagedict.get(i,[])) )
64 + link = page.link_to(request, text=linktext, attachment_indicator=1)
65 + entries.extend( [name, link] )
66 + itemlist.append( entries )
67 +
68 + if itemlist:
69 + itemlist.sort(reverse=reverse)
70 + if len(itemlist[0]) > 2:
71 + itemlist=[ (x[-2], x[-1]) for x in itemlist ]
72 +
73 + if show_summary:
74 + result += [ summary_of_subcategories % {'category': category, 'count': len(itemlist)} ]
75 +
76 + if skipitems:
77 + itemlist=itemlist[skipitems:]
78 + if items:
79 + itemlist=itemlist[:items]
80 + result += wikiutil2.formatList(request, itemlist, column=column, show_capital=show_capital)
81 +
82 + # show pages belong to this category
83 + if show_page:
84 + for category in categorylist:
85 + itemlist = []
86 + for i in sorted( cc.get_sub_pages(category,recursive=recursive, exclude_template=exclude_template) ):
87 + name = i
88 + page = Page(request, name)
89 + entries = []
90 + for s in sort:
91 + if "title".startswith(s):
92 + pagetitle = page.pi.get("pragma_page_title" ,page.page_name)
93 + entries.append( pagetitle )
94 + name = pagetitle
95 + elif "timestamp".startswith(s):
96 + edit_info = page.edit_info()
97 + timestamp = edit_info.get('timestamp', 0)
98 + entries.append(timestamp)
99 + else:
100 + return (_sysmsg % ('error', _('Invalid sort arguments "%s"!')) % (s, ))
101 + link = page.link_to(request, text=name, attachment_indicator=1)
102 + entries.extend( [name, link] )
103 + itemlist.append( entries )
104 +
105 + if itemlist:
106 + itemlist.sort(reverse=reverse)
107 + if len(itemlist[0]) > 2:
108 + itemlist=[ (x[-2], x[-1]) for x in itemlist ]
109 +
110 + if show_summary:
111 + result += [ summary_of_subpages % {'category': category, 'count': len(itemlist)} ]
112 +
113 + if skipitems:
114 + itemlist=itemlist[skipitems:]
115 + if items:
116 + itemlist=itemlist[:items]
117 + result += wikiutil2.formatList(request, itemlist, column=column, show_capital=show_capital)
118 +
119 + return "\n".join(result)
120 +
121 +
122 +
123 +def execute(macro, args):
124 + global category_cache
125 + request = macro.request
126 + _ = request.getText
127 + show_cat = True
128 + show_page = True
129 + show_summary = True
130 + show_capital = True
131 + exclude_template = True
132 + column = 3
133 + category = []
134 + sort = []
135 + reverse = False
136 + recursive = False
137 + items = 0
138 + skipitems = 0
139 +
140 + if args:
141 + for i in args.split(','):
142 + i=i.strip()
143 + if "=" in i:
144 + key, val = i.split('=',1)
145 + else:
146 + key = i
147 + val = "yes"
148 + boolval = (val=="1" or val.lower().startswith("t") or val.lower().startswith("y"))
149 + if key.startswith("no"):
150 + boolval = not boolval
151 +
152 + if "nocategories".startswith(key) or "categories".startswith(key):
153 + show_cat = boolval
154 + continue
155 + elif "nopages".startswith(key) or "pages".startswith(key):
156 + show_page = boolval
157 + continue
158 + elif "nosummary".startswith(key) or "summary".startswith(key):
159 + show_summary = boolval
160 + continue
161 + elif "nocapital".startswith(key) or "capital".startswith(key):
162 + show_capital = boolval
163 + continue
164 + elif "notemplates".startswith(key) or "templates".startswith(key):
165 + exclude_template = not boolval
166 + continue
167 + elif "descending".startswith(key):
168 + reverse = boolval
169 + continue
170 + elif "ascending".startswith(key):
171 + reverse = not boolval
172 + continue
173 + elif "recursive".startswith(key):
174 + recursive = boolval
175 + continue
176 + elif "sort".startswith(key):
177 + sort.append(val)
178 + continue
179 + elif "column".startswith(key):
180 + column = int(val)
181 + continue
182 + elif "items".startswith(key):
183 + items = int(val)
184 + continue
185 + elif "skipitems".startswith(key):
186 + skipitems = int(val)
187 + continue
188 + elif "=" in i:
189 + return (_sysmsg % ('error', _('Invalid ShowCategory arguments "%s"!')) % (i, ))
190 +
191 + if i.lower() == "all":
192 + category.append("all")
193 + continue
194 + else:
195 + category_check = request.cfg.cache.page_category_regex.search(i)
196 + if category_check and category_check.group("all") == i:
197 + category.append(i)
198 + continue
199 + try:
200 + i = int(i)
201 + column = i
202 + except:
203 + return (_sysmsg % ('error', _('Invalid ShowCategory arguments "%s"!')) % (i, ))
204 +
205 + if not sort:
206 + sort = ["title"]
207 +
208 + if not category:
209 + category.append(macro.formatter.page.page_name)
210 +
211 + return show_category(request, category, column=column, show_cat=show_cat, show_page=show_page,
212 + show_summary=show_summary, show_capital=show_capital, sort=sort,
213 + reverse=reverse, recursive=recursive, items=items, skipitems=skipitems,
214 + exclude_template=exclude_template)
215 +
216 +# vim:ts=4:sw=4:et
217 diff -r 0bfe351fb737 MoinMoin/wikiutil2.py
218 --- a/MoinMoin/wikiutil2.py Tue Nov 25 09:40:25 2008 +0800
219 +++ b/MoinMoin/wikiutil2.py Tue Nov 25 10:17:40 2008 +0800
220 @@ -8,6 +8,9 @@
221
222 import re
223 from MoinMoin import wikiutil
224 +from MoinMoin import caching
225 +from MoinMoin.Page import Page
226 +from MoinMoin.logfile import editlog
227
228 from MoinMoin import log
229 logging = log.getLogger(__name__)
230 @@ -66,3 +69,292 @@
231
232 return raw_body
233
234 +class CategoryCache(object):
235 + cache_date, pagedict, catcatdict, catpagedict = 0, {}, {}, {}
236 +
237 + def __init__(self, request):
238 + self.request = request
239 + self._update_category_cache_data()
240 +
241 + def _update_category_cache_data(self):
242 + cache = caching.CacheEntry(self.request, 'category', 'dict', scope='wiki', use_pickle=True)
243 + if cache.exists():
244 + try:
245 + self.cache_date, self.pagedict, self.catcatdict, self.catpagedict = cache.content()
246 + except:
247 + cache.remove() # cache gone bad
248 +
249 + log = editlog.EditLog(self.request)
250 + try:
251 + new_date = log.date()
252 + except logfile.LogMissing:
253 + new_date = self.cache_date
254 +
255 + if not (self.pagedict or self.catcatdict or self.catpagedict):
256 + pagelist = self.request.rootpage.getPageList(user="",return_objects=True)
257 + else:
258 + pagenamelist = set()
259 + pagelist = []
260 +
261 + if new_date > self.cache_date:
262 + for event in log.reverse():
263 + if event.ed_time_usecs <= self.cache_date:
264 + break
265 + # action: [ATTDEL, ATTNEW, SAVE, SAVENEW, SAVE/RENAME, SAVE/REVERT]
266 + if event.action not in ['ATTNEW', 'ATTDEL']:
267 + pagenamelist.add(event.pagename)
268 + if event.action == 'SAVE/RENAME':
269 + pagenamelist.add(event.extra)
270 +
271 + for pagename in pagenamelist:
272 + page = Page(self.request, pagename)
273 + pagelist.append(page)
274 + self.cache_date = new_date
275 +
276 + # cache outof date since there are changed pages.
277 + if pagelist:
278 + pattern = re.compile(r'(?:^-----*\s*\r?\n)(?:^##.*\r?\n)*^(?!##)(?P<category>.+?)$', re.M)
279 + for page in pagelist:
280 + body = page.get_raw_body()
281 + pagename = page.page_name
282 +
283 + name_checked = self.request.cfg.cache.page_category_regexact.search(pagename)
284 + if name_checked and name_checked.group("all") == pagename:
285 + page_is_category = True
286 + else:
287 + page_is_category = False
288 + # reset self.pagedict, catdict for pagename
289 + if self.pagedict.has_key(pagename):
290 + for catname in self.pagedict[pagename]:
291 + if page_is_category:
292 + catdict = self.catcatdict
293 + else:
294 + catdict = self.catpagedict
295 + if catdict.has_key(catname):
296 + if pagename in catdict[catname]:
297 + catdict[catname].remove(pagename)
298 + if not catdict[catname]:
299 + del catdict[catname]
300 + del self.pagedict[pagename]
301 +
302 + # if deleted page is a category, delete category if blank.
303 + if not body and page_is_category:
304 + if self.catcatdict.has_key(pagename):
305 + if not self.catcatdict[pagename]:
306 + del self.catcatdict[pagename]
307 + if self.catpagedict.has_key(pagename):
308 + if not self.catpagedict[pagename]:
309 + del self.catpagedict[pagename]
310 +
311 + for match in pattern.finditer(body):
312 + for item in match.group('category').split():
313 +
314 + if item.startswith("[["):
315 + item = item[2:-2]
316 + name_checked = self.request.cfg.cache.page_category_regexact.search(item)
317 + if name_checked and name_checked.group("all") == item:
318 + self.pagedict[pagename] = self.pagedict.get(pagename, set())
319 + self.pagedict[pagename].add(item)
320 + if page_is_category:
321 + self.catcatdict[item] = self.catcatdict.get(item, set())
322 + self.catcatdict[item].add(pagename)
323 + else:
324 + self.catpagedict[item] = self.catpagedict.get(item, set())
325 + self.catpagedict[item].add(pagename)
326 +
327 + # Update cache
328 + cache.update((new_date, self.pagedict, self.catcatdict, self.catpagedict))
329 +
330 + def _get_all_categories(self):
331 + result = set(self.catcatdict.keys())
332 + for value in self.catcatdict.values():
333 + result |= value
334 + result |= set(self.catpagedict.keys())
335 + return result
336 +
337 + def get_sub_categories(self, category, recursive=False, exclude_template=True):
338 + """ Return all sub categories of this category.
339 +
340 + @param category: category name, or list of names of categories
341 + @param recursive: if True, scan sub categories recursively.
342 + Default is False.
343 + @param exclude_template: if True, exclude template page.
344 + Default is True.
345 + @rtype: set()
346 + @return: set of sub categories
347 + """
348 + result = self._get_sub_categories(category, recursive, set())
349 +
350 + # exclude template from result
351 + if exclude_template:
352 + templates = []
353 + for item in result:
354 + if self.request.cfg.cache.page_template_regexact.search(item) is not None:
355 + templates.append(item)
356 + for item in templates:
357 + result.remove(item)
358 +
359 + return result
360 +
361 + def _get_sub_categories(self, category, recursive=False, scanned=set()):
362 + """ Return all subcategories of the category.
363 +
364 + scanned store already scanned categories, to prevent deadly loop.
365 + """
366 + result = set()
367 + scanned.add(category)
368 + if isinstance(category, (list,dict,set)):
369 + if "all" in category:
370 + result = self._get_all_categories()
371 + else:
372 + for c in category:
373 + result = result | self._get_sub_categories(c, recursive, set())
374 +
375 + elif "all" == category:
376 + result = self._get_all_categories()
377 +
378 + else:
379 + children = self.catcatdict.get(category)
380 + if children:
381 + for child in children:
382 + result.add(child)
383 + if child not in scanned and recursive:
384 + result = result | self._get_sub_categories(child, recursive, scanned)
385 +
386 + return result
387 +
388 + def get_sub_pages(self, category, recursive=False, exclude_template=True):
389 + result = set()
390 +
391 + if isinstance(category, (list,dict,set)):
392 + for c in category:
393 + result = result | get_sub_pages(c, recursive=recursive)
394 + return result
395 +
396 + if isinstance(category, (list,dict,set)):
397 + category_list = set(category)
398 + else:
399 + category_list = set([category])
400 +
401 + if recursive:
402 + category_list = category_list | self.get_sub_categories(category, recursive=recursive)
403 +
404 + for c in category_list:
405 + result = result | self.catpagedict.get(c, set())
406 +
407 + # exclude template from result
408 + if exclude_template:
409 + templates = []
410 + for item in result:
411 + if self.request.cfg.cache.page_template_regex.search(item) is not None:
412 + templates.append(item)
413 + for item in templates:
414 + result.remove(item)
415 +
416 + return result
417 +
418 + def get_templates(self, category, recursive=False):
419 + result = set()
420 + subpages = self.get_sub_pages(category, recursive, exclude_template=False)
421 + for item in subpages:
422 + if self.request.cfg.cache.page_template_regexact.search(item) is not None:
423 + result.add(item)
424 + return result
425 +
426 + def get_page_category_trail(self, pagename, level=9):
427 + result = []
428 + self._get_page_category_trail( pagename, level, result)
429 + return result
430 +
431 + def _get_page_category_trail(self, pagename, level, result, scanned=[]):
432 + categories = self.pagedict.get(pagename, set())
433 + if categories:
434 + level -= 1
435 + for category in categories:
436 + if category in scanned:
437 + continue
438 + branch = scanned[:]
439 + branch.append(category)
440 + if not self.pagedict.get(category) or level == 0:
441 + result.append(branch)
442 + else:
443 + self._get_page_category_trail(category, level, result, branch)
444 +
445 +
446 +def formatList(request, itemlist, column=3, show_capital=True):
447 + """
448 + These functions: formatList, shorList, columnList is from MediaWiki.
449 + Modified by Jiang Xin <worldhello.net@gmail.com>
450 + """
451 + cutoff = max(column*2, column+1)
452 + if len(itemlist) > cutoff and column>1:
453 + return columnList(request, itemlist, column=column, show_capital=show_capital)
454 + elif len(itemlist) > 0:
455 + return shortList(request, itemlist, show_capital=show_capital)
456 + else:
457 + return [""]
458 +
459 +def shortList(request, itemlist, show_capital=True):
460 + _ = request.getText
461 + startchar = itemlist[0][0][0]
462 + result = []
463 +
464 + if show_capital:
465 + result += ["<h3>" + startchar + "</h3>"]
466 +
467 + result += ["<ul><li>" + itemlist[0][1] + "</li>"]
468 +
469 + for i in range(1,len(itemlist)):
470 + if show_capital and startchar != itemlist[i][0][0]:
471 + startchar = itemlist[i][0][0]
472 + result += ["</ul><h3>" + startchar + "</h3>\n<ul>"]
473 + result += ["<li>"+itemlist[i][1]+"</li>"]
474 + result += ["</ul>"]
475 + return result
476 +
477 +def columnList(request, itemlist, column=3, show_capital=True):
478 + _ = request.getText
479 + if not column:
480 + column = 3
481 + chunk = len(itemlist) // column
482 + result = ['<table class="borderless" width="100%"><tr valign="top">']
483 +
484 + startChunk = 0
485 + endChunk = chunk
486 + startchar = 'none'
487 +
488 + for chunkIndex in range(0, column):
489 + result.append("<td>")
490 + atColumnTop = True
491 +
492 + for i in range(startChunk, endChunk):
493 + if i >= len(itemlist):
494 + break
495 +
496 + if startchar != itemlist[i][0][0] or atColumnTop:
497 + if show_capital and not atColumnTop:
498 + result.append("</ul>")
499 + if not show_capital:
500 + if atColumnTop:
501 + result.append("<ul>")
502 + else:
503 + if itemlist[i][0][0] == startchar:
504 + result.append("<h3>" + startchar + " " + _("cont.") + "</h3>\n<ul>")
505 + else:
506 + startchar = itemlist[i][0][0]
507 + result.append("<h3>" + startchar + "</h3>\n<ul>")
508 + atColumnTop = False
509 +
510 + result.append("<li>" + itemlist[i][1] + "</li>")
511 +
512 + startChunk = endChunk
513 + endChunk += chunk + 1
514 + if not atColumnTop:
515 + result.append("</ul>")
516 +
517 + result.append("</td>")
518 +
519 + result.append("</tr></table>")
520 +
521 + return result
522 +
523
4.2. ShowCategory extension
Extension: add new page dialog for creating new sub category or sub page.
This patch depends on MoinMoinPatch/MultipleTemplatesSupportForNewPageMaro
1 diff -r 7401f51c198b MoinMoin/macro/ShowCategory.py
2 --- a/MoinMoin/macro/ShowCategory.py Tue Nov 25 11:08:51 2008 +0800
3 +++ b/MoinMoin/macro/ShowCategory.py Tue Nov 25 11:13:23 2008 +0800
4 @@ -8,7 +8,7 @@
5 @license: GNU GPL, see COPYING for details.
6 """
7
8 -from MoinMoin import wikiutil2
9 +from MoinMoin import wikiutil, wikiutil2
10 from MoinMoin.Page import Page
11
12 _sysmsg = '<p><strong class="%s">%s</strong></p>'
13 @@ -19,26 +19,55 @@
14 recursive=False, items=0, skipitems=0, exclude_template=True):
15 cc = wikiutil2.CategoryCache(request)
16 _ = request.getText
17 + summary_of_subcategories = []
18 + summary_of_subpages = []
19
20 if "all" in categorylist:
21 + categorylist = ["all"]
22 show_cat = True
23 show_page = False
24 recursive = False
25 - summary_of_subcategories = "<h2>" + _("All categories") + "</h2>\n" + \
26 - _("There are %(count)d categories in this wiki.")
27 - summary_of_subpages = ""
28 + summary_of_subcategories = ["<h2>" + _("All categories") + "</h2>",
29 + _("There are %(count)d categories in this wiki."),
30 + ]
31 + summary_of_subpages = []
32 else:
33 - summary_of_subcategories = "<h2>" + _("Subcategories of <b>%(category)s</b>") + "</h2>\n" + \
34 - _("This category has the following %(count)d subcategories.")
35 - summary_of_subpages = "<h2>" + _("Pages in category <b>%(category)s</b>") + "</h2>\n" + \
36 - _("There are %(count)d pages are in this category.")
37 -
38 + summary_of_subcategories = ["<h2>" + _("Subcategories of <b>%(category)s</b>") + "</h2>",
39 + u"<span id='subcategory-heading'>" + _("This category has the following %(count)d subcategories.") + u"</span>",
40 + u"<div id='new-subcategory-dialog' class='new-subcategory-dialog'>",
41 + "%(newsubcategory)s"
42 + u"</div>",
43 + "<script type=\"text/javascript\">",
44 + "if (window.showToggle) {",
45 + " showToggle('subcategory-heading', ['new-subcategory-dialog'], '', \"" + _("add") + "\", \"" + _("hide") + "\", true);",
46 + "}",
47 + "</script>\n",
48 + ]
49 + summary_of_subpages = ["<h2>" + _("Pages in category <b>%(category)s</b>") + "</h2>",
50 + u"<span id='subpage-heading'>" + _("There are %(count)d pages are in this category.") + u"</span>",
51 + u"<div id='new-subpage-dialog' class='new-subpage-dialog'>",
52 + "%(newsubpage)s"
53 + u"</div>",
54 + "<script type=\"text/javascript\">",
55 + "if (window.showToggle) {",
56 + " showToggle('subpage-heading', ['new-subpage-dialog'], '', \"" + _("add") + "\", \"" + _("hide") + "\", true);",
57 + "}",
58 + "</script>\n",
59 + ]
60 +
61 + summary_of_subcategories = '\n'.join(summary_of_subcategories)
62 + summary_of_subpages = '\n'.join(summary_of_subpages)
63 result = []
64
65 # show sub category
66 + Parser = wikiutil.searchAndImportPlugin(request.cfg, "parser", request.page.pi['format'])
67 if show_cat:
68 for category in categorylist:
69 itemlist = []
70 + if category != "all":
71 + newsubcategory = wikiutil.renderText(request, Parser, u" <<NewPage(CategoryTemplate, %s, category=%s, validate=category)>>" % (_("Create a sub category"),category))
72 + else:
73 + newsubcategory = u""
74 for i in sorted( cc.get_sub_categories(category,recursive=recursive, exclude_template=exclude_template) ):
75 name = i
76 page = Page(request, name)
77 @@ -65,7 +94,7 @@
78 itemlist=[ (x[-2], x[-1]) for x in itemlist ]
79
80 if show_summary:
81 - result += [ summary_of_subcategories % {'category': category, 'count': len(itemlist)} ]
82 + result += [ summary_of_subcategories % {'category': category, 'count': len(itemlist), 'newsubcategory': newsubcategory} ]
83
84 if skipitems:
85 itemlist=itemlist[skipitems:]
86 @@ -76,7 +105,11 @@
87 # show pages belong to this category
88 if show_page:
89 for category in categorylist:
90 + template_pages = cc.get_templates(category, True)
91 + if template_pages:
92 + template_pages.insert(0, ('', _('<No addition>')))
93 itemlist = []
94 + newsubpage = wikiutil.renderText(request, Parser, u" <<NewPage(%s, %s, category=%s, validate=nocategory)>>" % (template_pages, _("Create a sub page"),category))
95 for i in sorted( cc.get_sub_pages(category,recursive=recursive, exclude_template=exclude_template) ):
96 name = i
97 page = Page(request, name)
98 @@ -102,7 +135,7 @@
99 itemlist=[ (x[-2], x[-1]) for x in itemlist ]
100
101 if show_summary:
102 - result += [ summary_of_subpages % {'category': category, 'count': len(itemlist)} ]
103 + result += [ summary_of_subpages % {'category': category, 'count': len(itemlist), 'newsubpage': newsubpage} ]
104
105 if skipitems:
106 itemlist=itemlist[skipitems:]
107 diff -r 7401f51c198b MoinMoin/wikiutil2.py
108 --- a/MoinMoin/wikiutil2.py Tue Nov 25 11:08:51 2008 +0800
109 +++ b/MoinMoin/wikiutil2.py Tue Nov 25 11:13:23 2008 +0800
110 @@ -254,20 +254,44 @@
111 return result
112
113 def get_templates(self, category, recursive=False):
114 - result = set()
115 - subpages = self.get_sub_pages(category, recursive, exclude_template=False)
116 - for item in subpages:
117 - if self.request.cfg.cache.page_template_regexact.search(item) is not None:
118 - result.add(item)
119 + """ Get templates list suitable for category.
120 + """
121 + result = []
122 + category_list = self._get_page_category_list('', category=category)
123 + for category in category_list:
124 + if category == 'CategoryCategory':
125 + continue
126 + subpages = self.get_sub_pages(category, recursive, exclude_template=False)
127 + for item in subpages:
128 + if self.request.cfg.cache.page_template_regexact.search(item) is not None:
129 + if item not in result:
130 + result.append(item)
131 + if result:
132 + break
133 return result
134 -
135 - def get_page_category_trail(self, pagename, level=9):
136 +
137 + def get_page_category_trail(self, pagename, level=9, category=''):
138 + """ Get category trail for page.
139 +
140 + For non-exist page, if we known category it should belong to, set category parameter.
141 + """
142 result = []
143 - self._get_page_category_trail( pagename, level, result)
144 + catlist = set()
145 + if category:
146 + catlist = set(category.split(','))
147 + if pagename:
148 + catlist = catlist | self.pagedict.get(pagename, set())
149 + if catlist:
150 + self._get_page_category_trail( catlist, level, result)
151 return result
152 -
153 +
154 def _get_page_category_trail(self, pagename, level, result, scanned=[]):
155 - categories = self.pagedict.get(pagename, set())
156 + # the first argument maybe a set of categories
157 + if isinstance(pagename, set):
158 + categories = pagename
159 + # the first argument is page name.
160 + else:
161 + categories = self.pagedict.get(pagename, set())
162 if categories:
163 level -= 1
164 for category in categories:
165 @@ -280,6 +304,18 @@
166 else:
167 self._get_page_category_trail(category, level, result, branch)
168
169 + def _get_page_category_list(self, pagename, level=9, category=''):
170 + category_list = []
171 + category_trail = self.get_page_category_trail(pagename, level=level, category=category)
172 + if category_trail:
173 + maxdepth = max ([len(trail) for trail in category_trail])
174 + for i in range(0,maxdepth):
175 + for trail in category_trail:
176 + if len(trail) < i+1:
177 + continue
178 + if trail[i] != 'CategoryCategory' and trail[i] not in category_list:
179 + category_list.append(trail[i])
180 + return category_list
181
182 def formatList(request, itemlist, column=3, show_capital=True):
183 """
5. Usage
Code |
Description |
<<ShowCategory(CategoryNews)>> |
Display a summary page for CategoryNews |
<<ShowCategory>> |
The category name is the name of current page. Display a summary page for it. |
<<ShowCategory(all)>> |
Display a list of all categories |
<<ShowCategory(CategoryNews, nocategories)>> |
Only display sub pages of CategoryNews, do not show sub categories. |
<<ShowCategory(CategoryNews, nopages)>> |
Only display sub categories of CategoryNews, do not show sub pages. |
<<ShowCategory(CategoryNews, nocat, nosummary)>> |
Do not show sub categories, and do not show summary of sub pages, only display list of sub pages. |
<<ShowCategory(CategoryNews, nocapital,nosum)>> |
Do not show summarys, and not show capital word in column list. |
<<ShowCategory(CategoryNews, recursive, descending)>> |
Show sub categories and sub pages recursively, and order by descending. |
<<ShowCategory(CategoryNews, rec, cat=0, items=20,skipitems=5,column=2,sort=timestamp)>> |
Show subpages recursively, sort by modify time, and only show item 6 to 26 in two columns. |
6. Copyright
7. License
GPL.
8. Bugs
I tried to adopt "ShowCategory" to MoinMoin 1.8.6. Unfortunately the file MoinMoin/wikiutil2.py does not exist. The following happened:
rudi@rudi72:~/moin-1.8.6$ patch <60010_macro_showcategory.patch The next patch would create the file ShowCategory.py, which already exists! Assume -R? [n] Apply anyway? [n] Skipping patch. 1 out of 1 hunk ignored -- saving rejects to file ShowCategory.py.rej can't find file to patch at input line 220 Perhaps you should have used the -p or --strip option? The text leading up to this was: -------------------------- |diff -r 0bfe351fb737 MoinMoin/wikiutil2.py |--- a/MoinMoin/wikiutil2.py Tue Nov 25 09:40:25 2008 +0800 |+++ b/MoinMoin/wikiutil2.py Tue Nov 25 10:17:40 2008 +0800 -------------------------- File to patch: MoinMoin/wikiutil2.py patching file MoinMoin/wikiutil2.py Hunk #1 FAILED at 8. Hunk #2 FAILED at 69. 2 out of 2 hunks FAILED -- saving rejects to file MoinMoin/wikiutil2.py.rej
What can I do to fix it? RudolfReuter 2009-12-30 11:13 MEZ
Hi RudolfReuter
please read HelpOnVariables and use SIG for a signature. wikiutil2 was never a second file from moin. May be the author has done a copy of it. -- ReimarBauer 2009-12-31 14:26:48
9. Discussion
9.1. Feature Request
First of all thanks for such a nice macro for moinmoin "ShowCategory". I am using it for my categories in my wiki by using the sort=timestamp. I have one question regarding to this macro. Is it possible to show the modify timeStamp with pages name list? e.g.
pageX 15m ago by Jiang
pageY 07:14 by Tom
PageZ 2010-02-16 by Jiang
At the moment, i am using it like this.
<<ShowCategory(nocapital,items=20,nosum,nocat,recursive,descending,column=1,sort=timestamp)>>
it shows me the pages list for my category and sort it by time stamp. I want to see also time stamp with page name (like moinmoin Recent Changes). So i can easily see that, at what time i made changes for my category pages. Maybe it would be also better to see that who has changed.
I tried some ways, but i couldn't able to print time stamp with page list.
from MoinMoin.util import timefuncs date = time.strftime("%d.%m.%y", timefuncs.tmtuple((wikiutil.version2timestamp(timestamp))) ) # UTC
Anybody has an idea, that how can i print the time stamp with page list. I shall be very thankful.
@SIG