Tuesday 5 February 2008

New Blog location!

There is a new home for the Team Rubber Developer Blog!

After many long nights of negotiations and some most excellent begging, the developers have been asked to join the Team Rubber blog family.

Find it here: teamrubber.com/blog. We've even got our own category!
Enjoy

Wednesday 9 January 2008

Content and Blogs

I'm sure that every person who tries to make money from blogs has a two main questions in mind:

Well, now we have two new system live that should help with these problems.

The Viral Ad Network offers publishers (i.e. you) the chance to get your hands on some of the best viral ads, and make money from them in the process.

Meanwhile, Viral Sauce - our viral video search engine - is taking signups for an alpha version of it's customised video feed service - which supplies you with custom video feeds for your website or blog.

For more information go to viraladnetwork.net , viralsauce.com or you can watch our webmaster tutorial video series for viral sauce.

By the way, we also have a new blog up - check it out at www.teamrubber.com/rubber

Wednesday 2 January 2008

A taste of GHOP

Something slightly less rubbery is the GHOP competition I mentioned a few weeks back. I thought I'd update everyone and put up some screenshots of the themes that our GHOP participants have created to date. These are all plone 3 themes, and in the collective to play with right now.
plonetheme.andreas01

plonetheme.blue_blog

plonetheme.essay

plonetheme.python

NB: This blog has moved to http://www.teamrubber.com/rubber/?cat=3 – planet.plone.org hasn't been updated with the new feed yet. If you feel the urge to comment please do so there

Wednesday 12 December 2007

GHOP help needed (with pretty graph)

If you haven't heard of GHOP yet, check out optilude's blog post on the subject.

... right, now everyone's up to speed, here's a pretty graph from the statistics that have been sent around everyone on the admin email list:



You'll notice we're dead last in terms of students claiming tasks. I don't accept that plone is inherently less interesting than these other projects, so we've just not got the right tasks.

Please, take the time to have a look at the list of available tasks and submit new ideas to the wiki. If you've got some more free time, email optilude and volunteer to help out by maintaining the task list and helping students.

This is a great opportunity to get young people involved in the community and have some niggling issues fixed, let's not waste it.

Sunday 21 October 2007

Cookin' with traverse_subpath


I've heard a few people mention this, so I thought I'd post this recipe. We're using a simpler version in Vice to prettify some URLs, but it was so easily generalised I knocked an example together.

The idea is that the traverse_subpath variable from Script (Python) was a nice recipe for getting information from URLs. You might have a URL http://127.0.0.1:8080/test/traverse_subpath/a/v/121/a/a/a/1213 and want the list ["a", "v" "121", "a", "a", "a", "1213"].

It turns out that as z3 views are based on their own traversal mechanism, it's really easy to override to get something to emulate this behaviour.

So, set up your view as you usually would, but note the subtle differences from the boilerplate:

traversesubpath.py
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope.publisher.browser import BrowserPage

class subpath(BrowserPage):

def __init__(self, context, request):
self.context = context # Use Martin's aq_magic
self.request = request
self._path = []

def publishTraverse(self, request, name):
self._path.append(name)
return self

@property
def traverse_subpath(self):
return self._path

__call__ = ViewPageTemplateFile('traversesubpath.pt')


traversesubpath.pt
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
lang="en"
i18n:domain="plone">

<ul>
<li
tal:repeat="pathitem view/traverse_subpath"
tal:content="pathitem" />
</ul>

</html>
With the URL I gave above, I get the following page rendered:
  • a
  • v
  • 121
  • a
  • a
  • a
  • 1213

It's that simple.

Friday 28 September 2007

A confession from the boss

We have a system where jobs have a status (active, inactive etc), which is stored in a field. There is also a list for each status containing the IDs of all the jobs matching that status.

When the status of a job is changed, a form-handling script updates the status of that job, and modifies the status lists. IF Andy writes code that does approximately the following things in roughly the following order:

* first check the status field of every job and update the status lists accordingly
* then write the new status of this job into the status field

which ahem, kind of doesn't work. Forget 'kind of', it's just flawed code and flawed thinking that causes other people problems in getting their work done, their timesheets entered, their tea made.

SO now the form handler does this instead:

* first write the status of this job into the status field
* then check the status field of every job and update the status lists accordingly

This is an example where, by trying to write a script that would be more robust (check all kubes and update everything JUST IN CASE), we end up with more errrrors than if I'd just followed the apparently sketchier route of appending the job to one status list and removing it from another. Hey ho.

Miami, er, Bristol Vice

We've been working on the new Vice syndication project, integrating it into our new Viral Content Manager system. Although the system is still pre-alpha it is very impressive! The basic structure of our content types is:

ContentItems are contained in a folderish portal tool, and contain a reference to 0..* ContentChannels which can be anywhere.

We now have working RSS and ATOM feeds for the ContentItems associated with a given ContentChannel, looking like this:

from zope.interface import implements
from zope.component import adapts, queryMultiAdapter, getMultiAdapter
from zope.interface import Interface
from Products.VCNArchetypes.interfaces import IChannel, IViral
from plone.syndication.outbound.interfaces import IFeed, IFeedItem
import logging


from plone.app.syndication.outbound.adapters.atct import ATFeedBase, ATFeedItemBase

class ContentFeed(ATFeedBase):
"""Adapter from IChannel to IFeed.
>>> from zope.interface.verify import verifyClass
>>> verifyClass(IFeed, ContentFeed)
True
"""

implements(IFeed)
adapts(IChannel, str)

def __iter__(self):
items = self.context.getContentItems()
while 1:
yield queryMultiAdapter((items.next(), self), IFeedItem)


class ViralFeedItem(ATFeedItemBase):
"""Adapter from IViral to IFeedItem.
Make sure that ViralFeedItem implements the IFeedItem
interface
>>> from zope.interface.verify import verifyClass
>>> verifyClass(IFeedItem, ViralFeedItem)
True
"""
implements(IFeedItem)
adapts(IViral, IFeed)

@property
def url(self):
return self.context.getViral_url()

@property
def body(self):
return self.context.getViral_description()


and called in with:

<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:zcml="http://namespaces.zope.org/zcml"
xmlns:five="http://namespaces.zope.org/five">

<class class="Products.VCNArchetypes.ContentChannel.ContentChannel">
<implements interface="plone.syndication.outbound.interfaces.IFeedable" />
</class>

<!-- Adapt IChannel to IFeed -->
<adapter
factory=".contentfeed.ContentFeed"
trusted="true" />
<class class=".contentfeed.ContentFeed">
<require
permission="plone.syndication.ViewFeeds"
interface="plone.syndication.outbound.interfaces.IFeed" />
</class>


<!-- Adapt IViral to IFeedItem -->
<adapter
factory=".contentfeed.ViralFeedItem"
trusted="true" />
<class class=".contentfeed.ViralFeedItem">
<require
permission="plone.syndication.ViewFeeds"
interface="plone.syndication.outbound.interfaces.IFeedItem" />
</class>

</configure>


One of the sprint tasks is creating an easy to follow, doctested, readme. Until that comes out hopefully this will help people use this brilliant addition to Plone!

Thanks derek_richardson, pbugni and everyone else who's contributed!