[Grok-dev] Re: GrokPaste: a grok pastebin app

Philipp von Weitershausen philipp at weitershausen.de
Sat Mar 24 05:15:44 EDT 2007


Kevin Teague wrote:
> Right now the app just has enough features to perform the basics of a 
> pastebin app. Long term, I'd like GrokPaste to be a fairly feature rich 
> pastebin app.
> 
> There is an instance running at:
> 
> http://www.bud.ca:8021/grokpaste/

Way cool. I love the design. A few comments on the code:

* I saw you copied the cookie credential implementation from my book.
   It's available in a separate package for your convenience:
   http://cheeseshop.python.org/pypi/wc.cookiecredentials.

* Any reason that grokpaste.paste.Pastesite is not a grok.Application?

* You configure the PAU plugins in an object *modified* event subscriber
   for the site object. That seems odd. It really should be an *added*
   subscriber. But even that isn't necessary because you can simply use a
   setup routine for the PAU local utility. I did a similar thing in
   NudgeNudge:
   http://codespeak.net/svn/z3/NudgeNudge/trunk/src/nudgenudge/app.py

(Btw, I can't seem to access the raw SVN, only the trac browser.)

> Currently the code is still very rough. I plan on applying some polish 
> to, and packing it into a tarball so we can link to from the Grok site.

Yes. It'd also be nice if this were available on the CheeseShop somehow :).

> Traversal
> ------------
> 
> Human readable URLs are not yet as easy to work with as other framworks, 
> Rails/Django etc. It might be cool to have some Traversal conventions. 
> Perhaps some convenience methods in the Traversal base class?
> 
> To support URLs such as /tags/foo/bar I wrote:
> 
>     def traverse(self, name):
>         if name == 'tags':
>             self.request.form['tags'] = self.request.getTraversalStack()
>             self.request.setTraversalStack([])
>             return queryMultiAdapter(
>                 (self.context, self.request), name='tagsearch')
>         else:
>             # try to get the item from the container
>             return self.context.get(name)

By the way, I don't think you have to do the "else" clause. If 
traverse() returns None, the standard traversal behaviour is assumed 
(which is container.get()). That should shorten traverse() 
implementations by a lot already.

Furthermore, I don't quite like how you manipulate request.form. The 
request is supposed to be read-only. Better set values on self (the 
view) if you want them to be accessible from the template.

> Something like this could be nice:
> 
>     def traverse(self, name):
>         if name == 'tags':
>             self.viewStackToList('tagsearch')
>         else:
>             # try to get the item from the container
>             return self.context.get(name)
> 
> Either that or some pre-built Traversal components that perhaps expect a 
> URLConfig Model to available?

During the sprint we were pondering about making traverse() take an 
arbitrary length of positional arguments, e.g.:

   def traverse(self, *traverse_subpath):
      ...

or in your case

   def traverse(self, name, tag=None):
      if name == 'tags' and tag is not None:
          ...

Would that help?

> Human Readable Time Deltas
> -----------------------------------------
> 
> I really like web sites with "posted 4 hours ago". To that end I made a 
> TimeReadable Global Utility. Right now this includes about 50 lines of 
> code that I grabbed from django.utils.timesince.py.
> 
> It would be nice to eventually have this functionaly in a megrok 
> package, or Grok core.

Sounds sensible. It would be even nicer if we didn't have to maintain 
this sort of stuff. Perhaps people who want this should simply install 
the django egg or we should depend on it for this kind of stuff?

> Development experience
> ----------------------------------
> 
> Grok rocks! w00t!
> 
> Consider the Plain-text Paste View:
> 
> class PastePlainView(grok.View):
>     "Plain-text view of a single Paste"
>     grok.context(Paste)
>     grok.name('plain')
> 
>     def render(self):
>         return self.context.body
> 
> Where in Zope 2 I might write:
> 
> /skins/grokpaste_scripts/pastePlainText.py
> ## Script (Python) "pastePlainText"
> ##bind container=container
> ##bind context=context
> ##bind namespace=
> ##bind script=script
> ##bind subpath=traverse_subpath
> ##parameters=
> ##title=Plain-text view of a single Paste
> 
> return context.body
> 
> 
> And in Zope 2 I'd have to keep the code in a skins directory, floating 
> around with a bunch of other unrelated files. And in Zope 3 I'd have to 
> write a bunch of ZCML. With Grok I can put all my Paste Views beside 
> each other, and I only need to state the bare essence of what I want the 
> app to do - yummy!

Great analogy. I love that. I think this will buy us our way into the 
CMF / Plone world :)


-- 
http://worldcookery.com -- Professional Zope documentation and training


More information about the Grok-dev mailing list