Size: 15511
Comment:
|
Size: 14579
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 42: | Line 42: |
I had to add a new `format` function, one that, rather then using `self.request.write` to output its results, it simply adds to a string (self.output), which it then returns. I added the following function (attachment:formatInMemory.py) (please note, all i did was to copy the base `format` function, and replace all the `request.write` calls to `self.output +=`.) to `MoinMoin\parser\wiki.py`. Also, changes were made to `macro\FootNote.py` (see the diff: attachment:footnotediff.txt or see the new `emit_footnotes` function): {{{#!python def emit_footnotes(request, formatter): # emit collected footnotes if request.footnotes: result = [] result.append('<div class="footnotes">') result.append('<div></div><ul>') for idx in range(len(request.footnotes)): fn_id = request.footnotes[idx][1] fn_no = formatter.anchorlink('fnref' + fn_id, str(idx+1), id = 'fndef' + fn_id) result.append('<li><span>') result.append(fn_no + '</span> ') from MoinMoin.parser import wiki from MoinMoin.formatter import text_html parser = wiki.Parser(request.footnotes[idx][0], request) parser.formatInMemory(formatter) result.append(parser.formatInMemory(formatter)) result.append('</li>') result.append('</ul></div>') request.footnotes = [] return ''.join(result) return '' }}} |
I had to add a new `format` function, one that, rather then using `self.request.write` to output its results, it simply adds to a string (self.output), which it then returns. I added the following function (attachment:formatInMemory.py) (please note, all i did was to copy the base `format` function, and replace all the `request.write` calls to `self.output += blah_blah()`.) to `MoinMoin\parser\wiki.py`. Also, changes were made to `macro\FootNote.py`. You can use the diff (attachment:footnotediff.txt) or copy and paste the new code /FootNotesCode. |
Why and Wherefore
I've been using several different wiki tools over the past few years, both at work and home. Zwiki, UseMod and now MoinMoin have seen use. I'm currently enamoured with MoinMoin as it's in Python, like Zwiki, but much easier to code for. Here are a list of some of the ideas that i've been playing around with, to enable some ProjectManagement features that i think would be useful. Note - most of this comes from the inspiring work done on WikiDb by NickTrout.
You can reach me at MailTo(jos AT theorganization NOSPAM DOT net).
Wiki as a ProjectManagement tool
Really, there is more to come here!
Wiki as a game playing platform
I really like how easy it is to both code up a rules engine (a macro), and the framework that the wiki offers (pages for move entry), when looking at Moin as a game playing tool.
Rock Paper Scissors
I just uploaded my rock-paper-scissors game macro to the MacroMarket (see MacroMarket_2fRockPaperScissors).
Checkers links and things
http://www.jimloy.com/checkers/rules.htm The Standard Laws of Checkers
http://www.acfcheckers.com/ American Checkers Federation
http://www.jimloy.com/checkers/numbered.htm The numbered Checker board - excellent! This is all i need to get started!
Patches and other code goodies
Footnotes macro
There is a request (see MoinMoinTodo Release 1.3) for the footnotes macro to be able to display wiki markup.
I've got a version of this running, but it required some largish hacking on the MoinMoin\parser\wiki.py file to get to work.
I had to add a new format function, one that, rather then using self.request.write to output its results, it simply adds to a string (self.output), which it then returns. I added the following function (attachment:formatInMemory.py) (please note, all i did was to copy the base format function, and replace all the request.write calls to self.output += blah_blah().) to MoinMoin\parser\wiki.py.
Also, changes were made to macro\FootNote.py. You can use the diff (attachment:footnotediff.txt) or copy and paste the new code /FootNotesCode.
Form
I've gotten forms working to the point where i can define a form in the wiki, and have the date update or create a new page. It requires the the following diff to the form.py macro: attachment:form.py.diff
What this does is allows for 2 extra args to the form macro. The name of the action (formaction) you want executed and the page that you want the output of the action to affect (addtopage). Only the formaction arg is required. So, you can now put actions into the action folder and submit data to them with from a form. See the example below.
Example
Here is an example which uses a form to post blog-like entries.
The form itself (on a page called BlogForm)
#form type=caption name=dummy label="Weblog Entry Form" #form type=text name=headline label="Headline" size=40 maxlength=50 #form type=textarea name=text label="Text" rows=10 cols=60 #form type=submit name=save label="Add entry"
The blogpost.py action that will be called (put this into the action folder): attachment:blogpost.py
And the macro call to Form:
[[Form(BlogForm,blogpost,JosYule/MyBlog)]]
The actual post is created on a subpage of JosYule/MyBlog. I've got the MonthCalendar macro running on the /MyBlog page, and the Form creates new posts on sub-pages of /MyBlog in the same format as MonthCalendar, allowing easy use of the wiki:macro/IncludePages macro to create a blog like thing.
Trackback
I've had some great feedback to the work that i've done on the trackback project so far. One of the first things i've got to fix is how the trackback.py action get called, as it was pointed out to me that they way i currently have it, it will only work for CGI based installs. It was suggested to me to use some kind of name suffix, like __trackback__ (JosYule__trackback__), which could be checked for in request.py at the same time that the XMLRPC stuff if checked (thanks OliverGraf, AdamShand and other #moin irc'ers). This suffix could be configurable as well. I'm still not sure where to save the data - this is an open question to any and all Moin devs.
The second part of the trackback stuff, is the sending of trackback pings to urls contained on a Moin page. I think the easiest way to enable this is to just write a action, SendTrackback.py. This action will also have to create some persistant data, which should be written to the same place that the trackback data is written to (i'm assuming).
Resources and Links
[http://www.movabletype.org/trackback/beginners/ What is Trackback?]
[http://www.movabletype.org/docs/mttrackback.html Trackback Protocol]
R 0.2 info
Added config vars: allow_trackback 0|1, trackback_suffix defaults to __trackback__, but could be whatever one wanted.
Trackback is now detected in the run() method of request.py (just after the XMLRPC detection) rather then the previous mutant GET/POST mess.
I'm going to put all the trackback related data (sent and received pings) in the data/pages/<pagename>/trackback folder. This follows how/where attachments are saved. I'm still not sure of the format for saving the trackback data. XML? RSS? Plain-text? A pickled object?
- I don't think it really matters too much. My only real request is that it's something which can be edited with a normal text editor rather then having to write a program to parse it. -- Adam
R 0.1 instructions
Please note that this code is soon to change in a pretty big way - this is just for experimenting with!!!
Add the variable allow_trackback to the config.py file. It is set to 0 by default, so if you want this to work, you also have to added the var to the moin_config.py file, and set it to 1.
Add the following line to _setup_args_from_cgi_form (from request.py), just before the return args line.
1 if not args.has_key('action') and os.environ["QUERY_STRING"]:
2 args['action'] = [os.environ["QUERY_STRING"].split('=')[1]]
Copy attachment:trackback.py and attachment:ViewTrackbacks.py to your action directory
Apply the following diff to Page.pyHere is the diff for Page.py (from moin 1.2.x)
629a630,646 > # Trackback RDF > if config.allow_trackback: > permalink = "http://" + request.server_name + request.script_name + "/" + wikiutil.quoteFilename(self.page_name) > trackback_url = permalink + "?action=trackback" > request.write(""" > <!-- > <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" > xmlns:dc="http://purl.org/dc/elements/1.1/" > xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> > <rdf:Description > rdf:about="%s" > dc:title="%s" > dc:identifier="%s" /> > trackback:ping="%s" > </rdf:RDF> > -->""" % (permalink, self.page_name,permalink,trackback_url)) >
Future Ideas
Users who are subscribed to be notified of changes should be notified of new trackbacks? AdamShand
It would be nice if trackbacks were incorporated into the RecentChanges page somehow (or something similar so site admins could keep up with what's going on). AdamShand
Both the above are kind of related. I think the email-new-trackbacks is probably more doable then the RecentChanges, but i've not even looked at the code yet. JosYule
At some point the ability to send trackbacks will probably need to be able to be acl'd to stop abuse. AdamShand
I'm not really clear how to plug an action into the ACL framework. Again, i'll have to look at the code. JosYule
It would be nice if there was a way to display any trackbacks inline on the page (eg. ShowTrackBacks). AdamShand
This is already in the works -- JosYule
Instead of having both a ViewTrackbacks and a SendTrackbacks action, what about just having a "Trackbacks" action which displays any trackbacks for that page and also has a form which can be used to send one? AdamShand
The SendTrackback action works 'automagically' - it parses all the hrefs on the current page, checks each one for trackback RDF and if it finds some, sends a trackback ping to the listed url. I had not intended to have an actual 'form' for sending trackbacks (see [http://www.movabletype.org/docs/mttrackback.html#autodiscovery%20of%20trackback%20ping%20urls this]). JosYule
- Right, sorry that makes sense. I was thinking about it from a manual point of view but of course you are correct that this is the easist way. -- Adam.
When you have a page which includes multiple other pages then you end up with multiple a trackback RDF section for each included page. I have no idea if this is legal but I suspect not. View the source of my blog pages (for an example see: AdamShand). -- Adam.
Old News
Ah-ha! I've got a alpha-version of trackback working, using just moin.cgi. It requires a tweak to the request.py file and 2 'action' scripts - trackback.py and ViewTrackback.py.
I still don't know where to write the trackback data. I was thinking into a folder in the data directory called trackback, or into the data/pages/pagename directory. The trackback data itself is currently written to a xml file ([http://my.netscape.com/publish/formats/rss-spec-0.91.html RSS] format) which is named the same as the page.
This is the line that gets added to _setup_args_from_cgi_form (from request.py), just before the return args line.
1 if not args.has_key('action') and os.environ["QUERY_STRING"]:
2 args['action'] = [os.environ["QUERY_STRING"].split('=')[1]]
This had to be added, as trackback is sent via a POST, and the request.py file, when POSTed too does not properly read the QUERY_STRING which is part of the URI. I don't know how/if this causes any bugs, tho nothing has come up yet.
This sounds like a combination of GET and POST, which is much like xmlrpc detection in Request.run(). Perhaps it should be done along the same lines to avoid possible confusion? -- OliverGraf DateTime(2004-06-18T13:33:15Z)
The trackback requests are not xml but real cgi x-www-form-urlencoded POSTs. So its really mixed up cgi if it uses QUERY_STRING. I don't know if this is standarts conform. There could be browsers out there stripping the stuff behind the ?. Possible solution: add __TrackBack__ after the page name and depend on this... one could even make this suffix configureable to avoid (unlikely) name clashes -- OliverGraf DateTime(2004-06-18T13:40:52Z)
I am going to have to modify Page.py, specifically send_page() to include the RDF for trackback auto-discovery. I'd like to include a new config variable allow_trackback. This would turn on or off the adding of the RDF to each page, and the use of the trackback action. I've had to add this to the config.py file.
I've included the attachment:trackback.py action and the attachment:ViewTrackbacks.py action. Please note that the trackback.py action wants to save trackback info in a sub-dir of your data dir called trackback. I didn't know where else to save this data, and i'm going to need a place to deal with the remembering of pinged URLs when i start with the auto-pingback stuff.
if that data can be deleted without losing something valuable (sorry, I don't know what all that "trackback" stuff is about), you could use the moin caching routines, see MoinMoin.caching
- unfortunatly, the data has to persist, see below. Thanks for the heads-up tho.
I think it should go into data/pages/<pagename>/trackback/ -- Adam
I've now changed Page.py to include the RDF for trackback auto-discovery. I've tested it out with Movable Type, and it all works great. What i now need to figure out is who to talk to about getting this added to 1.3, or if there is even interest in having this in 1.3...
Yes, please! This is great stuff!
-- AdamShand
Here is the diff for Page.py (from moin 1.2)
629a630,646 > # Trackback RDF > if config.allow_trackback: > permalink = "http://" + request.server_name + request.script_name + "/" + wikiutil.quoteFilename(self.page_name) > trackback_url = permalink + "?action=trackback" > request.write(""" > <!-- > <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" > xmlns:dc="http://purl.org/dc/elements/1.1/" > xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> > <rdf:Description > rdf:about="%s" > dc:title="%s" > dc:identifier="%s" /> > trackback:ping="%s" > </rdf:RDF> > -->""" % (permalink, self.page_name,permalink,trackback_url)) >
The next part of this would be auto-trackback discovery for any page. The wiki would go through all the external links on a page and try to find if any of them are trackbackable. If so, it would then send a ping to that page. This would allow for true wiki-to-wiki backlinks. Pretty interesting stuff. However, there are some very large questions that need to be answered around sending PINGs. Some that come to mind off the top are: the time needed to check the URLs for trackbackability, and the sending of the pings themselves (again the time issue), and keeping some list of pings already sent, so that each time a page is edited you don't keep sending the same pings.
Maybe make the auto-trackback functionality another edit time option (like removing whitespace and notifying via email). That way it's only done when the author feels there is a reason. -- AdamShand
As part of the auto-trackback, there would be a need to keep track of what URLs on a page have already been pinged. On each save, this list would be comparied with all URLs found on the page. Any new URLs would be checked for trackback, and if found, pinged. All the new URLs would be added to the list, so they would not get checked on the next save of the page.