This is the starter page for a collection of coding snippets for use in a zwiki. Please post comments and questions to GeneralDiscussion. (There's also the old DTMLCookbookDiscussion, but I think it's more about meta issues.)
cleanup
this page was renamed from ZwikiCookbook, but it's not just dtml.. rename back ? separate pages ? CookBook? ?
todo: replace live examples
Contents
- List all pages with names beginning "HowTo..."
- Wiki-link a page name or arbitrary text
- Look up a page object by name
- Include one page's content in another
- Include a page's content in a page template
- Table of contents macro
- Link to the latest messages in a mailman archive
- Get zope memory usage
- Generate colours and progress bars
- Zwiki issue tracker maintenance
- Create Discussion pages on demand
- Todo list app
List all pages with names beginning "HowTo..."
Here it's done in one line using a list comprehension:
<dtml-var "_.string.join([b.Title for b in pages() if b.Title.startswith('HowTo')], '<br>')">_.string is the standard python string library.
pages() is Zwiki's fundamental wiki-searching method. It searches the [Catalog]?, for better scalability in large wikis, and returns a list of catalog brains which contain the frequently used page attributes like Title.
You can give it zcatalog-style search arguments, so we could search directly for pages with names beginning "HowTo", but zcatalog isn't always able to do wildcard matching so instead we search for all pages and filter the results ourselves.
startswith is a standard method of python string objects.
Wiki-link a page name or arbitrary text
The wikilink() method converts any WikiNames in text to hyperlinks. Actually it's just an alias for renderLinksIn():
<dtml-var "wikilink(text)">
Look up a page object by name
<dtml-let page="pageWithName(pagename)">Unlike pages(), this returns a real page object.
Include one page's content in another
Here's the easiest way:
<dtml-var "include('ThePage')">which will fail silently if the page does not exist. Otherwise it is equivalent to:
<dtml-var "pageWithName('ThePage')(REQUEST=REQUEST,bare=1)">That is,
- get hold of the page object
- call it so it renders itself
- pass the bare argument so it doesn't add the usual skin
- pass the REQUEST in case the user's current authentication is needed
Include a page's content in a page template
<div tal:content="structure python:here.include('ThePage')" />In page templates called by Zwiki, here is the current wiki page.
Table of contents macro
Here is an old DTML+PythonScript macro that makes a fancy sort of ski-slope-colour-coded audience indicator and triple table of contents which I used on zwiki.org for a while. See eg QuickReference.
This only works for DTML-enabled wikis and requires manual maintenance of the contents entries and link targets, but less than if you did everything by hand. RestructuredText's .. contents:: directive is usually preferable nowadays. For more information see [http://custom-paper-writing.com/ custom paper]?.
## Script (Python) "toc" ##bind container=container ##bind context=context ##bind namespace= ##bind script=script ##bind subpath=traverse_subpath ##parameters=columns, headings=('Basics','Intermediate','Advanced'), colours=('green','red','black') ##title= ## linkindex = 1 print """ <!-- toc macro start --> <table border="0" width="" align="center"> <tr> """ columnwidth = '' #100/len(columns) colindex = 0 for column in columns: print """ <td valign="top" width="%s%%"> """ % (columnwidth) if column == None or column == 0: print """ """ else: heading, colour = headings[colindex], colours[colindex] print """ <div style="color:white; background-color:%s; font-weight:bold; text-align:center;padding-left:1em;padding-right:1em;">%s</div> <div class="pagecontents" style="font-size:small;"> <table> <tr> <td valign="top"> <ol style="margin-top:0; margin-bottom:0; margin-right:2em;" class="subtext" start="%s"> """ % (colour,heading,linkindex)#colour,colour,linkindex) if column != 1: for link in column: print """ <li><a href="#%s">%s</a></li> """ % (linkindex,link) linkindex += 1 print """ </ol> </td> </tr> </table> </div> </td> """ colindex += 1 print """ </tr> </table> <!-- toc macro end --> """ return printedInstall this as a pythonscript with id toc in the ZODB, then call it at the top of any DTML-enabled wiki page like this:
<dtml-var "toc((['basic topic 1','basic topic 2'], ['intermediate topic'], ['advanced topic'], ))">The links point to #1, #2, etc. and you need to create those named anchors at the start of each corresponding section of the page. You could also do this:
<dtml-var "toc(([],None,None))">or override the column headings and colours. The layout may or may not work as well in the plone skin.
Link to the latest messages in a mailman archive
<a href="/pipermail/LISTNAME/<dtml-var "_.str(ZopeTime().year())+'-'+ZopeTime().Month()">/thread.html#end">latest</a>
Get zope memory usage
Install this as an ExternalMethod with id memusage:
def memusage(self): """ Get this process's memory usage. """ # method 1 # may not work on virtual private servers import resource usage = resource.getrusage(resource.RUSAGE_SELF)[2] if usage > 0: return usage # method 2 # requires a unix-style ps command # may fail in low memory situations import os try: return int(os.popen('ps h -o vsize %s'%os.getpid()).read()) except: return 0then you could display it with <dtml-var memusage>. See WikiStats, MemoryUsage.
Generate colours and progress bars
This generates a green-red gradient, useful for a memory usage indicator:
<dtml-in "[0,10,20,30,40,50,60,70,80,90,100]" prefix=x> <dtml-let test="x_sequence_item*1000" mem="test #memusage()[2]" max="100000" usage="_.int(mem/(max/100))" free="100-usage" r="221+usage/3" g="250-usage*usage/40" b="250-usage*usage/40" colour="'#%02x%02x%02x'%(r,g,b)" m="(usage>30)*255" fontcolour="'#%02x%02x%02x'%(m,m,m)" > <small> <table border=0 cellpadding=0 cellspacing=0 width="100%"> <tr> <td width="&dtml-usage;%" bgcolor="&dtml-colour;" style="color:&dtml-fontcolour;;"> <b>memory usage: &dtml-mem; (&dtml-usage;%)</b> </td> <td width="&dtml-free;%" > </td> </tr> </table> </small> </dtml-let> </dtml-in>See ColourTests for more.
Zwiki issue tracker maintenance
Here are some things you can do at the zopectl debug prompt (see ZopeWiki:DebuggingZope for more about this).
Recategorize a number of issues:
>>> t = app.wikifolder.anypage >>> change = lambda num,cat: t.issuePageWithNumber(num).changeIssueProperties(category=cat) >>> [change(n,'newcategory') for n in [23,101,42]] >>> get_transaction().commit()Recategorize a whole category, without sending mail:
>>> t = app.wikifolder.anypage >>> def change(old,new): ... for p in t.pages(category=old): ... p.getObject().category=new ... p.getObject().index_object() ... >>> change('oldcategory','newcategory') >>> get_transaction().commit()