<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet href="" type="text/css"?>

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:dc="http://purl.org/dc/elements/1.1/"
         xmlns:dcterms="http://purl.org/dc/terms/"
         xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
         xmlns:rss="http://purl.org/rss/1.0/"
         xmlns:content="http://purl.org/rss/1.0/modules/content/">

    <rss:channel rdf:about="http://tomster.org/blog">

        <rss:title>Blog</rss:title>
        <rss:link>http://tomster.org/blog</rss:link>

        <rss:description>"I'm a geek -- with a life!" he insisted stubbornly...</rss:description>
        

        <rss:image rdf:resource="http://tomster.org/logo.png"/>

        <sy:updatePeriod>daily</sy:updatePeriod>
        <sy:updateFrequency>1</sy:updateFrequency>

        <rss:items>
            <rdf:Seq>
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2010/04/23/push-a-local-git-branch-to-remote-repository"/>
                
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2009/09/06/gitosis-and-virtualenv"/>
                
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2009/03/20/annotatable-testrequest"/>
                
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2009/01/12/git-command-aliases"/>
                
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2008/12/12/bristol-plone-performance-sprint-day-1"/>
                
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2008/10/18/windmill-for-browser-testing"/>
                
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2008/09/25/lxml-on-mac-os-x"/>
                
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2008/06/02/netboot-installing-ubuntu-on-a-sunfire-x2200"/>
                
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2008/04/26/blueprint-css-jquery"/>
                
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2008/04/18/connecting-plone-to-mac-os-x-server-with-ldap"/>
                
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2008/04/16/nginx-mod-wsgi-python2.4"/>
                
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2008/04/09/today-is-naked-css-day"/>
                
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2008/04/08/deliverance-a-la-wsgi-for-plone"/>
                
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2008/04/04/using-the-oki-c9800-on-a-mac"/>
                
                
                <rdf:li rdf:resource="http://tomster.org/blog/archive/2008/04/02/url-dependent-skinswitching-in-plone-3"/>
                
            </rdf:Seq>
        </rss:items>
    </rss:channel>

    <rss:image rdf:about="http://tomster.org/logo.png">
        <rss:title>Blog</rss:title>
        <rss:link>http://tomster.org/blog</rss:link>
        <rss:url>http://tomster.org/logo.png</rss:url>
    </rss:image>

    

    <rss:item rdf:about="http://tomster.org/blog/archive/2010/04/23/push-a-local-git-branch-to-remote-repository">

        <rss:title>Push a local git branch to remote repository</rss:title>

        <rss:link>http://tomster.org/blog/archive/2010/04/23/push-a-local-git-branch-to-remote-repository</rss:link>       

        <rss:description> Push a local branch to the remote repository and automatically make it track the new remote branch - in one step
 </rss:description>

        <content:encoded>
          <![CDATA[
          <p>So you create a local working branch and eventually decide you want to push it to the remote branch (either to share it with colleagues or with another machine, or simply to have a convenient remote backup).</p>
<p>That, of course is easy. First create a new branch:</p>
<pre class="literal-block">
# git checkout -b new_branch
Switched to a new branch 'new_branch'
</pre>
<p>Then perform some work:</p>
<pre class="literal-block">
# echo &quot;foo&quot; &gt;&gt; foo.txt
# git add foo.txt
# git commit foo.txt -m &quot;more foo&quot;
[new_branch 5ba552f] more foo
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 foo.txt
</pre>
<p>and when you're ready:</p>
<pre class="literal-block">
# git push
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 270 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To git&#64;github.com:tomster/git-svn-helpers.git
 * [new branch]      HEAD -&gt; new_branch
</pre>
<p>So far, so good. However, if you then want to pull in remote changes you get the following error:</p>
<pre class="literal-block">
# git pull
You asked me to pull without telling me which branch you
want to merge with, and 'branch.new_branch.merge' in
your configuration file does not tell me either.      Please
specify which branch you want to merge on the command line and
try again (e.g. 'git pull &lt;repository&gt; &lt;refspec&gt;').
See git-pull(1) for details.

If you often merge with the same branch, you may want to
configure the following variables in your configuration
file:

    branch.new_branch.remote = &lt;nickname&gt;
    branch.new_branch.merge = &lt;remote-ref&gt;
    remote.&lt;nickname&gt;.url = &lt;url&gt;
    remote.&lt;nickname&gt;.fetch = &lt;refspec&gt;

See git-config(1) for details.
</pre>
<p>You can either enter the <tt class="docutils literal"><span class="pre">git-config</span></tt> commands, edit <tt class="docutils literal"><span class="pre">.git/config</span></tt> manually or simply use the following shell script:</p>
<pre class="literal-block">
#!/usr/bin/env bash
function parse_git_branch {
  ref=$(git-symbolic-ref HEAD 2&gt; /dev/null) || return
  echo ${ref#refs/heads/}
}
BRANCHNAME=`parse_git_branch`
git push
git config branch.$BRANCHNAME.remote origin
git config branch.$BRANCHNAME.merge refs/heads/$BRANCHNAME
</pre>
<p>Save it as <tt class="docutils literal"><span class="pre">git-publish</span></tt> anywhere on your <tt class="docutils literal"><span class="pre">$PATH</span></tt> (don't forget to make it executable) and then all you need to do, whenever you want to push a local git branch for the first time is simply this:</p>
<pre class="literal-block">
# git publish
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 270 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To git&#64;github.com:tomster/git-svn-helpers.git
 * [new branch]      HEAD -&gt; new_branch
# git pull
Already up-to-date.
</pre>
<p><em>Update</em>: changed the shebang to <tt class="docutils literal"><span class="pre">#!/usr/bin/env</span> <span class="pre">bash</span></tt> since it really is a bash script, thanks to <a class="reference" href="http://twitter.com/HansHuebner/status/12710994844">&#64;HansHuebner</a></p>
<p><em>Update (2)</em>: As of <a class="reference" href="http://www.kernel.org/pub/software/scm/git/docs/RelNotes-1.7.0.txt">git 1.7</a> you can use <tt class="docutils literal"><span class="pre">git</span> <span class="pre">push</span> <span class="pre">--set-upstream</span></tt> to achieve the same effect.</p>

          ]]>
        </content:encoded>        

        <dc:date>2010-04-23T15:10:00+00:00</dc:date>

        <dcterms:modified>2010-08-23T06:07:59+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        

        
            <dc:subject>git</dc:subject>
        

    </rss:item>

    
    

    <rss:item rdf:about="http://tomster.org/blog/archive/2009/09/06/gitosis-and-virtualenv">

        <rss:title>gitosis and virtualenv</rss:title>

        <rss:link>http://tomster.org/blog/archive/2009/09/06/gitosis-and-virtualenv</rss:link>       

        <rss:description> Notes on setting up gitosis (on FreeBSD) using virtualenv.
 </rss:description>

        <content:encoded>
          <![CDATA[
          <p>Basically, the following is a condensed and simpler version of the excellent tutorial over at <a class="reference" href="http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way">scie.nti.st</a>, except that we don't use the system-wide site-packages. The crucial simplifications are:</p>
<blockquote>
<ul class="simple">
<li>we don't muck about with <tt class="docutils literal"><span class="pre">$PYTHONPATH</span></tt> or <tt class="docutils literal"><span class="pre">/etc/environment</span></tt> because that's evil :)</li>
<li>instead we use <tt class="docutils literal"><span class="pre">virtualenv</span></tt></li>
</ul>
</blockquote>
<p>First, install git:</p>
<pre class="literal-block">
cd /usr/ports/devel/git
sudo make install
</pre>
<p>Install python and friends:</p>
<pre class="literal-block">
cd /usr/ports/lang/python25
sudo make install
...
cd /usr/ports/devel/py-setuptools
sudo make install
...
sudo easy_install virtualenv
</pre>
<p>Add a git user:</p>
<pre class="literal-block">
sudo pw adduser -n git -m
</pre>
<p>Copy the public key:</p>
<pre class="literal-block">
cp ~/.ssh/authorized_keys /tmp/gitosis.pub
</pre>
<p>Become the git user and install gitosis using virtualenv:</p>
<pre class="literal-block">
sudo su - git
virtualenv . --no-site-packages
mkdir src
cd src/
git clone git://eagain.net/gitosis.git
cd gitosis
../../bin/python setup.py install
</pre>
<p>The only thing missing now is to <em>use absolut paths in the hook script</em> (to make it work with virtualenv). IOW, <tt class="docutils literal"><span class="pre">/home/git/repositories/gitosis-admin.git/hooks/post-update</span></tt> should look like this:</p>
<pre class="literal-block">
#!/bin/sh
set -e
/home/git/bin/gitosis-run-hook post-update
/usr/local/libexec/git-core/git-update-server-info
</pre>
<p>Make sure, the hook's executable bit is set:</p>
<pre class="literal-block">
chmod a+x /home/git/repositories/gitosis-admin.git/hooks/post-update
</pre>
<p>Voila! You can clone the <cite>gitosis-admin</cite> repository and start working with it.</p>

          ]]>
        </content:encoded>        

        <dc:date>2009-09-06T18:05:30+00:00</dc:date>

        <dcterms:modified>2009-09-06T18:05:30+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        

        
            <dc:subject>git</dc:subject>
        
        
            <dc:subject>freebsd</dc:subject>
        

    </rss:item>

    
    

    <rss:item rdf:about="http://tomster.org/blog/archive/2009/03/20/annotatable-testrequest">

        <rss:title>Annotatable TestRequest</rss:title>

        <rss:link>http://tomster.org/blog/archive/2009/03/20/annotatable-testrequest</rss:link>       

        <rss:description> How to test browser views without (the overhead of) a browser test in Zope and Plone
 </rss:description>

        <content:encoded>
          <![CDATA[
          <p>Browser tests aren't the only (and often not the best) way to test browser views. Much nicer to just instantiate the view directly, like so:
</p>
<pre><code>&gt;&gt;&gt; view = FooView(context, request)
</code></pre><p>Then just call any method of the view directly:
</p>
<pre><code>&gt;&gt;&gt; self.assertEqual(view.foo(), [])
</code></pre><p>But where to get the request? Enter <code>TestRequest</code>:
</p>
<pre><code>&gt;&gt;&gt; from zope.publisher.browser import TestRequest
&gt;&gt;&gt; request = TestRequest()
&gt;&gt;&gt; view = FooView(context, request)
&gt;&gt;&gt; self.assertEqual(view.foo(), [])
</code></pre><p>However, sometimes this can result in the following error:
</p>
<pre><code>TypeError: ('Could not adapt', &lt;zope.publisher.browser.TestRequest instance URL=http://127.0.0.1&gt;, 
    &lt;InterfaceClass zope.annotation.interfaces.IAnnotations&gt;)
</code></pre><p>In that case you additionally need to make the request object you've just created annotatable, like so:
</p>
<pre><code>&gt;&gt;&gt; from zope.publisher.browser import TestRequest
&gt;&gt;&gt; from zope.annotation.interfaces import IAttributeAnnotatable
&gt;&gt;&gt; from zope.interface import alsoProvides
&gt;&gt;&gt; request = TestRequest()
&gt;&gt;&gt; alsoProvides(request, IAttributeAnnotatable)
</code></pre>
          ]]>
        </content:encoded>        

        <dc:date>2009-03-20T13:49:30+00:00</dc:date>

        <dcterms:modified>2009-03-20T13:49:30+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        

        
            <dc:subject>zope</dc:subject>
        
        
            <dc:subject>tdd</dc:subject>
        

    </rss:item>

    
    

    <rss:item rdf:about="http://tomster.org/blog/archive/2009/01/12/git-command-aliases">

        <rss:title>Git command aliases</rss:title>

        <rss:link>http://tomster.org/blog/archive/2009/01/12/git-command-aliases</rss:link>       

        <rss:description> Not everything in svn is worse than in git!
 </rss:description>

        <content:encoded>
          <![CDATA[
          <p>One of the nice features of subversion are its built-in command aliases, i.e. instead of having to type <code>svn commit</code> you can just use <code>svn ci</code>, instead of <code>propertyedit</code> just type <code>pe</code>.
</p>
<p><code>git</code> doesn't have those, <a href="http://twitter.com/philikon/status/1111426171" title="Twitter / philiKON: git's lack of short aliase ...">which some find annoying</a>. However, you can easily remedy this by adding an <code>[alias]</code> section to your <code>~/.gitconfig</code> file. <a href="http://twitter.com/hexsprite/status/1111533837" title="Twitter / Jordan Baker: @tomlazar blog it please!  ...">Upon request</a> and because it's really a nice feature here's an example for that from my own configuration. I've copied it myself mostly from <a href="http://blog.zitc.de/" title="lower case">Andi</a>, who is as much more prolific than I as he is lazier to blog ;-)
</p>
<p>Anyway, here it goes:
</p>
<pre><code>[core]
    excludesfile = /Users/tomster/.gitignore
    pager = "/opt/local/bin/less -RciqMSj5"
    editor = mate -w

[color]
    diff = auto
    branch = auto
    status = auto

[diff]
    renames = true

[alias]
    st = status
    d = diff
    ci = commit -v
    cia = commit -v -a
    co = checkout
    cp = cherry-pick
    l = log
    ll = log -p
    lt = log trunk..
    llt = log -p trunk..
    lm = log master..
    llm = log -p master..
    b = branch
</code></pre><p>The <code>.gitignore</code> file referenced above looks like this (and should look rather familiar to svn users):
</p>
<pre><code>.svn
*.egg-info
*.pyc
.DS_Store
tmtags
</code></pre><p><strong>Update</strong>: <a href="http://twitter.com/philikon" title="Twitter / philikon">@philikon</a> found the <a href="http://git.or.cz/gitwiki/Aliases" title="Aliases - GitWiki">FM</a> :-)
</p>
          ]]>
        </content:encoded>        

        <dc:date>2009-01-12T01:10:00+00:00</dc:date>

        <dcterms:modified>2010-09-02T20:10:40+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        

        
            <dc:subject>subversion</dc:subject>
        
        
            <dc:subject>git</dc:subject>
        
        
            <dc:subject>hints</dc:subject>
        

    </rss:item>

    
    

    <rss:item rdf:about="http://tomster.org/blog/archive/2008/12/12/bristol-plone-performance-sprint-day-1">

        <rss:title>Bristol Plone Performance Sprint Day #1</rss:title>

        <rss:link>http://tomster.org/blog/archive/2008/12/12/bristol-plone-performance-sprint-day-1</rss:link>       

        <rss:description> Make Plone go faster
 </rss:description>

        <content:encoded>
          <![CDATA[
          <p>The <a href="http://tinyurl.com/6rsy7a" title="Summary - Plone Performance Sprint 2008 - OpenPlans">sprint</a> started with a brainstorming session where we collected all the ideas and areas the participants brought into three core areas. They have been tentatively named Cataloging and Indexing, Instrumentation and Benchmarking. We then proceeded to collect input on these three areas by having everybody write down whatever came to mind on post-its and we just stuck them together on the wall.
</p>
<p><a href="http://www.flickr.com/photos/15458827@N05/3101683363/" title="2008-12-12 11:32:03 +0000 by tom.lazar, on Flickr"><img src="http://farm4.static.flickr.com/3278/3101683363_7de6ed9477.jpg" width="500" height="375" alt="2008-12-12 11:32:03 +0000" /></a>
</p>
<p>After lunch we split up into three groups where all the input for each topic was processed. The group session was limited to just over an hour, as the goal was not to jump into (anf get lost in) an exhaustive discussion of all aspects and details but rather to come up with specific, actionable proposals which would then be put to the entire sprint in a short presentation, where we collectively decided on what (partially already <em>how</em>) we were going to work on for the remainder of the sprint.
</p>
<p>This approach turned out to be a really good idea for multiple reasons. For one, we collectively decided on what we would concentrate on. Nobody had to feel left out. By limiting the first session to an hour and demanding a short presentation from each group to the entire sprint, we avoid rushing into dead ends. And lastly, everybody was on the same picture from the very start.
</p>
<p>The three presentations then provided each group with further feedback and by the time they were over everybody was ready to get some actual work done.
</p>
<p>We ended day one by rewarding ourselves with a big dinner of real authentic English food (i.e. Indian curry) in an <a href="http://www.oldindia.co.uk/about.html" title="oldindia">old converted bank</a>.
   <a href="http://www.flickr.com/photos/15458827@N05/3101712521/" title="Rewarding ourselves with dinner by tom.lazar, on Flickr"><img src="http://farm4.static.flickr.com/3215/3101712521_9464fd5c63.jpg" width="375" height="500" alt="Rewarding ourselves with dinner" /></a>
</p>
          ]]>
        </content:encoded>        

        <dc:date>2008-12-12T11:25:24+00:00</dc:date>

        <dcterms:modified>2010-08-23T06:09:13+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        

        
            <dc:subject>ploneperfbristol2008</dc:subject>
        
        
            <dc:subject>plone</dc:subject>
        

    </rss:item>

    
    

    <rss:item rdf:about="http://tomster.org/blog/archive/2008/10/18/windmill-for-browser-testing">

        <rss:title>Windmill for Browser testing</rss:title>

        <rss:link>http://tomster.org/blog/archive/2008/10/18/windmill-for-browser-testing</rss:link>       

        <rss:description> A promising Chandler originated Selenium competitor
 </rss:description>

        <content:encoded>
          <![CDATA[
          <p>While cleaning up on the <a href="http://www.openplans.org/projects/plone-conference-2008-dc/remoteinclude" title="RemoteInclude - Plone Conference 2008 DC - OpenPlans">remoteinclude sprinting</a> we did last week at the post-conference sprint, I came across <a href="http://trac.getwindmill.com/wiki/AboutWindmill" title="AboutWindmill –
      windmill – Trac">Windmill</a>. Windmill looks like a really promising candidate for anyone wishing to do some non-trivial browser based testing of their web applications:
</p>
<blockquote><p>Windmill implements cross browser testing, in-browser recording and playback, and functionality for fast accurate debugging and test environment integration.
</p>
</blockquote><p>I'd be curious to know if any members of the Plone/Zope community have had any experiences with it. Also, if you've simply become curious and would like to try it out for yourself (and <em>then</em> report back) but are intimidated (or simply put off) by the <a href="http://trac.getwindmill.com/wiki/Install-Windmill" title="Install-Windmill –
      windmill – Trac">lengthy installation instruction</a>, here's a one-stop buildout including the particular python that windmill needs, that will get you going:
</p>
<pre><code>[buildout]
python = python
parts =
    python
    pythonbin
    windmill

[windmill]
recipe=zc.recipe.egg
eggs =
    simplejson==1.9.1
    windmill

[python]
recipe = zc.recipe.cmmi
url = http://www.python.org/ftp/python/2.5.2/Python-2.5.2.tgz
executable = ${buildout:directory}/parts/python/bin/python2.5
extra_options=
    --enable-unicode=ucs4
    --with-threads
    --with-readline
    MACOSX_DEPLOYMENT_TARGET=10.5 # uncomment this, if your're not on MAC OS X

[pythonbin]
recipe = plone.recipe.command
command = ln -s ${python:executable} ${buildout:bin-directory}/python
</code></pre><p><strong>Update</strong>: Martijn Peters points out, that you can use newer versions of simplejson, you just need to stick to the 1.9 branch for the time being:
</p>
<blockquote><p>"because I assume it's the 2.0.0 API change that makes them use 1.9.x on their instruction pages. It works just fine with 1.9.3 anyway, haven't tried 2.0.3 at all."
</p>
</blockquote><p>I've updated the buildout above accordingly. Also, if you already have a working python2.5 on your system (unlike yours truly who hosed his Mac OS X 10.5 python2.5 ages ago) you can reduce the buildout to this snippet: 
</p>
<pre><code>[buildout]
parts =
   windmill

[windmill]
recipe=zc.recipe.egg
eggs =
   simplejson &lt;=2.0.0dev
   windmill
</code></pre>
          ]]>
        </content:encoded>        

        <dc:date>2008-10-18T15:45:51+00:00</dc:date>

        <dcterms:modified>2008-10-20T07:40:42+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        

        
            <dc:subject>testing</dc:subject>
        
        
            <dc:subject>web development</dc:subject>
        

    </rss:item>

    
    

    <rss:item rdf:about="http://tomster.org/blog/archive/2008/09/25/lxml-on-mac-os-x">

        <rss:title>lxml on Mac OS X</rss:title>

        <rss:link>http://tomster.org/blog/archive/2008/09/25/lxml-on-mac-os-x</rss:link>       

        <rss:description> Now with even less seg-faulting!
 </rss:description>

        <content:encoded>
          <![CDATA[
          <p>For a current project I needed to include (the most excellent Python XML library) <a href="http://codespeak.net/lxml/" title="lxml homepage">lxml</a>. Getting the right version to run on Mac OS X has been notoriously difficult, though. Easy-installing it was broken (and currently is, for me, as well) and while I have found multiple how-tos, they all dealt with the problem by installing it manually from sources and patching the configure process etc. pp. That would, of course, defeat the whole purpose of using buildout in the first place.
</p>
<p>Cheeseshop to the rescue: there is a <a href="http://pypi.python.org/pypi/plone.recipe.lxml/" title="Python Package Index : plone.recipe.lxml 0.2">recipe for installing lxml</a> <em>along with the proper versions of libxml and libxslt</em>, however, its default values didn't work for me. So for the record: the following buildout snippet will get you non-segfaulting lxml on (at least) Mac OS X 10.5.x and Ubuntu linux. YMMV.
</p>
<pre><code>parts =
    [...]
    lxml

eggs =
    [...]
    lxml==2.1.2

[lxml]
recipe=plone.recipe.lxml
egg = 
    lxml==2.1.2

libxml2_url = 
    http://xmlsoft.org/sources/libxml2-2.7.1.tar.gz

libxslt_url =
    http://xmlsoft.org/sources/libxslt-1.1.24.tar.gz
</code></pre><p>p.s. this should be good news for all folks working with Deliverance. Perhaps now I could revisit that...
</p>
          ]]>
        </content:encoded>        

        <dc:date>2008-09-25T11:33:20+00:00</dc:date>

        <dcterms:modified>2008-09-25T11:33:20+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        

        
            <dc:subject>xml</dc:subject>
        
        
            <dc:subject>macintosh</dc:subject>
        
        
            <dc:subject>ubuntu</dc:subject>
        
        
            <dc:subject>linux</dc:subject>
        

    </rss:item>

    
    

    <rss:item rdf:about="http://tomster.org/blog/archive/2008/06/02/netboot-installing-ubuntu-on-a-sunfire-x2200">

        <rss:title>Netboot installing Ubuntu on a SunFire X2200</rss:title>

        <rss:link>http://tomster.org/blog/archive/2008/06/02/netboot-installing-ubuntu-on-a-sunfire-x2200</rss:link>       

        <rss:description> Because installing from CD is soooo nineties ;-)
 </rss:description>

        <content:encoded>
          <![CDATA[
          <p>After receiving my new toy at work <a href="http://twitter.com/tomlazar/statuses/823257451" title="Twitter / Tom Lazar: Ah, my new toy arrived! A S...">three days ago</a>, a <a href="http://www.sun.com/servers/x64/x2200/" title="Sun Fire X2200 M2 Server">SunFire X2200</a> with 16Gb RAM, today I finally got around to set it up.
</p>
<p>Now, while my server OS of choice is definitely FreeBSD this particular machine is going to be used as a development machine for a Plone project which will eventually be hosted at a provider who doesn't support FreeBSD but instead Ubuntu. Also, the machine came without an optical drive. So after a few fruitless attempts to boot from an USB stick, I simply stuck to what I already know and chose a TFTP based route using Mac OS X's built-in tftp server.
</p>
<p>Basically, I just followed <a href="http://tomster.org/blog/installing-freebsd-on-a-soekris-4801-using-mac-os-x-as-host" title="Installing FreeBSD on a Soekris 4801 using Mac OS X as host &amp;mdash; tomster.org">my previous how-to on how to install FreeBSD on a (headless, keyboardless) soekris machine</a>. Only, this time, I installed the dhcp server from mac ports, instead of compiling it manually:
</p>
<pre><code>sudo port install dhcp
</code></pre><p>Then I downloaded the <a href="http://www.ubuntu.com/getubuntu/download" title="Download Ubuntu | Ubuntu">Ubuntu Server ISO image</a> and mounted it.
</p>
<p>In my <code>dhcpd.conf</code> I modified the root-path and filename options thus:
</p>
<pre><code>option root-path "/Volumes/Ubuntu-Server 8./install/netboot/";
filename "pxelinux.0";
</code></pre><p>Next modified the (existing) <code>/System/Library/LaunchDaemons/tftp.plist</code> so that it looked like this:
</p>
<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" 
    "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
    &lt;key&gt;InitGroups&lt;/key&gt;
    &lt;true/&gt;
    &lt;key&gt;Label&lt;/key&gt;
    &lt;string&gt;com.apple.tftpd&lt;/string&gt;
    &lt;key&gt;ProgramArguments&lt;/key&gt;
    &lt;array&gt;
        &lt;string&gt;/usr/libexec/tftpd&lt;/string&gt;
        &lt;string&gt;-i&lt;/string&gt;
        &lt;string&gt;/Volumes/Ubuntu-Server 8./install/netboot&lt;/string&gt;
        &lt;string&gt;-u&lt;/string&gt;
        &lt;string&gt;root&lt;/string&gt;
        &lt;string&gt;-s&lt;/string&gt;
        &lt;string&gt;/Volumes/Ubuntu-Server 8./install/netboot&lt;/string&gt;
        &lt;string&gt;-l&lt;/string&gt;
    &lt;/array&gt;
    &lt;key&gt;Sockets&lt;/key&gt;
    &lt;dict&gt;
        &lt;key&gt;Listeners&lt;/key&gt;
        &lt;dict&gt;
            &lt;key&gt;SockServiceName&lt;/key&gt;
            &lt;string&gt;tftp&lt;/string&gt;
            &lt;key&gt;SockType&lt;/key&gt;
            &lt;string&gt;dgram&lt;/string&gt;
        &lt;/dict&gt;
    &lt;/dict&gt;
    &lt;key&gt;inetdCompatibility&lt;/key&gt;
    &lt;dict&gt;
        &lt;key&gt;Wait&lt;/key&gt;
        &lt;true/&gt;
    &lt;/dict&gt;
&lt;/dict&gt;
&lt;/plist&gt;
</code></pre><p>Now all I needed to do was to start both daemons...
</p>
<pre><code>sudo /opt/local/sbin/dhcpd 
sudo service tftp start
</code></pre><p>...finally fire up the machine and press <code>F12</code> at the boot prompt and Bob was my proverbial uncle.
</p>
          ]]>
        </content:encoded>        

        <dc:date>2008-06-02T18:10:00+00:00</dc:date>

        <dcterms:modified>2008-06-02T18:08:42+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        

        
            <dc:subject>ubuntu</dc:subject>
        
        
            <dc:subject>linux</dc:subject>
        

    </rss:item>

    
    

    <rss:item rdf:about="http://tomster.org/blog/archive/2008/04/26/blueprint-css-jquery">

        <rss:title>blueprint css + jquery</rss:title>

        <rss:link>http://tomster.org/blog/archive/2008/04/26/blueprint-css-jquery</rss:link>       

        

        <content:encoded>
          <![CDATA[
          <p>I'm using the <a href="http://code.google.com/p/blueprintcss/" title="blueprintcss - Google Code">blueprint CSS framework</a> for a new site that I'm working on and am rather enjoying the process (as far as that is humanly possible, given that it by definition involves working with CSS... <em>cough</em>).
</p>
<p>One of the neat features of blueprint is a compressor script that not only renders all the various CSS bits that you want according to the given column numbers and sizes for each project into one neat (and compact) CSS file, but it also lets you define <em>semantic classes and ids</em>, so you can use something like <code>class="navigation"</code> instead of <code>class="span-6 last"</code>. And on top of that, the compressor script will also generate a PNG image that conforms to the column size and padding you've selected. This proved to be really helpful in debugging the pages. Simply add the class <code>showgrid</code> to your outer most container <code>div</code> and <a href="http://files.bjorkoy.com/blueprint/tests/parts/grid.html" title="Blueprint Grid Tests">presto</a>!
</p>
<p>When demonstrating the layout to the client, though, I wanted a less obtrusive way of switching the grid on and off and I thus came up with little <a href="http://jquery.com/" title="jQuery: The Write Less, Do More, JavaScript Library">jQuery</a> script to generate a toggle switch for each page. And since jQuery will be the standard javascript library for Plone from version 3.1 onward, anyway I thought I might as well share the following snippet:
</p>
<pre><code>$(document).ready(function() {
    $("body").append("&lt;div id='debug'&gt;turn grid: &lt;a href='' id='togglegrid'&gt;" 
    + gridstate() + "&lt;/a&gt;&lt;/div&gt;";);
    $("#debug").css("position", "absolute");
    $("#debug").css("bottom", "0");
    $("#togglegrid").click(toggle_grid);
});

function toggle_grid () {
    $(".container").toggleClass("showgrid");
    $("#togglegrid").text(gridstate());
    return false;
}

function gridstate () {
    if ($(".container").hasClass("showgrid")) {
        return 'off';
    } else {
        return 'on';
    };
}
</code></pre><p>P.S. I'm not exactly a fan of the Javascript language but I do appreciate jQuery a lot and for the sanity that it partially restores when working with Javascript. The snippet above is a good example of that in my opinion. Javascript can't get any more "pythonic" than that IMHO ;-) (But please prove me wrong!)
</p>
          ]]>
        </content:encoded>        

        <dc:date>2008-04-26T17:01:13+00:00</dc:date>

        <dcterms:modified>2008-05-19T14:01:47+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        

        
            <dc:subject>jquery</dc:subject>
        
        
            <dc:subject>blueprintcss</dc:subject>
        
        
            <dc:subject>css</dc:subject>
        

    </rss:item>

    
    

    <rss:item rdf:about="http://tomster.org/blog/archive/2008/04/18/connecting-plone-to-mac-os-x-server-with-ldap">

        <rss:title>Connecting Plone to Mac OS X Server with LDAP</rss:title>

        <rss:link>http://tomster.org/blog/archive/2008/04/18/connecting-plone-to-mac-os-x-server-with-ldap</rss:link>       

        <rss:description> A step-by-step how-to for connecting a Plone 3.x instance with a Mac OS X 10.5.x Server's OpenDirectory service
 </rss:description>

        <content:encoded>
          <![CDATA[
          <p>The idea is, of course, that all (or just some) of your OS X Server users can authenticate against a Plone instance using the same credentials that they use to access all the other services (usually filesharing).
</p>

<h1>Requirements</h1>
<p>I'm assuming a buildout based setup, so you will need to add the following bits to your <code>buildout.cfg</code>:
</p>
<pre><code>[buildout]
parts =
    ...
    productdistros
    openldap
...
[openldap]
recipe = zc.recipe.cmmi
url = http://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-2.3.27.tgz 
extra_options= --disable-slapd --disable-backends
...
[productdistros]
recipe = plone.recipe.distros
urls =
    ...
    http://plone.org/products/ploneldap/releases/1.0/PloneLDAP-bundle-1.0.tar.gz

nested-packages =
    ...
    PloneLDAP-bundle-1.0.tar.gz
</code></pre><p>You will also need <a href="http://python-ldap.sourceforge.net/" title="python-ldap: LDAP client API for Python">python-ldap</a>, for which even <a href="http://svn.kmrc.de/download/distribution" title="Index of /download/distribution">some eggs exist</a>, however, I found that they didn't work on my test server (Ubuntu, 64bit) as they seem to have some <code>.so</code> files that assume a 32bit architecture (just a wild guess on my part), so instead I just installed it via <code>apt-get</code> (Ubuntu really has good support for Python2.4 based packages btw, no wonder it's so popular among Zopistas and Plonistas!)
</p>
<pre><code>sudo apt-get install python2.4-ldap
</code></pre><p>Now you can run <code>./bin/buildout</code> and restart your instance.
</p>

<h1>Adding the plug-in</h1>
<p>In the ZMI, navigate to your Plone instance's <code>acl_users</code> and add a <code>Plone LDAP Plugin</code> from the upper right hand select box. Obviously, filling out the following form with exactly the right values is the trickiest bit of the entire operation, so I've tried to make the example values as self-evident as possible. They all assume that the FQDN of your Mac OS X server is <code>my.ldap.server.tld</code>, so it should be a no-brainer to substitute all values according to your own setup.
</p>
<ul>
 <li>
     Set all three mappings (for Login Name Attribute, User ID Attribute and RDN Attribute) to <code>UID (uid)</code>.
 </li>

 <li>
     <code>Users Base DN</code> to <code>cn=users,dc=my,dc=ldap,dc=server,dc=tld</code>
 </li>

 <li>
     <code>Groups Base DN</code> to <code>cn=groups,dc=my,dc=ldap,dc=server,dc=tld</code>
 </li>

 <li>
     <code>Manager DN</code> to <code>uid=diradmin,cn=users,dc=my,dc=ldap,dc=server,dc=tld</code>. You will obviously need to substitute <code>diradmin</code> for the id you chose when setting up the OpenDirectory server. Hint: it's the same id you use to log into the Workgroup Manager ;-)
 </li>

 <li>
     I have switched off encryption and SSL in my tests, so no guarantees that it will work <em>with</em> encryption (my Plone instance is running inside a VMware Fusion instance on the OS X Server itself, so I didn't see any need to bother with encryption, for a change)
 </li>
</ul>

<h1>Configuring the plug-in</h1>
<p>Now you need to click on the newly created plugin at <code>/plone/acl_users/ldap</code> and activate <em>all</em> functionalities.
</p>
<p>Still at <code>/plone/acl_users/ldap</code> click on <code>Properties</code> and <code>User_Management</code> and move the ldap plug-in to the top in both forms.
</p>
<p>Finally, navigate to <code>/plone/acl_users/ldap/acl_users</code> and change the value for <code>User object classes</code> to <code>posixAccount</code>.
</p>
<p>You now should be able to log into the Plone site using the credentials of a OS X Server user.
</p>
          ]]>
        </content:encoded>        

        <dc:date>2008-04-18T19:38:43+00:00</dc:date>

        <dcterms:modified>2008-05-16T21:06:26+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        

        
            <dc:subject>ldap</dc:subject>
        
        
            <dc:subject>macintosh</dc:subject>
        
        
            <dc:subject>plone</dc:subject>
        
        
            <dc:subject>ubuntu</dc:subject>
        
        
            <dc:subject>hints</dc:subject>
        

    </rss:item>

    
    

    <rss:item rdf:about="http://tomster.org/blog/archive/2008/04/16/nginx-mod-wsgi-python2.4">

        <rss:title>nginx + mod_wsgi + python2.4</rss:title>

        <rss:link>http://tomster.org/blog/archive/2008/04/16/nginx-mod-wsgi-python2.4</rss:link>       

        <rss:description> A step-by-step how-to for installing nginx with mod_wsgi for Python 2.4 on Ubuntu-7.10 Server and Mac OS X 10.5.2 Client
 </rss:description>

        <content:encoded>
          <![CDATA[
          <p>Currently I'm having lots of fun experimenting with WSGI, <a href="http://blog.repoze.org/" title="Repoze Notes : /">repoze</a> and Deliverance. But while it's nice to know that it works in a development setup (i.e. deployed with paster) I needed to be sure it would work well in a production environment. And while there are already instructions floating around on how to deploy it with Apache and mod_wsgi, I wanted to know whether I could deploy WSGI-based sites using my trusted workhorse <a href="http://wiki.codemongers.com/Main" title="Main - Nginx Wiki">nginx</a>.
</p>
<p>Since nginx is much more monolithic than Apache (which is one reason why it can be so noticably more efficient than Apache in certain situations) you can't just drop in a plugin or module. Instead, you must compile nginx from sources and add the module <em>at compile time</em>.
</p>
<p>The projects I'm working on will be deployed on Ubuntu and FreeBSD, but of course I will want to be able to test the same setup on my OS X development machine. So I've begun my tests with Ubuntu and OS X. Since nginx is available in all three systems' packaging system, my strategy is to install nginx via its respective package (which will integrate it nicely with start- and shutdown scripts) and simply replace the nginx binary with a self-compiled version that includes mod_wsgi.
</p>
<p>So, here it goes: download and expand the sources for nginx (currently 0.5.35) and mod_wsgi (currently version 0.0.6):
</p>
<pre><code>wget http://sysoev.ru/nginx/nginx-0.5.35.tar.gz
wget http://hg.mperillo.ath.cx/nginx/mod_wsgi/archive/0.0.6.tar.gz
tar xzf nginx-0.5.35.tar.gz
tar xzf 0.0.6.tar.gz
</code></pre><p>*By the way, it seems to be a feature of mercurial unknown to the author of <code>mod_wsgi</code> Manlio Perillo to provide <code>.tgz</code> archives not only for the <code>tip</code> but also for each <code>tag</code>. Currently the <code>tip</code> of <code>mod_wsgi</code> doesn't compile on Mac OS X so I'm sticking with version 0.0.6 which has proven to be stable and contains the config fixes for Mac OS X.*
</p>
<p>For both Ubuntu and Mac OS X we will need to explicitly tell the mod_wsgi plugin to use Python 2.4 rather than the default 2.5 version that comes with both systems, since I'm intending to run Zope based applications:
</p>
<pre><code>$EDITOR mod_wsgi-0.0.6/config
</code></pre><p>Change the second line of the file to:
</p>
<pre><code>PYTHON='python2.4'
</code></pre>
<h2>Ubuntu</h2>
<p>On Ubuntu you will need to install the following packages:
</p>
<pre><code>sudo apt-get install gcc
sudo apt-get install python2.4-dev
sudo apt-get install libxslt-dev
sudo apt-get install libssl-dev
sudo apt-get install libpcre3-dev
</code></pre><p>To take advantage of the start- and stop mechanisms provided by the official nginx package, let's first install that:
</p>
<pre><code>sudo apt-get install nginx
</code></pre><p>Now we can change into the nginx source directory and configure the build process to replace the packaged version of nginx with one that includes <code>mod_wsgi</code> like so:
</p>
<pre><code>cd nginx-0.5.35
./configure --add-module=../mod_wsgi-0.0.6/ --prefix=/usr/local --sbin-path=/usr/sbin \
    --conf-path=/etc/nginx/nginx.conf --with-http_ssl_module
</code></pre><p>You should receive a summary that looks like this:
</p>
<pre><code>Configuration summary
  + threads are not used
  + using system PCRE library
  + using system OpenSSL library
  + md5 library is not used
  + sha1 library is not used
  + using system zlib library

  nginx path prefix: "/usr/local"
  nginx binary file: "/usr/sbin"
  nginx configuration file: "/etc/nginx/nginx.conf"
  nginx pid file: "/usr/local/logs/nginx.pid"
  nginx error log file: "/usr/local/logs/error.log"
  nginx http access log file: "/usr/local/logs/access.log"
  nginx http client request body temporary files: "/usr/local/client_body_temp"
  nginx http proxy temporary files: "/usr/local/proxy_temp"
  nginx http fastcgi temporary files: "/usr/local/fastcgi_temp"
</code></pre><p>Make sure, the packaged instance of nginx is not running (we won't be able to replace it, otherwise):
</p>
<pre><code>sudo /etc/init.d/nginx stop
</code></pre><p>Now you can do the usual <code>make ; sudo make install</code> dance.
</p>
<p>Before starting up the instance, we still need to run <code>setup.py</code> from the <code>mod_wsgi</code> folder:
</p>
<pre><code>cd ../mod_wsgi-0.0.6/
sudo python2.4 setup.py --prefix=/usr/local/ --sbin-path=/usr/sbin/ --conf-path=/etc/nginx/
</code></pre><p>Now you can start up your instance:
</p>
<pre><code>sudo /etc/init.d/nginx start
</code></pre>
<h2>Mac OS X</h2>
<p>On Mac OS X you will need to have the Developer Tools and MacPorts installed and the install the following in addition:
</p>
<pre><code>sudo port install python2.4
sudo port install libxslt # has libxml2 as auto-dependency
sudo port install py-libxml2
sudo port install nginx
</code></pre><p>For the configure process to find the 2.4 python libraries I found I needed to copy them to <code>/opt/local/lib</code>, as otherwise nginx would load the libraries of the system's 2.5 version at startup time which would throw <code>mod_wsgi</code> off track.
</p>
<pre><code>cp /opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/libpython2.4.dylib /opt/local/lib/
</code></pre><p>Now we can configure it to match the nginx version from the ports collection like so:
</p>
<pre><code>./configure --add-module=../mod_wsgi-0.0.6/ --prefix=/opt/local --conf-path=etc/nginx/nginx.conf --sbin-path=sbin/ --with-http_ssl_module
</code></pre><p>Again, here's the summary output you should expect:
</p>
<pre><code>Configuration summary
  + threads are not used
  + using system PCRE library
  + using system OpenSSL library
  + md5 library is not used
  + sha1 library is not used
  + using system zlib library

  nginx path prefix: "/opt/local"
  nginx binary file: "/opt/local/sbin/"
  nginx configuration file: "/opt/local/etc/nginx/nginx.conf"
  nginx pid file: "/opt/local/logs/nginx.pid"
  nginx error log file: "/opt/local/logs/error.log"
  nginx http access log file: "/opt/local/logs/access.log"
  nginx http client request body temporary files: "/opt/local/client_body_temp"
  nginx http proxy temporary files: "/opt/local/proxy_temp"
  nginx http fastcgi temporary files: "/opt/local/fastcgi_temp"
</code></pre><p>Now you can do the usual <code>make ; sudo make install</code> dance. 
</p>
<p>Before starting up the instance, we still need to run <code>setup.py</code> from the <code>mod_wsgi</code> folder:
</p>
<pre><code>cd ../mod_wsgi-0.0.6/
sudo python2.4 setup.py --prefix=/opt/local/ --sbin-path=/opt/local/sbin/ --conf-path=/opt/local/etc/nginx/
</code></pre><p>Now we're finally ready to fire up our new instance. While testing and developing I can't be bothered to use <code>launchctl</code> so I chose a more pedestrian approach:
</p>
<pre><code>sudo killall nginx ; sudo /opt/local/sbin/nginx
</code></pre><p>Now you can take a look at the sample <code>nginx.conf</code> file provided in the <code>examples</code> directory of mod_wsgi to take the provided WSGI demos for a spin and, of course, to serve as a starting point to get your own apps running. Next I'll be looking at getting <code>repoze.plone</code> and <code>repoze.grok</code> running behind nginx+mod_wsgi, so stay tuned.
</p>
          ]]>
        </content:encoded>        

        <dc:date>2008-04-16T12:28:22+00:00</dc:date>

        <dcterms:modified>2008-07-04T13:31:43+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        

        
            <dc:subject>wsgi</dc:subject>
        
        
            <dc:subject>repoze</dc:subject>
        
        
            <dc:subject>python</dc:subject>
        
        
            <dc:subject>ubuntu</dc:subject>
        
        
            <dc:subject>nginx</dc:subject>
        
        
            <dc:subject>linux</dc:subject>
        
        
            <dc:subject>hints</dc:subject>
        

    </rss:item>

    
    

    <rss:item rdf:about="http://tomster.org/blog/archive/2008/04/09/today-is-naked-css-day">

        <rss:title>Today is Naked CSS Day</rss:title>

        <rss:link>http://tomster.org/blog/archive/2008/04/09/today-is-naked-css-day</rss:link>       

        <rss:description> Git nekkid!
 </rss:description>

        <content:encoded>
          <![CDATA[
          <p>Out of a whim I decided to join today's <a href="http://naked.dustindiaz.com/" title="CSS Naked Day">CSS Naked Day</a>. After all, as a Plone Site there is no need to be ashamed :-)
</p>
          ]]>
        </content:encoded>        

        <dc:date>2008-04-09T15:27:03+00:00</dc:date>

        <dcterms:modified>2008-04-09T15:27:03+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        


    </rss:item>

    
    

    <rss:item rdf:about="http://tomster.org/blog/archive/2008/04/08/deliverance-a-la-wsgi-for-plone">

        <rss:title>Deliverance á la WSGI for Plone</rss:title>

        <rss:link>http://tomster.org/blog/archive/2008/04/08/deliverance-a-la-wsgi-for-plone</rss:link>       

        <rss:description> Exciting times to be a Plone developer...
 </rss:description>

        <content:encoded>
          <![CDATA[
          <p><a href="http://www.openplans.org/projects/deliverance/project-home" title="Deliverance - deliverance">Deliverance</a> is the New Kid on the Block[tm] in the Plone world. I find the whole concept very intriguing and have decided to give it a try on both of my current new projects. (No risk, no fun, eh!?)
</p>
<p>One of the two projects is smaller in scope where I am both the Zope/Plone developer <em>and</em> the HTML/CSS handyman and the other a larger affair together with another Zopista and an external web agency with up to five more people, none of which is experienced with - or much interested in - Plone, so I am curious, how Deliverance will hold up in these two quite different scenarios.
</p>
<p>Now, if you just want to dip your toes into the proverbial water, I suggest you check out <a href="http://pypi.python.org/pypi/plone.recipe.deliverance" title="Python Package Index : plone.recipe.deliverance 1.0rc1">Martin Aspeli's Deliverance recipe</a> (does that man ever sleep?) However, Martin's recipe, along with any other tutorial that I found floating about, uses deliverance in its so-called <a href="http://www.openplans.org/projects/deliverance/using-the-proxy" title="Using the proxy - deliverance">proxy mode</a> where a second daemon is fired up that mediates between the web- and application server. This is not optimal, of course, as it pretty much defeats the whole point of the <a href="http://www.python.org/dev/peps/pep-0333/" title="PEP 333 -- Python Web Server Gateway Interface v1.0">WSGI</a> concept, so I set out to create a setup, where Plone would be themed by Deliverance configured as a WSGI middleware. Forthwith my notes:
</p>
<p>I conducted my test on Mac OS X 10.5.2 with Python 2.4.5 installed via Macports. I didn't use <code>virtualenv</code> (although I should have) but had to make sure throughout the whole process, that python2.4 was used (as opposed to Leopard's default 2.5.1). To do that, I installed easy_install and setuptools explicitly for 2.4:
</p>
<pre><code>wget http://peak.telecommunity.com/dist/ez_setup.py
sudo python2.4 ez_setup.py
sudo python ez_setup.py -U setuptools
</code></pre><p>Before dealing with Deliverance I set up a WSGI enabled Plone instance. The <a href="http://svn.repoze.org/buildouts/repoze.plone/trunk" title="Revision 886: /buildouts/repoze.plone/trunk">buildout provided by repoze.plone</a> proved to be the best candidate to do so (believe me!)
</p>
<pre><code>svn co http://svn.repoze.org/buildouts/repoze.plone/trunk repoze.plone
cd repoze.plone
python2.4 bootstrap.py
./bin/buildout
</code></pre><p>I then fired up the new instance as per instructions:
</p>
<pre><code>./bin/supervisord
./bin/addzope2user admin admin
</code></pre><p>I then could add a Plone instance <code>foo</code> at <code>localhost:8080</code> just as always. I then stopped the zope instance so:
</p>
<pre><code>./bin/supervisorctl stop zope
</code></pre><p>and then restarted it using <code>paster</code>:
</p>
<pre><code>./bin/paster serve etc/zope2.ini
</code></pre><p>and sure enough, <code>localhost:8080/foo</code> was still there!
</p>
<p>Now the only thing missing was Deliverance itself. To make it available for the instance, I simply easy_installed it into my system (this is the part, where next time I'll use <code>virtualenv</code>!):
</p>
<pre><code>sudo easy_install-2.4 Deliverance
</code></pre><p>This enabled me to add the following snippet to <code>etc/zope2.ini</code>:
</p>
<pre><code>[filter:deliverance]
paste.filter_app_factory = deliverance.wsgimiddleware:make_filter
theme_uri = file:///%(here)s/layout.html
rule_uri = file:///%(here)s/rules.xml
</code></pre><p>To use the deliverance as a filter in the WSGI stack I just had to add it somewhere. I chose to add it just after zope2 itself, so that my pipeline section looked like so:
</p>
<pre><code>[pipeline:main]
pipeline = egg:Paste#cgitb
           egg:Paste#httpexceptions
           egg:repoze.retry#retry
           egg:repoze.tm#tm
           egg:repoze.vhm#vhm_xheaders 
           errorlog
           deliverance
           zope2
</code></pre><p>Before restarting zope (or rather 'reserving it with paster') I had to add the rulefiles mentioned in the filter declaration. Eager as I was at this point, I simply borrowed the trivial default rule and theme from Martin's recipe, spiced it up a little with <a href="http://svn.repoze.org/www/trunk/static.repoze.org/themes/maintainable/rules.xml">one of repoze.org's own rule files</a> and created a <code>etc/rules.xml</code> file that looked like this:
</p>
<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;rules xmlns:xi="http://www.w3.org/2001/XInclude" 
    xmlns="http://www.plone.org/deliverance"&gt;
    &lt;prepend theme="//head" content="//head/link" nocontent="ignore" /&gt; 
    &lt;prepend theme="//head" content="//head/style" nocontent="ignore" /&gt; 
    &lt;append theme="//head" content="//head/script" nocontent="ignore" /&gt;    
    &lt;append theme="//head" content="//head/meta" nocontent="ignore" /&gt;
    &lt;append-or-replace 
        theme="//head" 
        content="//head/title"
        nocontent="ignore" /&gt;
    &lt;append-or-replace theme="//div[@id='content']"
        content="//div[@id='region-content']"
        nocontent="ignore" /&gt;
&lt;/rules&gt;
</code></pre><p>and a <code>etc/layout.html</code> file that looked like this:
</p>
<pre><code>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15"&gt;
&lt;title&gt;The Theme&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;A theme&lt;/h1&gt;
&lt;div id="content"&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;address&gt;&lt;/address&gt;
&lt;!-- hhmts start --&gt;Last modified: Fri Mar 16 09:33:37 CDT 2007 &lt;!-- hhmts end --&gt;
&lt;/body&gt; &lt;/html&gt;
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&gt;

&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"&gt;
&lt;head&gt;
    &lt;title&gt;layout&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre><p>Now I could stop the foreground paster process, fire it up again, hit reload in my browser and voila! Bob was my proverbial Uncle!
</p>
<p>Next, I'll give <code>mod_wsgi</code> a try. But, of course, <em>not</em> the one for Apache but... yup, there's a <a href="mod_wsgi">mod_wsgi for nginx</a>, too, yay! Stay tuned...
</p>
<p>P.S. I'd like to take this opportunity to thank <a href="http://repoze.org/index.html" title="Repoze">Chris, Tres and Paul</a> for their efforts to connect Zope and Plone with non-techies and non-Zopistas. I'm very confident that you guys are creating some serious groundwork here that will benefit us immensely during <a href="http://limi.net/articles/thank-you-plone-community" title="Thank you, Plone Community! &amp;mdash limi.net">the next eight years</a>! Rock on!
</p>
          ]]>
        </content:encoded>        

        <dc:date>2008-04-08T18:01:42+00:00</dc:date>

        <dcterms:modified>2008-04-08T20:13:21+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        

        
            <dc:subject>zope</dc:subject>
        
        
            <dc:subject>repoze</dc:subject>
        
        
            <dc:subject>wsgi</dc:subject>
        
        
            <dc:subject>plone</dc:subject>
        
        
            <dc:subject>deliverance</dc:subject>
        

    </rss:item>

    
    

    <rss:item rdf:about="http://tomster.org/blog/archive/2008/04/04/using-the-oki-c9800-on-a-mac">

        <rss:title>Using the OKI C9800 on a Mac</rss:title>

        <rss:link>http://tomster.org/blog/archive/2008/04/04/using-the-oki-c9800-on-a-mac</rss:link>       

        <rss:description> From the WTF-Department
 </rss:description>

        <content:encoded>
          <![CDATA[
          <p>Earlier this week I bought a printer for the new project I'm working on. A <a href="http://www.c9800.co.uk/" title="OKI C9800 Colour Laser Printer">big, bad-ass OKI 9800 A3  color printer</a> for the price of a small car -- not my money -- the client's money ;-).
</p>
<p>Since we're a Mac-only shop here, I made sure it's got postscript3 and ethernet, so that connectivity wouldn't be a problem. Well, it was. Of course. Long story short: if we used the offical, OKI supplied PPD, the printer wouldn't print. It only could be coaxed into printing when using the generic postscript PPD -- which of course knew nothing about the A3 paper size or any of the other nifty features.
</p>
<p>After spending three days(!) with the OKI hotline (spent mainly with re-stating our problem and configuration to various operators) I finally hit gold. In the form of a friendly, competent and female(!) operator (Hallo, Frau Walther!) who didn't just resort to OKI's ticket database but (gasp!) to her <em>memory</em>. She actually <em>remembered</em> a similar case a while back, told me to hold, came back 30 seconds later and ever since we're able to print here!
</p>
<p>Turns out, that <strong>OKI has been delivering a faulty PPD - ever since march 2005!</strong> In the end it's just a single <code>%</code> character that's missing. I have to ask myself: WTF did they not update that file? Anyway, I'm posting this so that any other fellow OKI users can find this (because until now googling for the error <code>Missing filter "application/vnd.cups-postscript 0 fierycupsfilter"</code> didn't deliver any results. Hopefully, this will have changed).
</p>
<p>Below you can find a diff of the the PPD or, for your convenience, you can download a <a href="/geek/mac/OKI%20C9800/view">patched version right here from tomster.org</a>.
</p>
<pre><code>@@ -2947,5 +2947,5 @@

 *% PPD Last Modified 2005.03.10
 *% OS 10.2 PPD DB version 4/10/03 JDF
-*cupsFilter: "application/vnd.cups-postscript 0 fierycupsfilter"
+*% cupsFilter: "application/vnd.cups-postscript 0 fierycupsfilter"
 *% End of PPD file
</code></pre>
          ]]>
        </content:encoded>        

        <dc:date>2008-04-04T12:03:31+00:00</dc:date>

        <dcterms:modified>2008-04-04T16:20:51+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        

        
            <dc:subject>rant</dc:subject>
        
        
            <dc:subject>macintosh</dc:subject>
        
        
            <dc:subject>hints</dc:subject>
        

    </rss:item>

    
    

    <rss:item rdf:about="http://tomster.org/blog/archive/2008/04/02/url-dependent-skinswitching-in-plone-3">

        <rss:title>URL-dependent skinswitching in Plone 3</rss:title>

        <rss:link>http://tomster.org/blog/archive/2008/04/02/url-dependent-skinswitching-in-plone-3</rss:link>       

        

        <content:encoded>
          <![CDATA[
          <p>I was just about to explain to somebody via email how to switch skins per url in Plone 3 when I realised I should rather blog it and send him the link instead of just explain it to him privately, so here it goes...
</p>
<p>Add a file <code>skinswitcher.py</code> to the top-level of your product with the following contents:
</p>
<pre><code>def setskin(site, event):
    if event.request.URL.find('127.0.0.1') &gt; -1 \
        or event.request.URL.startswith('https'):
        site.changeSkin('NuPlone', event.request)
</code></pre><p>then include the following snippet in your top-level <code>configure.zcml</code>:
</p>
<pre><code>&lt;subscriber
    for="Products.CMFPlone.interfaces.IPloneSiteRoot
         zope.app.publication.interfaces.IBeforeTraverseEvent"
    handler=".skinswitcher.setskin" /&gt;
</code></pre><p>This particular example simply enables the <code>NuPlone</code> skin when the site is accessed via <code>https</code> or <code>127.0.0.1</code> (instead of <code>localhost</code>) and otherwise uses the default skin which is my usecase 99% of the time but it should be easy now to modify <code>skinswitcher.py</code> to your particular needs.
</p>
          ]]>
        </content:encoded>        

        <dc:date>2008-04-02T10:02:30+00:00</dc:date>

        <dcterms:modified>2008-04-02T15:37:55+00:00</dcterms:modified>

        <dc:creator>Tom Lazar</dc:creator>

        

        
            <dc:subject>plone</dc:subject>
        
        
            <dc:subject>hints</dc:subject>
        

    </rss:item>

    

</rdf:RDF>
