2005

render_pattern: Repeat patterns easily in Nevow templates

After render_fragment, dialtone mentioned render_pattern, that would get one or many patterns from the page and put them in the current tag. Well, that's easy to write:

def render_pattern(self, name):
    """
    Find and render a pattern.

    Example:

    <span nevow:pattern="foo">
      I'm very repetititive.
    </span>
    <ul>
      <li nevow:render="pattern foo">
        this text will get removed when rendering
      </li>
      <li nevow:render="pattern foo"/>
    </ul>
    """
    def f(ctx, data):
        doc = self.docFactory.load(ctx)
        patterns = inevow.IQ(doc).allPatterns(name)
        return ctx.tag.clear()[patterns]
    return f

Updated to adapt doc to inevow.IQ before calling allPatterns.

render_fragment: Reusable fragment embedding in Nevow templates

This Nevow renderer came up on #twisted.web. Thanks to rwall and dialtone for input.

def render_fragment(self, name):
    """
    Find and render a fragment, with optional docFactory.

    Find a fragment factory from self via attributes named
    fragment_* and replace content of current tag with said
    fragment.

    If pattern docFactory is found under this tag, pass it as
    docFactory to the fragment factory.

    Example:

    class MyFrag(rend.Fragment):
        ...

    class MyPage(rend.Page):
        fragment_foo = MyFrag
        ...

    and give MyPage a template with

    <!-- no docFactory -->
    <div nevow:render="fragment foo">
      this text will get removed when rendering
    </div>

    <!-- with docFactory -->
    <div nevow:render="fragment foo">
      this text will get removed when rendering
      <span nevow:pattern="docFactory">
        but this whole tag will be passed as docFactory to MyFrag.
      </span>
    </div>
    """
    def f(ctx, data):
        callable = getattr(self, 'fragment_%s' % name, None)
        if callable is None:
            callable = lambda ctx, *args: ctx.tag[
             "The fragment named '%s' was not found in %r." % (name, self)]
        kwargs = {}
        try:
             docFactory = ctx.tag.onePattern('docFactory')
        except stan.NodeNotFound:
             pass
        else:
             kwargs['docFactory'] = loaders.stan(docFactory)
        return ctx.tag.clear()[callable(**kwargs)]
    return f
2005-12-21T22:45:00+02:00, originally published 2005-12-21T18:40:00+02:00

render_if: Conditional Parts in Nevow Templates

This Nevow renderer has saved me a lot of time:

def render_if(self, ctx, data):
    r=ctx.tag.allPatterns(str(bool(data)))
    return ctx.tag.clear()[r]

Use it like this:

<nevow:invisible nevow:render="if" nevow:data="items">
  <ul nevow:pattern="True"
      nevow:render="sequence">
    <li nevow:pattern="header">The items are a-coming!</li>
    <li nevow:pattern="item">(the items will be here)</li>
  </ul>
</nevow:invisible>

And now, if the list returned by data_items is empty, there will be no <ul> tag at all in the output.

I just realized non-boolean tests may be wanted -- for example, test if a string matches a regexp. You could do that by mangling the data before render_if, but that's not nice, because then you don't have access to the original data inside nevow:pattern="True". So, instead let's parametrize the test:

def render_ifparam(self, name):
    tester = getattr(self, 'tester_%s' % name, None)

    if tester is None:
        callable = lambda context, data: context.tag[
             "The tester named '%s' was not found in %r." % (name, self)]
        return callable

    def f(ctx, data):
        r=ctx.tag.allPatterns(str(bool(tester(data))))
        return ctx.tag.clear()[r]

    return f

Note how we still cast the return value of the tester to boolean. You could avoid that and call the renderer render_switch. Adding support for Deferred tests would be quite easy, too. The only ugly part is I don't know of any way to make the same renderer work nicely for nevow:render="if" and nevow:render="ifparam foo".

[Updated to add return f, also renamed second render_if to render_ifparam to clarify things a bit. Thanks k3mper.]

2006-03-22T22:52:00+02:00, originally published 2005-12-17T16:59:00+02:00

My review of Twisted Network Programming Essentials

I've just finished my review of the book Twisted Network Programming Essentials by Abe Fettig. Now go read it.

You may also be interested in an earlier review I wrote about Foundations of Python Network Programming.

2005-11-30T17:23:00+02:00, originally published 2005-11-29T02:12:00+02:00

turku-dev: Kehittäjätapaaminen Turussa

This entry is about a local software developer gathering, and written in Finnish. My apologies if it is complete gibberish to you, but atleast you can stare at the pretty ä dots.

Mikä?

Vapaamuotoinen tapaaminen ohjelmistoja työkseen ja/tai harrastuksekseen tekeville, tai muuten aiheesta kiinnostuneille.

Tutustutaan ihmisiin, puhutaan mukavia, syödään ruokaa. Jos haluat kertoa hienosta uudesta softasta, jota olet juuri tekemässä, löydät varmaan jonkun samanmielisen. Jos tarvitset apua hankalaan ongelmaan, joku varmaan on joskus tehnyt jotain samankaltaista. Eikä ihmisten tunteminen ainakaan haittaa urakehitystäkään.

Sillä ei ole väliä onko työkalusi C, Perl, Java, Python, Ruby vai PHP; tai Linux, BSD, OS X vai jopa Windows. Vapaat/avoimet ohjelmistot ovat monelle meistä tärkeitä, joten niiltä et kokonaan pysty välttymään, mutta tarkoitus on vain saada samanhenkisiä ihmisiä kokoon.

Missä?
Turun keskustassa oleva ravintola Harald, katso kartta.
Meitä kiinnostaa eniten Turun seudun toiminta, mutta ajatuksia "road showsta" on heitetty ilmaan, eli jatkossa kehittäjätapaaminen saattaa olla sinunkin lähikuppilassasi.
Koska?

Nyt lauantaina, 26.11. n. klo 12:30 alkaen. Niin pitkään kun intoa riittää.

Seuraava kerta varmaan joskus tammikuussa, ja siitä sitten eteenpäin vaikka kuukauden tai parin välein.

Kuka?

Tällä tapahtumalla ei ole virallista järjestäjää, eikä se liity minkään yhdistyksen tjms. toimintaan. Minä aloin asiasta tutuille puhumaan, Tero Kuusela on tehnyt lähes kaiken valmistelutyön.

Tällä hetkellä aiheesta kiinnostuneiden ihmisten taustoja ja kiinnostuksia: VSTKY, Linux-Aktivaattori, Debian, Python, Linux kernel, Google Summer of Code, jne..

Tahtoo!

Liity postituslistalle. Listan osoite on turku-dev@lists.inoi.fi ja liittyminen tapahtuu lähettämällä viesti osoitteeseen turku-dev-subscribe@lists.inoi.fi ja vastaamalla vahvistus-pyyntöön.

Ihmismäärän arvioimiseksi pyydän, että ilmoitat tulostasi etukäteen osoitteeseen Tero Kuusela <tero@teroajk.net>.

2005-11-25T15:33:00+02:00, originally published 2005-11-22T15:48:00+02:00
by Tommi Virtanen <>

The MochiKit screencast is very nice

"It's simply a more convenient syntax."

"MochiKit is full of more convenient syntax."

The MochiKit screencast is great. I think screencasts are a great way to introduce people to new software.

2005-11-21T16:47:00+02:00

I registered at Technorati.com

I just registered at Technorati, and it requires me to post an entry claiming my Technorati Profile.

..and when I registered an alternate URL for it, they required me to do it all over again: Technorati Profile.

2005-11-21T01:56:00+02:00, originally published 2005-11-21T01:37:00+02:00

New website template

Just finished a new website layout. I'm reasonably pleased with it.

Tags:
2005-11-20T17:34:00+02:00

Python is confusing

>>> def simple(): yield 'a'
...
>>> ', '.join(simple())
'a'
>>> def horrible():
...     if ' ' not in False: yield 'a'
...
>>> ', '.join(horrible())
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: sequence expected, generator found
>>>

But it does accept generators!

(Yes, I know what triggers it to say that. It's still horribly misleading.)

2005-11-02T14:40:00+02:00

Using nevow.guard the smart way

<ronwalf> ok, I give up... How do I get the AVATAR_LOGIN stuck
between the SessionWrapped resource ul and the current
resource url

Well, we aim to please.

def getActionURL(ctx):
    request = inevow.IRequest(ctx)
    current = url.URL.fromRequest(request).clear()
    root = request.getRootURL()
    root = url.URL.fromString(root)
    assert root is not None
    root = root.pathList()
    me = current.pathList(copy=True)
    diff = len(me) - len(root)
    assert diff >= 0
    action = current
    if diff == 1:
        action = action.curdir()
    else:
        while diff > 1:
            diff -= 1
            action = action.parent()
    action = action.child(guard.LOGIN_AVATAR)
    for element in me[len(root):]:
        action = action.child(element)
    return action

Comment from ronwalf (on IRC) on 2005-09-17T00:06:57:

<ronwalf> Better.  after root = root.pathList()
<ronwalf> if root == ['']: root = []
2005-09-17T00:06:57Z, originally published 2005-09-16T22:59:00+02:00

Turuxi gathering looks a bit too boring :(

The Turuxi gathering today looks like a bit too boring for me, personally. I think I'll go xycle instead.

2005-09-16T15:23:18+02:00
2005-12-27T11:48:00+02:00, originally published 2005-12-21T19:18:00+02:00