<?xml version="1.0" encoding="utf-8" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns="http://purl.org/rss/1.0/">




    



<channel rdf:about="http://noandwhere.com/archive/weblog/RSS">
  <title>Weblog</title>
  <link>http://noandwhere.com</link>

  <description>
    
      
    
  </description>

  

  
            <syn:updatePeriod>daily</syn:updatePeriod>
            <syn:updateFrequency>1</syn:updateFrequency>
            <syn:updateBase>2008-05-25T23:56:47Z</syn:updateBase>
        

  <image rdf:resource="http://noandwhere.com/logo.png"/>

  <items>
    <rdf:Seq>
      
        <rdf:li rdf:resource="http://noandwhere.com/archive/archive-your-gmail-inbox-from-python"/>
      
      
        <rdf:li rdf:resource="http://noandwhere.com/archive/microblogs-status-update-services-listen-up"/>
      
      
        <rdf:li rdf:resource="http://noandwhere.com/archive/scrawld"/>
      
      
        <rdf:li rdf:resource="http://noandwhere.com/archive/finally-on-plone-3"/>
      
      
        <rdf:li rdf:resource="http://noandwhere.com/archive/closing-tabs-in-safari-with-applescript"/>
      
      
        <rdf:li rdf:resource="http://noandwhere.com/archive/adding-safe-mime-types-to-epiphany"/>
      
      
        <rdf:li rdf:resource="http://noandwhere.com/archive/close-other-tabs-extension-for-epiphany"/>
      
      
        <rdf:li rdf:resource="http://noandwhere.com/archive/r-i-p-smartportlets"/>
      
      
        <rdf:li rdf:resource="http://noandwhere.com/archive/sorry-about-the-mess"/>
      
      
        <rdf:li rdf:resource="http://noandwhere.com/archive/banner-ad-products-for-plone"/>
      
    </rdf:Seq>
  </items>

</channel>


  <item rdf:about="http://noandwhere.com/archive/archive-your-gmail-inbox-from-python">
    <title>Archive your Gmail inbox from Python</title>
    <link>http://noandwhere.com/archive/archive-your-gmail-inbox-from-python</link>
    <description>A quickie Python script to clean out your Gmail inbox... I run this whenever my Gmail notifier has notified me of a bunch of mail that I don't really need to read.</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<pre>import imaplib

gmail_user = 'your_username'
gmail_pass = 'your_password'

M = imaplib.IMAP4_SSL('imap.gmail.com')

M.login(gmail_user, gmail_pass)

M.select()

typ, data = M.search(None, 'ALL')

for num in data[0].split():
    M.store(num, '+FLAGS', '\\Seen')
    M.store(num, '+FLAGS', '\\Deleted')

M.expunge()</pre>
<p>A couple of points:</p>
<ul>
<li>When I mention 'archive' in the title, I mean the Gmail 'Archive' feature - ie, remove the message from the inbox but keep it in 'All Mail'.</li>
<li>You need to have IMAP enabled on your Gmail account.</li>
<li>Don't let that '\\Deleted' stuff scare you - in Gmail's IMAP implementation, that removes the message from the inbox, but it doesn't actually delete it.</li>
</ul>
<p class="discreet">(... he said, ignoring the fact that he hadn't posted anything here in the past seven months.)</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Sean Fulmer</dc:creator>
    <dc:rights></dc:rights>
    <dc:date>2009-03-29T01:15:00Z</dc:date>
    <dc:type>Blog Entry</dc:type>
  </item>


  <item rdf:about="http://noandwhere.com/archive/microblogs-status-update-services-listen-up">
    <title>Microblogs, status update services... please listen up</title>
    <link>http://noandwhere.com/archive/microblogs-status-update-services-listen-up</link>
    <description>You guys all provide services that are easy-to-use, fun, and even occasionally useful. It's time to start working together.</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>I recently signed up with <a class="reference external" href="http://rejaw.com">Rejaw</a>, thus bringing the total number of
micro-blogging/status-updating services I use up to something like seven.
For the most part, I update them all simultaneously via <a class="reference external" href="http://ping.fm">Ping.FM</a> - but
Rejaw is brand new, so I had to whip together a <a class="reference external" href="/projects/web-two-point-oh-beta/ping-rejaw.py/view">quick script to allow me to
update Rejaw from Ping.FM</a> along with everything else. It's great that all
of these services have APIs and tools that allow me to do stuff like that,
but I wish it wasn't necessary.</p>
<p>All of these services have a very similar feature set:</p>
<ul class="simple">
<li>A means to post a short entry, usually a textarea and a button</li>
<li>A means to reply to an entry, again just a textarea and a button</li>
<li>A list of entries and replies</li>
<li>A means to &quot;follow&quot; other users, eg subscribe to their entries</li>
</ul>
<p>I think that about covers the basics. Now, if you look around at <a class="reference external" href="http://twitter.com">Twitter</a>,
<a class="reference external" href="http://pownce.com">Pownce</a>, <a class="reference external" href="http://plurk.com">Plurk</a>, <a class="reference external" href="http://rejaw.com">Rejaw</a> etc, you might wonder why the textarea, button, and
list provided by any one of these services is any more compelling than the
same features on the other services. The answer is - it isn't.</p>
<p><a class="reference external" href="http://ping.fm">Ping.FM</a> addresses the box+button aspect of this by allowing you to update
all of your services from a single location, and you can use RSS to
aggregate timelines from the services in a single location, but you still
need to jump around from one service to another to properly manage replies
and subscriptions.</p>
<p>So - to the point... all of you microstatusblogamathings need to get
together and come up with a way to do the following:</p>
<ul class="simple">
<li>Use some other service as a source for updates, and allow your service
to be used in the same way. The textarea+button on
your site is no better than the one on the other guy's site, so why should
I be forced to use yours? Having my content on your site is what should
matter to you - it shouldn't matter how it gets there. If you come up
with some awesomely compelling feature that makes your textarea better
than the others, fine... but have some basic standard that all of you
guys can use to work together.</li>
<li>Follow and reply to others, regardless of the service they choose as
their &quot;home&quot; service, for the same reasons. Having this cross-site
conversation visible on your site makes <em>your</em> site better, and it makes
<em>my</em> life easier.</li>
</ul>
<p>Now, do I think any of this will actually happen? Of course not. People
have been making the same argument for interoperability in the context of instant messaging services for over a decade,
and it still hasn't happened. But these new services are being built by a
new generation of developers, so maybe they're a bit more open to this sort
of suggestion than the giant corporations who control the IM services.
Maybe it could happen.</p>
]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Sean Fulmer</dc:creator>
    <dc:rights></dc:rights>
    <dc:date>2008-08-10T00:45:00Z</dc:date>
    <dc:type>Blog Entry</dc:type>
  </item>


  <item rdf:about="http://noandwhere.com/archive/scrawld">
    <title>Scrawld</title>
    <link>http://noandwhere.com/archive/scrawld</link>
    <description>How I migrated my old blog entries over to Scrawl, a lightweight blogging solution for Plone</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>I've been doing the &quot;news-items-as-blog&quot; thing in Plone here for a while. It fits well in a plain-vanilla Plone environment, but the presentation never felt very &quot;bloggy&quot; to me. I wanted to try something new, but I didn't want to stray too far from the &quot;pure Plone&quot; approach to blogging, so when I noticed <a class="reference external" href="http://plone.org/products/scrawl">Scrawl</a> in the Plone products index, I thought I'd give it a try.</p>
<p>Installation of Scrawl was straightforward, and after creating a few test entries with it, I was ready to migrate my news items over to Scrawl's &quot;blog entry&quot; content type. This was pretty easy, since Scrawl simply repurposes the News Item content type. First, I re-named the folder that contained my existing news items. Then, I created a new folder with the same ID as the old folder.  Finally, I ran the following script (from my custom skin folder) to create Blog Entries with the same content and ID's as my old News Items:</p>
<pre class="literal-block">
from Products.CMFCore.utils import getToolByName

# get the catalog &amp; workflow tools
pc = getToolByName(context, &quot;portal_catalog&quot;)
wf = getToolByName(context, &quot;portal_workflow&quot;)

# folder where the new Scrawl items will go
# change this for your own needs
nblog = context.nowhere.archive

# get News Items and create Blog Entries
entries = [e.getObject() for e in
            pc.searchResults(portal_type=&quot;News Item&quot;)]
for e in entries:

    # get info from the old object
    nid = e.id
    nkws = e.Subject()
    cdate = e.CreationDate()
    edate = e.getEffectiveDate()
    mdate = e.ModificationDate()
    ntitle = e.Title()
    ndescr = e.Description()
    ntext =  e.getText()
    ntype = e.Schema()['text'].getContentType(e)

    # create the new object
    nblog.invokeFactory(type_name = &quot;Blog Entry&quot;, id=nid)
    item = nblog[nid]
    item.editMetadata(subject=nkws)
    item.setFormat(ntype)
    item.update(title=ntitle,
                text=ntext,
                description=ndescr,
                creation_date=cdate,
                effective_date=edate,
                )

    # my items are initially private, so two steps to publish
    wf.doActionFor(item, &quot;show&quot;)
    wf.doActionFor(item, &quot;publish&quot;)

    # set the dates on the new object to match the old object
    item.setCreationDate(cdate)
    item.setEffectiveDate(edate)
    item.setModificationDate(mdate)
    item.indexObject()
    print &quot;created &quot;+ nid

return printed
</pre>
<p>After running that, I had published blog entries that were copies of my old new items, with the same id's and in the same location as the old items, completely migrated with old URLs intact.</p>
<p>Feel free to copy and modify that script for your own needs - it's a simple example of how to migrate one content type over to another.</p>
<p>Edit: It just occurred to me that my script up there does not migrate comments. I only had a couple of comments on my old entries, so it's not a big deal for me, but it might be for you.</p>
]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Sean Fulmer</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>howto</dc:subject>
    
    
      <dc:subject>plone</dc:subject>
    
    <dc:date>2008-05-26T02:25:00Z</dc:date>
    <dc:type>Blog Entry</dc:type>
  </item>


  <item rdf:about="http://noandwhere.com/archive/finally-on-plone-3">
    <title>Finally on Plone 3!</title>
    <link>http://noandwhere.com/archive/finally-on-plone-3</link>
    <description>now all I need is something to blog about :/</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Migrated this site to Plone 3 this evening, after many months of putting it off. the only thing that bit me was CacheFu, but that was easily solved by, y'know, <em>installing</em> it.</p>
<p>Not too crazy about this NuPlone theme, but it'll have to do for now.. stay tuned :)</p>
]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Sean Fulmer</dc:creator>
    <dc:rights></dc:rights>
    <dc:date>2008-05-02T04:56:33Z</dc:date>
    <dc:type>Blog Entry</dc:type>
  </item>


  <item rdf:about="http://noandwhere.com/archive/closing-tabs-in-safari-with-applescript">
    <title>Closing Tabs in Safari with AppleScript</title>
    <link>http://noandwhere.com/archive/closing-tabs-in-safari-with-applescript</link>
    <description>More adventures in browser tab manipulation</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>A lot of stuff has happened in the past couple of months, mostly because of the fact that I got a new job. This is the first time in the last three years that I've had a steady income - and it feels great. I had no idea how much stress I was putting on myself as a freelancer!</p>
<p>Anyway - the point: steady income =&gt; more money =&gt; shiny new iMac =&gt; I'm no longer using <a class="reference" href="http://www.gnome.org/projects/epiphany/">Epiphany</a> as my main browser, so I needed to cook up a way to quickly close a bunch of tabs in Safari. Safari already has a way to close all tabs except the current tab, so we just need a way to close tabs to the left or to the right of the current tab. <a class="reference" href="http://www.apple.com/applescript/">AppleScript</a> to the rescue!</p>
<p>First, the left tabs:</p>
<pre class="literal-block">
tell application &quot;Safari&quot;
    set cWindow to first item of windows
    set ctIndex to index of current tab of cWindow
    repeat ctIndex - 1 times
            close first item of tabs of cWindow
    end repeat
end tell
open location &quot;x-launchbar:hide&quot;
</pre>
<p>Then, the right:</p>
<pre class="literal-block">
tell application &quot;Safari&quot;
    set cWindow to first item of windows
    set ctIndex to index of current tab of cWindow
    repeat while (count of tabs of cWindow) &gt; ctIndex
            close last item of tabs of cWindow
    end repeat
end tell
open location &quot;x-launchbar:hide&quot;
</pre>
<p>I save those as &quot;Close Left Tabs&quot; and &quot;Close Right Tabs&quot; in ~/Library/Scripts. When I need to use them, I just bang a couple of keys to bring up the very-excellent <a class="reference" href="http://www.obdev.at/products/launchbar/index.html">LaunchBar</a> <a class="footnote-reference" href="#id2" id="id1" name="id1">[1]</a>, then 'CL' or 'CR' to run whichever one I need.</p>
<p>So, this is great for me and Safari, but it doesn't bode well for the <a class="reference" href="http://noandwhere.com/archive/close-other-tabs-extension-for-epiphany/">similar work I did for Epiphany</a>. There's a problem with that one, I think related to the disconnecting of GTK signals. The symptom is that if you're using that extension, Epiphany won't cleanly exit after you've closed all of its windows. And the real problem is that since I'm not in GNOME most of the time these days, I'm really not feeling an urgent need to fix it, which sort of sucks if you happen to be using this extension with Epiphany.</p>
<p>So, if you're one of those two people... feel free to hack on it ;)</p>
<table class="docutils footnote" frame="void" id="id2" rules="none">

<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1" name="id2">[1]</a></td><td>Hence the &quot;x-launchbar:hide&quot; bit at the end of each script - feel free to omit those :)</td></tr>
</tbody>
</table>
]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Sean Fulmer</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>development</dc:subject>
    
    
      <dc:subject>epiphany</dc:subject>
    
    
      <dc:subject>applescript</dc:subject>
    
    
      <dc:subject>safari</dc:subject>
    
    
      <dc:subject>add-ons</dc:subject>
    
    <dc:date>2008-04-11T04:03:31Z</dc:date>
    <dc:type>Blog Entry</dc:type>
  </item>


  <item rdf:about="http://noandwhere.com/archive/adding-safe-mime-types-to-epiphany">
    <title>Adding safe MIME types to Epiphany</title>
    <link>http://noandwhere.com/archive/adding-safe-mime-types-to-epiphany</link>
    <description>or, how GNOME's over-zealous hand-holding nearly ruined a moment of joy</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>I was pretty excited when I found out that <a href="http://www.amazon.com/gp/dmusic/help/amd.html?ie=UTF8&forceos=LINUX&ASIN=&isTrack=">Amazon's MP3 downloader is finally available for Linux</a>. I get most of my music from <a href="http://www.emusic.com">eMusic</a>, but it's nice to have options :)</p>
<p>I downloaded the deb package, installed it, bought an album, and was immediately presented with a fun dialog similar to this:</p>
<br />
<p><img src="images/epiphany_unsafe_filetype_dialog.png" alt="Epiphany unsafe file type dialog" /></p>
<p>JOY. What could have been a seamless, 1-click music purchase was changed into a clumsy series of download/locate/click steps. I can't really blame Amazon for this - it's Epiphany making the safest decision when presented a brand new MIME type, which isn't such a bad thing in and of itself.</p>
<p> (However, GNOME will, without a peep,  happily allow me to unleash this file's document-damaging, privacy-invading wrath once I've downloaded it.)</p>
<p>What <i>is</i> a bad thing is that there's no UI in Epiphany to let me decide what's safe and what isn't. Isn't setting up helper apps for file types a pretty common thing? You can't even fix this as a regular user - <b>to add a new safe MIME type to Epiphany, you have to add it to the "safe" section in /etc/gnome/epiphany/mime-types-permissions.xml</b>, which of course requires you to be root.</p>
<p>(In this case, the MIME type for Amazon's AMZ files is<i> &lt;mime-type type="audio/x-amzxml"/&gt;</i>)</p>
<p>GNOME is my desktop environment of choice, and I admire the GNOME project's goal of simplicity, but forcing a user to muck around with XML inside of a system configuration file seems to be contrary to that goal. When you dumb things down to the point where you're removing the means to change common settings, you're going a bit too far. <br /></p>
<p>Like I said, it's nice to have options. :)<br /></p>
]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Sean Fulmer</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>epiphany</dc:subject>
    
    
      <dc:subject>gnome</dc:subject>
    
    <dc:date>2008-03-03T03:15:00Z</dc:date>
    <dc:type>Blog Entry</dc:type>
  </item>


  <item rdf:about="http://noandwhere.com/archive/close-other-tabs-extension-for-epiphany">
    <title>'Close Other Tabs' extension for Epiphany</title>
    <link>http://noandwhere.com/archive/close-other-tabs-extension-for-epiphany</link>
    <description>Bringing some Tab Mix Plus goodness to the GNOME web browser!</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>I recently started using <a href="http://www.gnome.org/projects/epiphany/">Epiphany</a> as my main web browser, and I found that I really missed the 'close other tabs' functionality that I had in <a href="http://www.mozilla.com/firefox">Firefox</a> with the <a href="http://tmp.garyr.net/">Tab Mix Plus</a> extension. Thankfully, I didn't have to live without that for too long - <a href="http://www.gnome.org/projects/epiphany/documentation/extensions/index.html">Epiphany is easy to extend</a>, with Python no less! After a quick read through the extension docs and a couple of glances at some existing extension code, I was able to add what I needed:</p>
<p><img src="images/cot_tab_menu.png" alt="Close Other Tabs - Main Menu" /></p><p><img src="images/cot_tab_context_menu.png" alt="Close Other Tabs - Tab context menu" /></p>
<p>If you'd like to try this out, download <a title="Close Other Tabs" href="../projects/epiphany/epiphany_close_other_tabs.tar.gz">Close Other Tabs</a>, extract it, open a terminal in the extracted directory, and run 'make install' to copy the extension to your Epiphany settings. Once youve done that, you can activate it under Tools &gt; Extensions in Epiphany. If you don't have 'make' installed, you can manually copy close_other_tabs.* into ~/.gnome2/.epiphany/extensions.<br /></p>
<p>I've still got some work to do on it, primarily on UI niceties like disabling the menu items when only one tab is open, etc. I also need to put some credits in there - the layout of the README, the Makefile, etc all begain life in a different extension. :)</p>
<p><i>(Edit: Done!)</i><br /></p>
<p>Anyway, if you try this out, please let me know what you think!</p>
<blockquote>
<p><i><b>2008-03-07 I'm not sure why, but this extension is causing Epiphany to leak memory and not exit cleanly. Something to do with disconnecting signals I think, but I'm not sure what I've done wrong. :/</b></i><br /></p>
</blockquote>
]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Sean Fulmer</dc:creator>
    <dc:rights></dc:rights>
    <dc:date>2008-02-19T06:52:03Z</dc:date>
    <dc:type>Blog Entry</dc:type>
  </item>


  <item rdf:about="http://noandwhere.com/archive/r-i-p-smartportlets">
    <title>R.I.P. SmartPortlets</title>
    <link>http://noandwhere.com/archive/r-i-p-smartportlets</link>
    <description>If you used SmartPortlets on Plone 2.x and have been wondering when the Plone 3 version would arrive... well, it won't. But it's not all bad news...</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p> <a href="http://plone.org/products/smartportlets">SmartPortlets</a> was something I crufted together last year, and people seemed to like it. Some people liked it <a href="http://theploneblog.org/blog/archive/2006/07/29/sean-fulmer-i-love-you">too much</a>. ;-)</p>
<p> I've received a few emails asking when I might push out an updated version for Plone 3, and the answer is always "when I have the time". But after reading <a href="http://martinaspeli.net/articles/portlet-sanity">Martin Aspeli's latest post about Plone 3 portlets</a>, I can change that answer to "never" and not feel bad about it...</p>
<p><blockquote>"<a href="http://dev.plone.org/plone/browser/plone.portlet.collection">plone.portlet.collection</a> allows you to point a portlet at a Smart Folder to get any type of listing. It's not 100% done yet, so it doesn't have a release, but it's nearly there."</blockquote></p>
<p>That's pretty much what SmartPortlets did, so I suppose I'm off the hook!</p>
]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Sean Fulmer</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>plone</dc:subject>
    
    
      <dc:subject>projects</dc:subject>
    
    
      <dc:subject>portlets</dc:subject>
    
    <dc:date>2007-11-10T05:51:20Z</dc:date>
    <dc:type>Blog Entry</dc:type>
  </item>


  <item rdf:about="http://noandwhere.com/archive/sorry-about-the-mess">
    <title>Sorry about the mess</title>
    <link>http://noandwhere.com/archive/sorry-about-the-mess</link>
    <description>Working towards a migration to Plone 3 - things might be screwy for a while...</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p> Today I migrated all of my old COREBlog2 entries to standard Plone news items, and set the front page to display a smart folder summary listing of those news items. All of this is to ease the hopefully-imminent migration of this site to Plone 3.</p>
<p> I don't think I'm going to stay with this particular setup for my blog... I rather like having full entries listed on the blog front page. I'll probably end up using <a href="http://plone.org/products/quills">Quills</a>, but we'll see.</p>
<p> At any rate, the dust will settle around here sooner or later.. sorry for the inconvenience!</p>
]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Sean Fulmer</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>noandwhere</dc:subject>
    
    <dc:date>2007-10-22T01:06:24Z</dc:date>
    <dc:type>Blog Entry</dc:type>
  </item>


  <item rdf:about="http://noandwhere.com/archive/banner-ad-products-for-plone">
    <title>Banner ad products for Plone</title>
    <link>http://noandwhere.com/archive/banner-ad-products-for-plone</link>
    <description>from the punch-the-monkey-and-win dept</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p> Two of my clients recently asked for
banner ad systems for their Plone sites. I took some notes on two of
the products that are currently available, and I thought they might be
worth sharing, so here goes...</p>
<p> I looked at two advertising systems for Plone:
</p><ul><li><span class="link-external"><a href="http://plone.org/products/kbannerad">KBannerAd</a></span></li><li><span class="link-external"><a href="http://plone.org/products/promoengine">PromoEngine</a></span></li></ul>
<h3> KBannerAd</h3>
<p> KBannerAd is an older product from the Plone 2.1 era, but I
have tested it with Plone 2.5 and it does work without any problems,
although there are a few UI glitches.</p>
<p> For creating ads, KBannerAd is simple to use. You create an
ad using a tool in the Site Setup area. The ad object has fields for:</p>
<ul><li>an image (can be gif, jpg, png, or flash; text ads
are not supported)</li><li>a destination URL (either
internal or external)</li><li>a rotation weight</li><li>effective
and end dates</li><li>location of the ad (ie, which portlet
or banner slot)</li><li>maximum clicks</li></ul>
<p> Ad rotation is essentially random, but weighted - if ad A has
a weight of 80 and ad B has a weight of 20, then over a few hundred
page views, ad A will have been displayed approximately 80% of the time.</p>
<p> The lifetime of an ad is determined by the effective and end
dates, and by the maximum clicks (whichever comes first). The max
clicks allows the site owner to sell ads on a cost-per-click basis
(meaning, the number of times the ad is actually clicked). The ad tool
in Site Setup shows how many times each ad has been clicked.</p>
<p> Ads are controlled by workflow, so if an ad is not in a state
accessible to the user, the ad will not be displayed.</p>
<h3>PromoEngine</h3>
<p> PromoEngine is a newer product, under active development
using the latest Plone development techniques. It is only at version
0.5.1, but I have not encountered any problems with it in my tests.</p>
<p> For creating ads, PromoEngine is a bit more complex than
KBannerAd, but with that complexity comes a bit more power in the
ability to organize and display ads. PromoEngine uses a tool in Site
Setup - you add folders under that tool to organize your ads. To each
of these folders you can add subfolders, images, and ad objects. An ad
object has the following fields:</p>
<ul><li>Reference field to associate ads with specific
content</li><li>The portlet slot (or banner location) where
the ad should be displayed</li><li>A Kupu editor to create
the ad content - basically anything you can build in Kupu can be used
for an ad, so you could have images, Flash, text, links, whatever. A
catch here is that, for example, if the site owner is building a banner
ad, they must remember to link the image to the destination URL. This
is slightly more difficult than KBannerAd, which automatically wraps
the banner ad with the destination URL.</li></ul>
<p> The reference field is a good feature - it will allow you to
run specific ads with specific content items (articles, etc).</p>
<p> PromoEngine does not have the max clicks and rotation
weighting that KBannerAd has. The life of an ad is determined strictly
by workflow and expiration date, and rotation is completely random.
Weight is a planned feature, but is not yet implemented.</p>
<h3>Common Shortcomings</h3>
<ul><li>Neither system will do per-impression rotation.</li><li>Other
than the click counts provided by KBannerAd, neither system provides
any type of statistics reporting.</li><li>Neither system
has the ability to manage the actual sale of ads </li><li>Neither
system can create a sized pop-up window when an ad is clicked (although
this might be possible with PromoEngine, with some tweaks to Kupu).</li><li>Since
both systems serve ads directly in the HTML of a page, CacheFu page
caching will prevent proper rotation of the ads.</li></ul>
<h3>Feature Comparison</h3>
<table class="listing"><tbody><tr>
<th colspan="1" align="left" valign="middle"></th><th colspan="1" align="left" valign="middle"><p>
KBannerAd </p>
</th><th colspan="1" align="left" valign="middle"><p>
PromoEngine </p>
</th></tr>
<tr><td colspan="1" align="left" valign="middle"><p>
Image Ads </p>
</td><td colspan="1" align="left" valign="middle">X
</td><td colspan="1" align="left" valign="middle">X
</td></tr>
<tr><td colspan="1" align="left" valign="middle"><p>
Flash Ads </p>
</td><td colspan="1" align="left" valign="middle">X
</td><td colspan="1" align="left" valign="middle">X
</td></tr>
<tr><td colspan="1" align="left" valign="middle"><p>
Text Ads </p>
</td><td colspan="1" align="left" valign="middle"> 
</td><td colspan="1" align="left" valign="middle">X
</td></tr>
<tr><td colspan="1" align="left" valign="middle"><p>
Custom ad slots </p>
</td><td colspan="1" align="left" valign="middle">X
</td><td colspan="1" align="left" valign="middle">X
</td></tr>
<tr><td colspan="1" align="left" valign="middle"><p>
Weighted ad rotation </p>
</td><td colspan="1" align="left" valign="middle">X
</td><td colspan="1" align="left" valign="middle"> 
</td></tr>
<tr><td colspan="1" align="left" valign="middle"><p>
Per-impression rotation </p>
</td><td colspan="1" align="left" valign="middle"> 
</td><td colspan="1" align="left" valign="middle"> 
</td></tr>
<tr><td colspan="1" align="left" valign="middle"><p>
Ad click tracking </p>
</td><td colspan="1" align="left" valign="middle">X
</td><td colspan="1" align="left" valign="middle"> 
</td></tr>
<tr><td colspan="1" align="left" valign="middle"><p>
Ad view statistics </p>
</td><td colspan="1" align="left" valign="middle"> 
</td><td colspan="1" align="left" valign="middle"> 
</td></tr>
<tr><td colspan="1" align="left" valign="middle"><p>
Ads governed by workflow </p>
</td><td colspan="1" align="left" valign="middle">X
</td><td colspan="1" align="left" valign="middle">X
</td></tr>
<tr><td colspan="1" align="left" valign="middle"><p>
Ad folders for organization </p>
</td><td colspan="1" align="left" valign="middle"> 
</td><td colspan="1" align="left" valign="middle">X
</td></tr>
<tr><td colspan="1" align="left" valign="middle"><p>
Actively developed </p>
</td><td colspan="1" align="left" valign="middle"> 
</td><td colspan="1" align="left" valign="middle">X
</td></tr>
</tbody></table><h3>Recommendation</h3>
<p> Based on all of this, both of my clients have decided to go
with PromoEngine, primarily because:</p>
<ul><li>It is a newer product, with active development.</li><li>It
allows the organization of ads into folders and subfolders in a
flexible manner - you could organize your ads (and their associated
images and other resources) by client, campaign, whatever.</li><li>Rich-text
(Kupu) creation of ads allows for more creativity in your ad design,
and allows for text-only ads.</li><li>Allows specific ads
to be associated with specific content items.</li></ul>
<h3>Stuff I'd like to see</h3><ul><li>The
simple image+URL ad types in KBannerAd are nice, would like to see
those in PromoEngine.</li><li>A wrapper around a
PromoEngine text ad, to make the whole thing clickable.</li><li>A
way to designate an ad destination as a sized pop-up window.</li><li>Full
reporting for views and click-throughs.</li></ul><p>If
work ever slows down, I'll try to find the time to contribute some of
that. But working with good open-source projects is a double-edged
sword - if you make the right connections and land some good clients,
you'll find yourself too busy to contribute back to the projects!</p>
]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Sean Fulmer</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>plone</dc:subject>
    
    <dc:date>2007-09-11T00:00:00Z</dc:date>
    <dc:type>Blog Entry</dc:type>
  </item>





</rdf:RDF>

