First Pentropy plugin test successful
Filed under: pentropy breve pylonsThe tag cloud on the right side is now a plugin. I utilized the new xinclude feature of Breve to create a component-based page.
The main blog controller:
class PostController ( BaseController ):
# ...
@jsonify
api_tags ( self ):
tag_index = Tag.select ( order_by = [ asc ( Tag.c._name ) ] )
tags = [ ( t.name,
( h.url_for ( controller='post', action='by_tag', id=t.id ),
len ( t.posts ) ) )
for t in tag_index ]
return dict ( tags )
the plugin controller:
class TagcloudController ( BaseController ):
def cloud ( self ):
body = urlopen ( 'http://pentropy.twisty-industries.com/post/api_tags' ).read ( )
c.tags = simplejson.loads ( body ).items ( )
c.max = float ( max ( zip ( *zip ( *c.tags )[ 1 ] )[ 1 ] ) )
return render_response ( 'tagcloud/cloud?fragment=1' )
the plugin's template:
div [
ol ( class_ = 'tag-list' ) [ [
li [
span ( class_ = 'tag-context' ) [ '%d posts are tagged %s' % ( _posts, _tag ) ],
a ( href = _link, class_ = 'tag',
style = 'font-size: %0.2fem;' % ( 0.8 + _posts / c.max ) +
'color: rgb(%d,100,120);' % ( _posts / c.max * 180 ) +
'padding: %0.2fem;' % ( c.max / ( _posts or 1 ) / 10 ) )
[ _tag ]
] for _tag, ( _link, _posts ) in c.tags
] ]
]
and finally, the index template looks like this:
# index.b
html [
body [
...
xinclude ( 'http://pentropy.twisty-industries.com/tagcloud/cloud' )
...
]
]
The basic sequence of events goes like this: a request is made for index.b (or rather a child template that inherits index, but that's not relevant here), index.b requests the plugin via the xinclude directive. The controller at the url passed to xinclude accesses the published API available in the main controller to get the JSON data describing the available tags (a list of ( tagname, ( link, article_count ) ) ). It then renders its own template (cloud.b) and returns the XHTML output back to the main template which injects it into its own final output.
It seems like a lot of steps for something that could have been (and originally was) simply an included template. However what it provides in return is the ability to define completely encapsulated plugins that have no knowledge of the internal workings of the main application. All they require is a defined JSON (or XMLRPC) interface to retrieve their data from.
The next step is to define a caching mechanism to reduce the number of times this complete sequence must be traversed. In the case of the tag cloud, it's clear we can cache until a new post is made (tags are never created independently of posts in Pentropy). To this end I'll probably add a generic cache directive that will be utilized something like this:
html [
body [
cache ( expires = c.tags_changed ) [
h1 [ 'Tags' ],
xinclude ( 'http://pentropy.twisty-industries.com/tagcloud/cloud' )
]
]
]
Having a generic cache directive will allow for static HTML fragments to be stored based upon specific criteria. More on this later.





