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

<Channel 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="http://purl.org/net/rss1.1#"
         xmlns:p="http://purl.org/net/rss1.1/payload#"
         rdf:about="http://lichota.pl/blog">

    <title>Blog</title>
    <link>http://lichota.pl/blog</link>

    

    <image rdf:parseType="Resource">
        <title>Blog</title>
        <url>http://lichota.pl/logo.png</url>
    </image>

    <items rdf:parseType="Collection">
        
        <item rdf:about="http://lichota.pl/blog/2009/12/27/plone.memoize-and-memcached">
            <title>plone.memoize and memcached</title>
            <link>http://lichota.pl/blog/2009/12/27/plone.memoize-and-memcached</link>
            <description>plone.memoize has built-in support for caching data in memcached, but it's not activated by default. In this article I want to show how to turn it on.</description>
            <p:payload xmlns="http://www.w3.org/1999/xhtml"
                       rdf:parseType="Literal"><div class="section">
<h3><a id="intruduction" name="intruduction">Intruduction</a></h3>
<p>By default results of functions that use <tt class="docutils literal"><span class="pre">&#64;plone.memoize.ram.cache</span></tt> decorator are stored in <tt class="docutils literal"><span class="pre">RAMCache</span></tt> - zope utility for storing data. But in <tt class="docutils literal"><span class="pre">ram.py</span></tt> file from <a class="reference" href="http://pypi.python.org/pypi/plone.memoize">plone.memoize</a> you can find <tt class="docutils literal"><span class="pre">MemcacheAdapter</span></tt> class. This adapter gives possibility to store this data in <a class="reference" href="http://memcached.org/">memcached</a>. To turn it on you must register <tt class="docutils literal"><span class="pre">ICacheCooser</span></tt> adapter.</p>
</div>
<div class="section">
<h3><a id="code" name="code">Code</a></h3>
<p><tt class="docutils literal"><span class="pre">memcached.py</span></tt>:</p>
<pre class="literal-block">
# -*- coding: utf-8 -*-
from threading import local
from pylibmc import Client
from plone.memoize.ram import MemcacheAdapter

class MemcacheChooserUtility(object):
    &quot;&quot;&quot;
    See ICacheChooser.
    &quot;&quot;&quot;
    _v_thread_local = local()

    def getClient(self):
        &quot;&quot;&quot;
        Return thread local connection to memcached.
        &quot;&quot;&quot;
        connection = getattr(self._v_thread_local, 'connection', None)
        if connection is None:
            connection = Client(['127.0.0.1:11211'])
            self._v_thread_local.connection = connection

        return connection

    def __call__(self, fun_name):
        &quot;&quot;&quot;
        Create new adapter for plone.memoize.ram.
        &quot;&quot;&quot;
        return MemcacheAdapter(client=self.getClient(), globalkey=fun_name)
</pre>
<p><tt class="docutils literal"><span class="pre">overrides.zcml</span></tt>:</p>
<pre class="literal-block">
&lt;configure xmlns=&quot;http://namespaces.zope.org/zope&quot;&gt;

    &lt;utility
        provides=&quot;plone.memoize.interfaces.ICacheChooser&quot;
        factory=&quot;.memcached.MemcacheChooserUtility&quot;
        /&gt;

&lt;/configure&gt;
</pre>
</div>
<div class="section">
<h3><a id="installation" name="installation">Installation</a></h3>
<p>Add <a class="reference" href="http://pypi.python.org/pypi/pylibmc/0.7.4">pylibmc</a> to buildout. Use <tt class="docutils literal"><span class="pre">0.7.4</span></tt> - last version compatible with python 2.4. You can also use <a class="reference" href="http://pypi.python.org/pypi/python-memcached">python-memcached</a>, but I prefer <tt class="docutils literal"><span class="pre">pylibmc</span></tt> because this library reopen connection after memcached restart automatically.</p>
<p>Remember to include <tt class="docutils literal"><span class="pre">overrides.zcml</span></tt> in instance configuration.</p>
</div>
<div class="section">
<h3><a id="pros-and-cons" name="pros-and-cons">Pros and cons</a></h3>
<p>Advantages:</p>
<ul class="simple">
<li>one cache for all instances on ZEO</li>
<li>restarting of Zope do not clear cache</li>
</ul>
<p>Disadvantages:</p>
<ul class="simple">
<li>no invalidating (but there is workaround - in next article)</li>
</ul>
</div>
</p:payload>
            <dc:date>2009-12-27T23:05:00+01:00</dc:date>
            <dcterms:modified>2009-12-27T23:04:19+01:00</dcterms:modified>
            <dc:creator>Wojciech Lichota</dc:creator>
            
            
            <dc:subject>memoize</dc:subject>
            
            
            <dc:subject>memcached</dc:subject>
            
            
            <dc:subject>plone</dc:subject>
            
        </item>
        
        
        <item rdf:about="http://lichota.pl/blog/2009/11/08/deploying-plone-site-to-static-files">
            <title>Deploying Plone site to static files</title>
            <link>http://lichota.pl/blog/2009/11/08/deploying-plone-site-to-static-files</link>
            <description>Shows how to dump site build with Plone to static website (HTML, CSS, JS, images, etc.).</description>
            <p:payload xmlns="http://www.w3.org/1999/xhtml"
                       rdf:parseType="Literal"><div class="section">
<h3><a id="introduction" name="introduction">Introduction</a></h3>
<p>Deploying Plone site to static files has the following advantages:</p>
<blockquote>
<ul class="simple">
<li>Security: You can run Plone internally, and possibly on a less robust/costly server, since it will only be used by internal content managers.  You could then export your published site content in its static form (.html, .css, .jpg, .swf, .pdf files, etc.) and deploy that static site easily to either a very affordable, simple shared HTML site hosting plan, or a massively scalable, load-balanced web server environment for larger organizations.</li>
<li>Scalability: Since the published site is static HTML, CSS, images, etc., with no database backend to have to connect to or dynamic scripting engine needed to transform the content as a page is requested, the site is served up much faster and the deployment environment is more stable due to fewer moving parts (no database, no scripting engine, etc.)  Demands on server CPU and RAM can be greatly reduced.</li>
<li>Flexible Hosting Options: You can run Plone on your laptop, export your static site as simple HTML, CSS, JavaScript, and image files, and deploy to a $5/month plan shared hosting environment.  Or, you can put your entire published site onto a thumb drive to carry around with you.  Your entire site could be served from memory (cache the static HTML and other files), since no database is needed for the published site to run.  There's no need to buy a Plone-centric hosting plan in this scenario.</li>
<li>It's Achievable!: There are a few sites out there using the CMFDeployment add-on tool for Zope/Plone.  This is the low-hanging fruit, but we shouldn't paint ourselves into a corner if there is a better approach.  Entransit may be another option, but to-date, this tool allows for exporting to a relational DB or possibly XML, but not HTML at the moment. <a class="footnote-reference" href="#id2" id="id1" name="id1">[1]</a></li>
</ul>
</blockquote>
<dl class="docutils">
<dt>I know about two packages that can deploy Plone site to static files:</dt>
<dd><ul class="first last simple">
<li><a class="reference" href="http://pypi.python.org/pypi/enpraxis.staticsite">enpraxis.staticsite</a></li>
<li><a class="reference" href="http://pypi.python.org/pypi/stxnext.staticdeployment">stxnext.staticdeployment</a></li>
</ul>
</dd>
</dl>
<p>In this article I will show how to install, configure and use <em>stxnext.staticdeployment</em>.</p>
</div>
<div class="section">
<h3><a id="domains" name="domains">Domains</a></h3>
<p>In my <a class="reference" href="/blog/plone-site-with-many-skins-simultaneously">previous blog entry</a> I described how to configure <em>frontend</em> and <em>backend</em> domains. In site with static deployment there are three domains:</p>
<blockquote>
<ul class="simple">
<li><em>backend</em> - for editors to edit content (default Plone skin)</li>
<li><em>preview</em> - for editors to immediately see changes is content (custom skin)</li>
<li><em>frontend</em> - for visitors (custom skin)</li>
</ul>
</blockquote>
<p><em>Frontend</em> domain is served by apache mainly from static files, but some of requests (e.g. submits of forms) are forwarded to Plone.</p>
</div>
<div class="section">
<h3><a id="installation" name="installation">Installation</a></h3>
<p>Edit buildout.cfg and append <cite>stxnext.staticdeployment</cite> to eggs and zcml parameters in instance section:</p>
<pre class="literal-block">
[instance]
eggs =
  ...
  stxnext.staticdeployment

zcml =
  ...
  stxnext.staticdeployment
</pre>
<p>Instance must be rebuild and restarted:</p>
<pre class="literal-block">
./bin/buildout
./bin/instance stop
./bin/instance start
</pre>
<p>This product must be also installed inside Plone site. Do do it, go to <em>Site Setup</em> -&gt; <em>Add/Remove Products</em>, select checkbox near <em>stxnext.staticdeployment</em> and click <em>Install</em> button.</p>
</div>
<div class="section">
<h3><a id="configuration" name="configuration">Configuration</a></h3>
<p>Every website has own configuration (different set of eggs, skin, products etc.) - this I meas as project. But website can have few instances (development, test and production instances). Because of this, configuration is split for two parts:</p>
<blockquote>
<ul class="simple">
<li>instance parameters:<ul>
<li>parameters connected to instance - e.g.: domain</li>
<li>configured in <em>Control Panel</em> - can be edited throw the web (<em>Site Setup</em> -&gt; <em>Static deployment</em> -&gt; <em>Settings</em> tab)</li>
<li>form has description and validation - can be used by less experienced users</li>
</ul>
</li>
<li>website parameters:<ul>
<li>stored in INI file</li>
<li>created by developer of website</li>
<li>can be used by many sites</li>
<li><a class="reference" href="https://svn.plone.org/svn/collective/stxnext.staticdeployment/trunk/src/stxnext/staticdeployment/etc/staticdeployment.ini">default configuration</a> (included in egg)</li>
<li>default configuration can be overriden by file <cite>${buildout:directory}/etc/staticdeployment.ini</cite></li>
</ul>
</li>
</ul>
</blockquote>
</div>
<div class="section">
<h3><a id="frontend-domain" name="frontend-domain"><em>Frontend</em> domain</a></h3>
<p><em>Frontend</em> domain must be configured in some special way. It will serve static files from disk, but if requested data do not exists in configured directory it will forward request to Plone. Similar all POST request should be also passed to Plone:</p>
<pre class="literal-block">
&lt;VirtualHost *:80&gt;
  ServerName example.org
  ServerAlias static.example.org
  DocumentRoot /var/www/example.org/html

  CustomLog /var/www/example.org/logs/access.log common
  ErrorLog /var/www/example.org/logs/error.log

  RewriteEngine on
  RequestHeader append plone_skin &quot;Notre Dame&quot;

  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}index.html !-f
  RewriteRule ^/(.*) &quot;http://localhost:8080/VirtualHostBase/http/%{SERVER_NAME}:80/site/++skin++Notre Dame/VirtualHostRoot/$1&quot; [L,P]

  ## make rewrite on every POST requests
  RewriteCond %{REQUEST_METHOD} ^POST$
  RewriteRule ^/(.*) &quot;http://localhost:8080/VirtualHostBase/http/%{SERVER_NAME}:80/site/++skin++Notre Dame/VirtualHostRoot/$1&quot; [L,P]
&lt;/VirtualHost&gt;
</pre>
<p>This is only basic configuration. It's very possible that list of circumstances (when content should be served from Plone not from files) will be bigger.</p>
</div>
<div class="section">
<h3><a id="deployment" name="deployment">Deployment</a></h3>
<p>When website is ready to deployment go to <em>Site Setup</em> -&gt; <em>Static deployment</em> -&gt; <em>Deployment</em> tab. Select <em>Deploy static version of website</em> checkbox and press <em>Save</em> button. Deployment will work for few seconds or minutes (it depends on size of website and server performance).</p>
</div>
<div class="section">
<h3><a id="summary" name="summary">Summary</a></h3>
<p><a class="reference" href="http://pypi.python.org/pypi/stxnext.staticdeployment">stxnext.staticdeployment</a> v 0.3.1 is not fully functional (it will not dump whole website to static files). Some of pages can work not properly. Static files can't provide all functionalities that are in Plone (e.g. interface translation). But we use this module (with success) in few our projects, so we decided to release it under Open Source license. It can be base for bigger, better and faster solution.</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><a class="reference" href="http://www.coactivate.org/projects/plone-static-publishing/project-home">Plone Static Publishing project at CoActivate</a></td></tr>
</tbody>
</table>
</div>
</p:payload>
            <dc:date>2009-11-08T10:24:33+01:00</dc:date>
            <dcterms:modified>2009-11-08T10:24:33+01:00</dcterms:modified>
            <dc:creator>Wojciech Lichota</dc:creator>
            
            
            <dc:subject>apache</dc:subject>
            
            
            <dc:subject>buildout</dc:subject>
            
            
            <dc:subject>plone</dc:subject>
            
            
            <dc:subject>staticdeployment</dc:subject>
            
        </item>
        
        
        <item rdf:about="http://lichota.pl/blog/2009/11/07/compiled-website-with-plone-django-xapian-and-ssi">
            <title>Compiled Website with Plone, Django, Xapian and SSI</title>
            <link>http://lichota.pl/blog/2009/11/07/compiled-website-with-plone-django-xapian-and-ssi</link>
            <description>Slides from talk (RuPy 2009) about deployment large scale applications based on Plone, Django, Xapian and SSI.</description>
            <p:payload xmlns="http://www.w3.org/1999/xhtml"
                       rdf:parseType="Literal">
<p>Slides from <a class="external-link" href="http://rupy.eu">RuPy</a> talk "Composite Website with Plone, Django, Xapian and SSI" by <a class="external-link" href="http://lukasz.langa.pl">Łukasz Langa</a> and me.</p>
<p><a title="Compiled Website with Plone, Django, Xapian and SSI" class="internal-link" href="uploads/compiled_websites_rupy09.pdf">Compiled Website with Plone, Django, Xapian and SSI</a> (PDF - 6 MB)</p>
<p><a class="external-link" href="http://www.slideshare.net/wlichota/compiled-websites-with-plone-django-xapian-and-ssi">Presentation on SlideShare.net</a></p>
</p:payload>
            <dc:date>2009-11-07T18:10:00+01:00</dc:date>
            <dcterms:modified>2009-11-08T13:53:37+01:00</dcterms:modified>
            <dc:creator>Wojciech Lichota</dc:creator>
            
            
            <dc:subject>wsgi</dc:subject>
            
            
            <dc:subject>xapian</dc:subject>
            
            
            <dc:subject>python</dc:subject>
            
            
            <dc:subject>django</dc:subject>
            
            
            <dc:subject>apache</dc:subject>
            
            
            <dc:subject>plone</dc:subject>
            
            
            <dc:subject>staticdeployment</dc:subject>
            
        </item>
        
        
        <item rdf:about="http://lichota.pl/blog/2009/09/30/plone-site-with-many-skins-simultaneously">
            <title>Plone site with many skins simultaneously</title>
            <link>http://lichota.pl/blog/2009/09/30/plone-site-with-many-skins-simultaneously</link>
            <description>Shows how to setup site on Plone with many skins. Each skin will have own domain.</description>
            <p:payload xmlns="http://www.w3.org/1999/xhtml"
                       rdf:parseType="Literal"><p>Default plone skin is tidy and user-friendly but is not beautiful. Because of this most of users, want to change look and feel of site build with Plone.</p>
<p>There are many <a class="reference" href="http://plone.org/products/search?getCategories=themes&amp;portal_type=PSCProject">additional skins</a> that can be easily installed.</p>
<p>Most of available new skins for Plone looks better, but also skins are not so user-friendly for editors like default skin. Best situation could be if editor could use default skin and visitor could see site in other skin. This is possible - and even not so complicated to configure.</p>
<div class="section">
<h3><a id="installing-new-skin" name="installing-new-skin">Installing new skin</a></h3>
<p>As example I will use <a class="reference" href="http://plone.org/products/plonetheme-notredame/">Notre Dame</a> - skin is used on this website.</p>
<p>At first egg with skin must be added to instance. Edit <cite>buildout.cfg</cite> and append skin to <cite>eggs</cite> and <cite>zcml</cite> parameters in <cite>instance</cite> section:</p>
<pre class="literal-block">
[instance]
eggs =
    ...
    plonetheme.notredame

zcml =
    ...
    plonetheme.notredame
</pre>
<p>Instance must be rebuild and restarted:</p>
<pre class="literal-block">
./bin/buildout
./bin/instance stop
./bin/instance start
</pre>
<p>Now new skin must be installed inside PloneSite. Do do it, go to <em>Site Setup</em> -&gt; <em>Add/Remove Products</em>, select checkbox near <em>Notre Dame</em> and click <em>Install</em> button.</p>
<p>After reload you should see website in new skin.</p>
</div>
<div class="section">
<h3><a id="configuring-skin-on-other-domain" name="configuring-skin-on-other-domain">Configuring skin on other domain</a></h3>
<p>At first site must me reconfigured in <em>ZMI</em>.</p>
<p>Go to <em>properties tab</em> in <em>portal_skin</em> (<a class="reference" href="http://example.org:8080/site/portal_skins/manage_propertiesForm">http://example.org:8080/site/portal_skins/manage_propertiesForm</a>) and set <em>REQUEST variable name</em> to <cite>HTTP_PLONE_SKIN</cite></p>
<p>In <em>portal_css</em> you must recognize all entries that was added by new skin. In most cases it will be few last entries. New style added by <em>Notre Dame</em> are preceded by <cite>++resource++plonetheme.notredame</cite> - so in this case it's very easy.</p>
<p>In these entries you must add new condition:</p>
<pre class="literal-block">
python: portal.REQUEST.get('HTTP_PLONE_SKIN', *) == 'Notre Dame'
</pre>
<p>Last thing to configure is apache. Create new file with vhost configuration:</p>
<pre class="literal-block">
&lt;VirtualHost *:80&gt;
    ServerName admin.example.org
    ServerAdmin admin&#64;example.org

    RewriteEngine on
    RequestHeader append plone_skin &quot;Plone Default&quot;
    RewriteRule ^/(.*) http://localhost:8080/VirtualHostBase/http/%{SERVER_NAME}:80/site/VirtualHostRoot/$1 [L,P]
&lt;/VirtualHost&gt;

&lt;VirtualHost *:80&gt;
    ServerName example.org
    ServerAdmin admin&#64;example.org

    RewriteEngine on
    RequestHeader append plone_skin &quot;Notre Dame&quot;
    RewriteRule ^/(.*) &quot;http://localhost:8080/VirtualHostBase/http/%{SERVER_NAME}:80/site/++skin++Notre Dame/VirtualHostRoot/$1&quot; [L,P]
&lt;/VirtualHost&gt;
</pre>
<p>After apache <em>reload</em> you can use two urls:</p>
<blockquote>
<ul class="simple">
<li><em>backend domain</em> - <a class="reference" href="http://admin.example.org">http://admin.example.org</a> (Default Plone skin)</li>
<li><em>frontend domain</em> - <a class="reference" href="http://example.org">http://example.org</a> (Notre Dame skin)</li>
</ul>
</blockquote>
</div>
<div class="section">
<h3><a id="pros-and-cons" name="pros-and-cons">pros and cons</a></h3>
<p>Advantages:</p>
<blockquote>
<ul class="simple">
<li>editor can use the same UI on every site</li>
<li>visitor can see nicer website</li>
<li>it's easier to create new skin only for visitors (designer, html and css specialist do not need to bother about screens to edit content)</li>
<li>caching (e.g. varnish) can be configured only for <em>frontend domain</em></li>
</ul>
</blockquote>
<dl class="docutils">
<dt>Disadvantages:</dt>
<dd><ul class="first last simple">
<li>in <em>backend domain</em> you do not edit content with the same CSS - so you will see effect only after save</li>
<li><em>frontend</em> and <em>backend</em> uses the same portlets - in <em>backend</em> you see portlets that are useful only for visitors</li>
</ul>
</dd>
</dl>
</div>
</p:payload>
            <dc:date>2009-09-30T20:34:39+02:00</dc:date>
            <dcterms:modified>2009-09-30T20:34:39+02:00</dcterms:modified>
            <dc:creator>Wojciech Lichota</dc:creator>
            
            
            <dc:subject>apache</dc:subject>
            
            
            <dc:subject>buildout</dc:subject>
            
            
            <dc:subject>plone</dc:subject>
            
            
            <dc:subject>skin</dc:subject>
            
        </item>
        
        
        <item rdf:about="http://lichota.pl/blog/2009/09/17/plone-and-video-content">
            <title>Plone and video content</title>
            <link>http://lichota.pl/blog/2009/09/17/plone-and-video-content</link>
            <description>Shows how to publish video in website based on Plone (3.3).</description>
            <p:payload xmlns="http://www.w3.org/1999/xhtml"
                       rdf:parseType="Literal"><div class="section">
<h3><a id="introduction" name="introduction">Introduction</a></h3>
<p>Site based on default Plone configuration can be extended to support video content.</p>
<p>There are few solutions to present videos in Plone:</p>
<blockquote>
<ul class="simple">
<li>p4a.plonevideoembed</li>
<li>Products.FlashVideo</li>
<li>collective.flowplayer</li>
</ul>
</blockquote>
<p>I prefer <a class="reference" href="http://pypi.python.org/pypi/collective.flowplayer">collective.flowplayer</a>, because it's light, user-friendly and up-to-date.
This product integrates <a class="reference" href="http://flowplayer.org/">flowplayer</a> ver. 3 (on GPL license) - it can play AVI, MP3 and MP4 media files.</p>
<p>Few days ago I made additional module - <a class="reference" href="http://stxnext.pl/open-source/stxnext.transform.avi2flv">stxnext.transform.avi2flv</a>. It converts videos in AVI format to FLV. This conversion is made automatically, when editor uploads file recognized as AVI.</p>
</div>
<div class="section">
<h3><a id="requirements" name="requirements">Requirements</a></h3>
<p><a class="reference" href="http://stxnext.pl/open-source/stxnext.transform.avi2flv">stxnext.transform.avi2flv</a> uses <cite>FFmpeg</cite>. It must be installed with mp3 (lame) nad flv support.</p>
<p>To install it on Ubuntu 9.04 you have to run:</p>
<pre class="literal-block">
sudo apt-get install ffmpeg libavcodec-unstripped-52
</pre>
<p>On CentOS 5.3 command is even simpler:</p>
<pre class="literal-block">
sudo yum install ffmpeg
</pre>
</div>
<div class="section">
<h3><a id="installation" name="installation">Installation</a></h3>
<p>Plone's 3.3 standard buildout must be extended only with few lines:</p>
<pre class="literal-block">
[buildout]
...
eggs =
    ...
    stxnext.transform.avi2flv
    collective.flowplayer

[zope2]
...
additional-fake-eggs =
    collective.testcaselayer


[instance]
...
zcml =
    ...
    stxnext.transform.avi2flv
    collective.flowplayer
</pre>
<p>After rebuild and restart of instance this two products must be also activated.
Go to <strong>Site Setup</strong> -&gt; <strong>Add/Remove Products</strong> and install <strong>Avi2flv Transform Install</strong>.</p>
</div>
<div class="section">
<h3><a id="configuration" name="configuration">Configuration</a></h3>
<p>Options for FFmpeg that controls quality of output video can be configured via ZMI.
Go to <a class="reference" href="http:/example.org/site/portal_transforms/avi_to_flv/manage_main">http:/example.org/site/portal_transforms/avi_to_flv/manage_main</a></p>
<p>With default configuration it will execute command similar to:</p>
<pre class="literal-block">
ffmpeg -i &quot;input.avi&quot; -y -b 1024k -r 25 -acodec libmp3lame -ar 44100 'output.flv'
</pre>
<p>Description of these options and more control parameters you can find in <a class="reference" href="http://ffmpeg.org/ffmpeg-doc.html">FFmpeg manual</a>.</p>
</div>
</p:payload>
            <dc:date>2009-09-17T22:21:56+02:00</dc:date>
            <dcterms:modified>2009-09-17T22:21:56+02:00</dcterms:modified>
            <dc:creator>Wojciech Lichota</dc:creator>
            
            
            <dc:subject>video</dc:subject>
            
            
            <dc:subject>buildout</dc:subject>
            
            
            <dc:subject>plone</dc:subject>
            
        </item>
        
        
        <item rdf:about="http://lichota.pl/blog/2009/08/13/plone-discussion-mechanism-replaced-by-collective.disqus">
            <title>Plone discussion mechanism replaced by collective.disqus</title>
            <link>http://lichota.pl/blog/2009/08/13/plone-discussion-mechanism-replaced-by-collective.disqus</link>
            <description>Today I updated this website to newest Plone (3.3 rc5). Also I replaced default Plone discussion mechanism by DISQUS comments system. In few works I will describe this proccess and my motivations.</description>
            <p:payload xmlns="http://www.w3.org/1999/xhtml"
                       rdf:parseType="Literal"><p>Today I replaced default Plone discussion mechanism with <a class="reference" href="http://disqus.com">DISQUS</a> comments system.</p>
<div class="section">
<h3><a id="installation-and-configuration" name="installation-and-configuration">Installation and configuration</a></h3>
<p>It's only few easy steps to integrate DISQUS with your Plone site:</p>
<ul>
<li><p class="first">create account on <a class="reference" href="http://disqus.com">DISQUS</a></p>
</li>
<li><p class="first">add you website in DISQUS admin panel (remember configured website short name)</p>
</li>
<li><p class="first">install <cite>collective.disqus</cite>:
- add to your buildout:</p>
<pre class="literal-block">
eggs =
  collective.disqus
...
zcml =
  collective.disqus
</pre>
<ul class="simple">
<li>use <em>Add products</em> in <em>Site Setup</em> or <em>QuickInstaller</em> to activate it</li>
</ul>
</li>
<li><p class="first">go to <em>Site Setup</em> -&gt; <em>DISQUS comment system</em> form and configure <em>Website short name</em></p>
</li>
<li><p class="first">enable <em>Allow discussion</em> option in content objects</p>
</li>
</ul>
<p>Current version of <cite>collective.disqus</cite> doesn't migrate comments. So all comments that was created before installation will be hidden (not removed).</p>
</div>
<div class="section">
<h3><a id="motivation" name="motivation">Motivation</a></h3>
<p>Default Plone discussion mechanism doesn't have nice panel to administer comments. It's hard to find new comments. It's not possible to block posts with links or some other unwelcome contents.</p>
<p>There is few products that tries to fill up this gaps:</p>
<ul class="simple">
<li><a class="reference" href="http://plone.org/products/plone-comments/">quintagroup.plonecomments</a></li>
<li><a class="reference" href="http://pypi.python.org/pypi/collective.discussionplus">collective.discussionplus</a></li>
<li><a class="reference" href="http://plone.org/products/easycommenting/">EasyCommenting</a></li>
</ul>
<p>In <em>clean</em> Plone commenting is allowed only for authenticated site members. This can be of course also widen:</p>
<ul class="simple">
<li><a class="reference" href="http://plone.org/documentation/how-to/openid-support">plone.openid</a></li>
<li><a class="reference" href="http://plone.org/products/AnonymousCommenting/">AnonymousCommenting</a></li>
<li><a class="reference" href="http://plone.org/products/plone-captchas/">quintagroup.plonecaptchas</a></li>
</ul>
<p>Installation and proper configuration of so many plugins will take some time and functionality will not be full.</p>
<p>But on the web there are much more specialized tools for commenting:</p>
<ul class="simple">
<li><a class="reference" href="http://js-kit.com/">JS-Kit</a></li>
<li><a class="reference" href="http://disqus.com">DISQUS</a></li>
<li><a class="reference" href="http://intensedebate.com/home">IntenseDebate</a></li>
</ul>
<p>This comments system can be easyly integrated with sites - user just need to create account and add some special code into his website.</p>
<p>I use DISQUS because:</p>
<ul class="simple">
<li>it was ease to integrate</li>
<li>it's easy to manage comments and threads</li>
<li>has clean admin panel</li>
<li>it's free, without adverts</li>
<li>look &amp; feel is similar to Plone's</li>
</ul>
</div>
<div class="section">
<h3><a id="example" name="example">Example</a></h3>
<p>Example of DISQUS comment system integrated with Plone you can see at the bottom of this page.</p>
</div>
</p:payload>
            <dc:date>2009-08-13T23:45:00+02:00</dc:date>
            <dcterms:modified>2009-08-13T23:57:15+02:00</dcterms:modified>
            <dc:creator>Wojciech Lichota</dc:creator>
            
            
            <dc:subject>collective</dc:subject>
            
            
            <dc:subject>disqus</dc:subject>
            
            
            <dc:subject>plone</dc:subject>
            
        </item>
        
        
        <item rdf:about="http://lichota.pl/blog/2009/08/09/lxml-infinity-loop-memory-leak-workaround-for-deliverance">
            <title>lxml infinity loop/memory leak - workaround for deliverance</title>
            <link>http://lichota.pl/blog/2009/08/09/lxml-infinity-loop-memory-leak-workaround-for-deliverance</link>
            <description>lxml's (v2.0 - v2.2.2) implementation of CSSSelector has bug that can use all available memory. This situation can totally hang your server. In here I will show few workarounds - useful until this bug will be fixed.</description>
            <p:payload xmlns="http://www.w3.org/1999/xhtml"
                       rdf:parseType="Literal"><p>Few weeks ago we had some problems with development server. After few minutes of work server totally hang - every try to connect via ssh was finished with timeout.
We had to make hard reset but after few minutes it hang again. Next restart, but this time we turn on debug mode (single user mode in linux) and start services one by one.
After this investigations we was surprised that deliverance after few minutes of work consume all available memory (4 GB of RAM and 6 GB of swap).</p>
<p>Further investigation show that CSS selector with typo was so problematic.</p>
<p>In deliverance v0.3 (trunk version) rules has <em>pointers</em> to HTML elements. This pointers consists with two parts - type of selection (e.g.: children or attributes) and selector (CSS selector or XPath) separated with colon:</p>
<pre class="literal-block">
&lt;replace content=&quot;children:#content-wrapper&quot; theme=&quot;children:#content&quot; /&gt;
</pre>
<p>Let look at sample:</p>
<blockquote>
attributes(href):/html/body/a</blockquote>
<p>Deliverance will use XPath to extract tag <strong>a</strong> from body of document.
But if developer forgot colon (<strong>:</strong>):</p>
<pre class="literal-block">
attributes(href)/html/body/a
</pre>
<p>this <em>pointer</em> will be parsed by lxml as CSS selector. Of course this selector is not correct, but lxml (versions 2.0 - 2.2.2) cannot manage it and parse it in infinity loop and consume more and more memory. Issue is submitted on <a class="reference" href="https://bugs.launchpad.net/lxml/+bug/401630">lxml bug tracker</a></p>
<div class="section">
<h3><a id="workarounds" name="workarounds">Workarounds</a></h3>
<p>Deliverance use not more than 512 MB of memory so environment must not allow to use more than this.</p>
<div class="section">
<h4><a id="memory-limit-for-user" name="memory-limit-for-user">1. Memory limit for user</a></h4>
<p>Run <em>deliverance-proxy</em> as separated user. Make system limits for this user. More info in manual pages on every linux:</p>
<pre class="literal-block">
man limits.conf
</pre>
<p>If deliverance will <em>eat</em> to much memory python will rise MemoryError.</p>
</div>
<div class="section">
<h4><a id="memory-limit-for-process" name="memory-limit-for-process">2. Memory limit for process</a></h4>
<p>Configure limits only for processes started form commend line. Create simple bash script:</p>
<pre class="literal-block">
#!/bin/bash
ulimit -v 507200
ulimit -H -v 507200

bin/deliverance-proxy $*
</pre>
<p>Also with this script deliverance will stop with MemoryError.</p>
</div>
<div class="section">
<h4><a id="use-memmon-from-supervisor" name="use-memmon-from-supervisor">3. Use memmon from supervisor</a></h4>
<p><a class="reference" href="http://supervisord.org">Supervisor</a>'s plugin <a class="reference" href="http://pypi.python.org/pypi/superlance">superlance</a> has special feature that will restart process it if use to much memory. Configuration is simple with buildout:</p>
<pre class="literal-block">
[buildout]
extensions = gp.vcsdevelop
vcs-extend-develop = svn+http://codespeak.net/svn/z3/deliverance/trunk/#egg=deliverance
develop-dir = src

parts =
  deliverance
  supervisor

eggs =
  deliverance

[deliverance]
recipe = repoze.recipe.egg:scripts
scripts = deliverance-proxy
eggs = ${buildout:eggs}

[supervisor]
recipe = collective.recipe.supervisor
plugins = superlance
port = 8000
user = admin
password = :)
serverurl = http://127.0.0.1:8000
programs =
  10 deliverance ${buildout:bin-directory}/deliverance-proxy [${buildout:directory}/src/theme/rules.xml] true
eventlisteners =
  Memmon TICK_60 ${buildout:bin-directory}/memmon [-p deliverance=500MB]
</pre>
<p>This will build deliverance-proxy controlled with supervisor and monitored for memory leaks.</p>
</div>
</div>
</p:payload>
            <dc:date>2009-08-09T22:45:00+02:00</dc:date>
            <dcterms:modified>2009-08-13T22:01:51+02:00</dcterms:modified>
            <dc:creator>Wojciech Lichota</dc:creator>
            
            
            <dc:subject>python</dc:subject>
            
            
            <dc:subject>lxml</dc:subject>
            
            
            <dc:subject>deliverance</dc:subject>
            
        </item>
        
        
        <item rdf:about="http://lichota.pl/blog/2009/07/12/buildout-for-plone-3-with-deliverance-on-wsgi">
            <title>Buildout for Plone 3 with deliverance on WSGI</title>
            <link>http://lichota.pl/blog/2009/07/12/buildout-for-plone-3-with-deliverance-on-wsgi</link>
            <description>In this article I want to show how to create development and production instances of Plone (3.3 rc4) with deliverance (0.3 - trunk version). All components lives in WSGI environment and cooperated with Apache HTTP server.</description>
            <p:payload xmlns="http://www.w3.org/1999/xhtml"
                       rdf:parseType="Literal"><p>I made this article because most of tutorials available on web use some strange techniques, like <a class="reference" href="http://blog.redinnovation.com/2009/03/13/setting-up-plone-32-and-repoze-hackyish/">hacks</a>, <a class="reference" href="http://www.martinaspeli.net/articles/rolling-out-repoze">rolling out</a> or <a class="reference" href="http://feneric.blogspot.com/2009/06/buildout-with-repoze-zope-and-plone.html">manual paths configuration</a>. Not bed is <a class="reference" href="http://plone.org/documentation/tutorial/install-plone-3-behind-apache-and-mod_wsgi-using-repoze">official tutorial</a> but there is to many manual steps (like running <tt class="docutils literal"><span class="pre">mkzope2instance</span></tt>) and it doesn't show how to use deliverance. My development buildout is quite similar to solution described in <a class="reference" href="http://www.sixfeetup.com/blog/2009/4/27/deploying-plone-and-zine-together-with-deliverance-using-repoze">six feet up blog post</a>.</p>
<p>My solution is designed to be as simple as possible:</p>
<ul class="simple">
<li>only few commands</li>
<li>generates all necessary config files (for paster, apache, mod_wsgi)</li>
<li>easy for development</li>
<li>fast in production</li>
</ul>
<div class="section">
<h3><a id="development-instance" name="development-instance">Development instance</a></h3>
<p>This instance will help during development of deliverance theme. Programmer or designer must edit ruleset - definition of transforms that deliverance should perform on theme and content taken form Plone.</p>
<div class="section">
<h4><a id="ingredients" name="ingredients">Ingredients</a></h4>
<dl class="docutils">
<dt>Frontend HTTP server (<strong>Apache2</strong> with mod_rewrite)</dt>
<dd>Listen on port 80, recognize virtual hosts and makes rewrites to Paster</dd>
<dt>Backend HTTP server (<strong>Paster</strong>)</dt>
<dd>Listen on non-privileged port (&gt;1024), creates WSGI stack, serves static content (e.g. theme files)</dd>
<dt>Theme engine (<strong>Deliverance</strong>)</dt>
<dd>Change layout of website</dd>
<dt>Main application (<strong>repoze.zope2</strong>)</dt>
<dd>Allow Zope2 application exist in WSGI environment</dd>
<dt>Content Management System (<strong>Plone</strong>)</dt>
<dd>CMS based on Zope2, simplifies creating and managing of website content</dd>
</dl>
</div>
<div class="section">
<h4><a id="installation" name="installation">Installation</a></h4>
<p>Download and extract all files from <a class="reference" href="http://lichota.pl/blog/uploads/plone_deliverance_wsgi.tar.gz">plone_deliverance_wsgi.tar.gz</a> archive:</p>
<pre class="literal-block">
cd /var/lib/zope
wget http://lichota.pl/blog/uploads/plone_deliverance_wsgi.tar.gz
tar -xvzf plone_deliverance_wsgi.tar.gz
cd plone_deliverance_wsgi
</pre>
<p>Edit <tt class="docutils literal"><span class="pre">settings.cfg</span></tt> and configure basic settings like: domain name (be default deliverance.example.com, port number (default <tt class="docutils literal"><span class="pre">8080</span></tt>) or admin password (<tt class="docutils literal"><span class="pre">admin</span></tt>).</p>
<p>If chosen domain name is not configured in any DNS, you can add it to your <tt class="docutils literal"><span class="pre">/etc/hosts</span></tt> file, and point in to <tt class="docutils literal"><span class="pre">127.0.0.1</span></tt>.</p>
<p>Run buildout:</p>
<pre class="literal-block">
python2.4 bootstrap.py
./bin/buildout -vc buildout-devel.cfg
</pre>
<p>Configure and restart apache:</p>
<pre class="literal-block">
sudo cp ./etc/deliverance.example.com.conf /etc/apache2/sites-enabled
sudo /etc/init.d/apache2 reload
</pre>
<p>Now you can start Paster:</p>
<pre class="literal-block">
./bin/ctl fg
</pre>
<p>ZMI will be available at address <a class="reference" href="http://127.0.0.1:8080/manage">http://127.0.0.1:8080/manage</a>.</p>
</div>
<div class="section">
<h4><a id="using" name="using">Using</a></h4>
<p>When everything is ready you can you three url's:</p>
<ul class="simple">
<li><a class="reference" href="http://admin.deliverance.example.com">http://admin.deliverance.example.com</a></li>
<li><a class="reference" href="http://deliverance.example.com">http://deliverance.example.com</a></li>
<li><a class="reference" href="http://www.deliverance.example.com">http://www.deliverance.example.com</a></li>
</ul>
<p>Using first address you can omit deliverance transforms, so you will see <em>clean</em> plone interface. With this address you can add, edit and manage content of website.</p>
<p>Next two addresses use deliverance engine. Theme and transform rules are located in <tt class="docutils literal"><span class="pre">./src/theme</span></tt> directory. All files in this directory are served by <tt class="docutils literal"><span class="pre">egg:Paster#static</span></tt> middleware. So for example main theme file is available at address <a class="reference" href="http://deliverance.example.com/theme/theme.html">http://deliverance.example.com/theme/theme.html</a></p>
<p>In archive with buildouts I included skin (released on Creative Common license) with very simple ruleset. This ruleset (<tt class="docutils literal"><span class="pre">./src/theme/rules.xml</span></tt>) takes some part of pages generated by Plone and insert it in theme. More informations about writing such ruleset you can find at <a class="reference" href="http://deliverance.openplans.org/configuration.html">deliverance documentation</a>.</p>
<p>In development instance theme and ruleset is parsed on every request, so it's slower but you do not need to restart paster after every change.</p>
<p>Development instance has some useful Plone products - <a class="reference" href="http://pypi.python.org/pypi/Products.DocFinderTab/1.0.4">Products.DocFinderTab</a>, <a class="reference" href="http://pypi.python.org/pypi/stxnext.pdb">stxnext.pdb</a>. It use also <tt class="docutils literal"><span class="pre">egg:Paste#evalerror</span></tt> middleware that allows interactive debugging.</p>
</div>
</div>
<div class="section">
<h3><a id="sample-deliverance-theme" name="sample-deliverance-theme">Sample deliverance theme</a></h3>
<p>Theme layout is based on <strong>colorus</strong> template created by <a class="reference" href="http://www.realitysoftware.ca">Reality Software</a> and released by <a class="reference" href="http://www.flash-gallery.org">Flash Gallery</a> under the <a class="reference" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> license.</p>
<p>Ruleset defines very simple transformations - copy some tags from <tt class="docutils literal"><span class="pre">head</span></tt>, removes unnecessary divs (e.g: <tt class="docutils literal"><span class="pre">&lt;div</span> <span class="pre">class=&quot;portletWrapper&quot;&gt;...&lt;/div&gt;</span></tt>), copy content (title, top menu, portlets, page content and footer).</p>
<p>Rules uses CSS selectors (only in v0.3) which are much more user friendly than XPath syntax.</p>
</div>
<div class="section">
<h3><a id="production-instance" name="production-instance">Production instance</a></h3>
<p>When website is ready we need move it to production server. It means that we need to create production instance. In this configuration Apache with <em>mod_wsgi</em> creates WSGI stack, so separated (backend) HTTP server is not needed.</p>
<div class="section">
<h4><a id="id1" name="id1">Installation</a></h4>
<p>Information how to install Apache2 with mod_wsgi you can find in <a class="reference" href="http://code.google.com/p/modwsgi/wiki/QuickInstallationGuide">mod_wsgi Wiki</a>. Remember that mod_wsgi <strong>must</strong> use python 2.4.x. If default python interpreter at server is newer than 2.4 (2.5 or 2.6) you must compile mod_wsgi form source and set python version before executing make:</p>
<pre class="literal-block">
cd /tmp
wget http://modwsgi.googlecode.com/files/mod_wsgi-version.tar.gz
cd mod_wsgi-version
./configure --with-python=/usr/bin/python2.4
make
sudo make install
</pre>
<p>Now lets create instance. Download and extract all files from <a class="reference" href="http://lichota.pl/blog/uploads/plone_deliverance_wsgi.tar.gz">plone_deliverance_wsgi.tar.gz</a> archive:</p>
<pre class="literal-block">
cd /var/lib/zope
wget http://lichota.pl/blog/uploads/plone_deliverance_wsgi.tar.gz
tar -xvzf plone_deliverance_wsgi.tar.gz
cd plone_deliverance_wsgi
</pre>
<p>Edit <tt class="docutils literal"><span class="pre">settings.cfg</span></tt> and change domain name, admin password and number of processes. In my opinion (based on some load tests) best performance of website is when number of processes is equal to number of CPU's (or CPU cores if such exists). Every process can also use few threads. Increasing threads number increase performance in small extent, so I suggest 2 threads.</p>
<p>Run buildout:</p>
<pre class="literal-block">
python2.4 bootstrap.py
./bin/buildout -vc buildout-production.cfg
</pre>
<p>You can also copy ZODB database file (<cite>./var/filestorage/Data.fs</cite>) from development instance to production server. Now you must copy created on development instance theme an place it in <cite>./src/theme</cite>.</p>
<p>Because mod_wsgi will create few separated applications (in few processes and threads) database (ZODB) must be accessible simultaneously. ZEO server (build by buildout recipe) will take care of it. We just need to start it:</p>
<pre class="literal-block">
./bin/zeoserver start
</pre>
<p>Configure and restart apache:</p>
<pre class="literal-block">
sudo cp ./etc/deliverance.example.com.conf /etc/apache2/sites-enabled
sudo /etc/init.d/apache2 reload
</pre>
<p>Zope will be not running on separated port. So to access ZMI there must be special address - <a class="reference" href="http://zmi.deliverance.example.com">http://zmi.deliverance.example.com</a></p>
<p>In production configuration deliverance rulset and theme is parsed only once - at application start. So when you edit something in this files you must restart apache.</p>
<hr class="docutils" />
<p><a class="reference" href="http://lichota.pl/blog/uploads/plone_deliverance_wsgi.tar.gz">Download the buildout used in this article</a> (52 KB)</p>
</div>
</div>
</p:payload>
            <dc:date>2009-07-12T18:45:00+02:00</dc:date>
            <dcterms:modified>2009-08-13T22:02:14+02:00</dcterms:modified>
            <dc:creator>Wojciech Lichota</dc:creator>
            
            
            <dc:subject>wsgi</dc:subject>
            
            
            <dc:subject>zope</dc:subject>
            
            
            <dc:subject>buildout</dc:subject>
            
            
            <dc:subject>repoze</dc:subject>
            
            
            <dc:subject>deliverance</dc:subject>
            
            
            <dc:subject>apache</dc:subject>
            
            
            <dc:subject>plone</dc:subject>
            
        </item>
        
        
        <item rdf:about="http://lichota.pl/blog/2009/07/06/gpxtools-tools-useful-to-manipulate-gpx-files">
            <title>gpxtools - command line tools useful to manipulate GPX files</title>
            <link>http://lichota.pl/blog/2009/07/06/gpxtools-tools-useful-to-manipulate-gpx-files</link>
            <description>Information about first release of gpxtools - command line tools useful to manipulate GPX files.</description>
            <p:payload xmlns="http://www.w3.org/1999/xhtml"
                       rdf:parseType="Literal"><p>One of my hobby is cycling. There are few website that collects informations about trips and than can show statistics. My favorite is <a class="reference" href="http://www.bikebrother.com/biker/sargo">BikeBrother</a>.</p>
<p>Some of my rides I record with GPS device (<a class="reference" href="http://www.royaltek.com/index.php?option=com_content&amp;view=article&amp;id=196:rbt-2100&amp;catid=52:bluetooth">RBT-2100</a>) connected via bluetooth to my phone (<a class="reference" href="http://www.sonyericsson.com/cws/products/mobilephones/overview/p1i?lc=pl&amp;cc=pl">SE P1i</a>). Tracks are stored in GPX files. But this data aren't perfect. For example - elevation (position in meters above sea level) sometimes has very strange value (probably because low quality of GPS device or some distortion of signal).</p>
<p>To fix such low quality data in GPX file I made few command-line tools:</p>
<dl class="docutils">
<dt><strong>gpx-elevation-fix</strong></dt>
<dd>Fixes elevation (Z-axis) data in GPX file based on <a class="reference" href="http://srtm.csi.cgiar.org/">SRTM</a> data.</dd>
<dt><strong>gpx-cleanup</strong></dt>
<dd>Removes from GPX file unnecessary data (e.g.: speed or course) stored by some GPS devices.</dd>
<dt><strong>gpx-compress</strong></dt>
<dd>Removes unnecessary chars (e.g.: white spaces) to decrease GPX file size.</dd>
</dl>
<p>Scripts are of course written in python. <a class="reference" href="http://pypi.python.org/pypi/gpxtools/">More information</a> can be found on PyPI.</p>
<p>Tools can be easily used in pipeline:</p>
<pre class="literal-block">
cat input.gpx  | ./bin/gpx-fix-elevation | ./bin/gpx-cleanup | ./bin/gpx-compress &gt; output.gpx
</pre>
<p>Correct value of elevation is calculated based on data from Shuttle Radar Topography Mission (<a class="reference" href="http://srtm.csi.cgiar.org/">SRTM</a>). Very useful was <a class="reference" href="http://code.google.com/p/eleserver/">eleserver</a> by <em>grahamjones139</em> - SRTM calculation code is based on this project.</p>
<p><em>gpx-cleanup</em> and <em>gpx-compress</em> commands should decrease GPX file size - shorter upload time.</p>
<p>In plans I have next tools:</p>
<ul class="simple">
<li>join and split GPS tracks,</li>
<li>strip track (remove points on start and end of track that are almost in the same place),</li>
<li>smooth track (recognize and remove accidental position jumps),</li>
</ul>
<p>but I must find some time for small research ;)</p>
</p:payload>
            <dc:date>2009-07-06T23:45:00+02:00</dc:date>
            <dcterms:modified>2009-08-13T22:02:32+02:00</dcterms:modified>
            <dc:creator>Wojciech Lichota</dc:creator>
            
            
            <dc:subject>buildout</dc:subject>
            
            
            <dc:subject>python</dc:subject>
            
            
            <dc:subject>gpxtools</dc:subject>
            
            
            <dc:subject>gpx</dc:subject>
            
            
            <dc:subject>gps</dc:subject>
            
        </item>
        
        
        <item rdf:about="http://lichota.pl/blog/2009/07/06/allow-openid-users-to-leave-comments-on-plone-based-websites">
            <title>Allow OpenID users to leave comments on Plone-based website</title>
            <link>http://lichota.pl/blog/2009/07/06/allow-openid-users-to-leave-comments-on-plone-based-websites</link>
            <description>Small tutorial that explains how to allow OpenID users to leave comments on Plone-based website.</description>
            <p:payload xmlns="http://www.w3.org/1999/xhtml"
                       rdf:parseType="Literal"><p>Every good blog should have ability to leave a comment on blog entry. Plone since version 3.0 has built in discussion support. To enable it, editor must check <em>Allow comments</em> checkbox on edit form.</p>
<p>By default only logged in users can leave comments. This approach is good for administrators (less comment spam), but is quite annoying for viewers - because they must create account. But there is solution good for both sides - OpenID.</p>
<p>To add OpenID support to Plone-based website just go to: <em>Site Setup</em> / <em>Add-on Products</em> and install <em>OpenID Authentication Support</em>. Now users can log in with OpenID, but still such users can't see &quot;Add Comment&quot; button.  To fix it I had to look into Plone code, because Google couldn't find any useful linka. Fix is very easy - authenticated user must have <em>Reply to item</em> permission.</p>
<p>Solution step by step:</p>
<ul class="simple">
<li>install <em>OpenID Authentication Support</em> in <em>Site Setup</em> / <em>Add-on Products</em>,</li>
<li>go to <em>Security</em> form (in ZMI) - just add <strong>manage_access</strong> to URL (e.g.: <a class="reference" href="http://example.com/plone-site/manage_access">http://example.com/plone-site/manage_access</a>),</li>
<li>set <em>Reply to item</em> permission for <em>Authenticated</em> users (click checkbox in row <em>Reply to item</em> for column <em>Authenticated</em> and click <em>Save Changes</em> button).</li>
</ul>
</p:payload>
            <dc:date>2009-07-06T00:10:00+02:00</dc:date>
            <dcterms:modified>2009-08-13T22:02:51+02:00</dcterms:modified>
            <dc:creator>Wojciech Lichota</dc:creator>
            
            
            <dc:subject>zope</dc:subject>
            
            
            <dc:subject>openid</dc:subject>
            
            
            <dc:subject>plone</dc:subject>
            
        </item>
        
        
        <item rdf:about="http://lichota.pl/blog/2009/07/04/development-buildout-for-plone-3.3-rc3-on-repoze">
            <title>Simple development buildout for Plone 3.3 (RC3) on Repoze</title>
            <link>http://lichota.pl/blog/2009/07/04/development-buildout-for-plone-3.3-rc3-on-repoze</link>
            <description>Introduce how to build newest Plone instance and run it with paster.</description>
            <p:payload xmlns="http://www.w3.org/1999/xhtml"
                       rdf:parseType="Literal">
<p>On the web there are some documents that describes how to build Plone compatibile with WSGI, e.g.:</p>
<ul><li><a class="external-link" href="http://valentinewebsystems.com/en/blog/2008/02/19/plone-repoze-and-buildout">How to add repoze to your plone buildout</a></li><li><a class="external-link" href="http://feneric.blogspot.com/2009/06/buildout-with-repoze-zope-and-plone.html">Buildout with Repoze, Zope, and Plone</a></li><li><a class="external-link" href="http://www.martinaspeli.net/articles/rolling-out-repoze">Rolling out Repoze</a><br /></li></ul>
But this solutions uses mostly now very beautiful workarounds. So I made my own buildout. I will use it only for development. Deployment buildout probably will be completely different.
<p>Buildout is based on code be <a title="Posts by Mikko Ohtamaa" href="http://blog.redinnovation.com/author/moo/">Mikko Ohtamaa</a> published on Red Innovation Ltd. <a class="external-link" href="http://blog.redinnovation.com/2009/03/13/setting-up-plone-32-and-repoze-hackyish/">blog</a>.</p>
<pre>[buildout]
extends =
    http://good-py.appspot.com/release/repoze.zope2/1.0
    http://dist.plone.org/release/3.3rc3/versions.cfg

parts =
    zope2
    paster
    instance

find-links =
    http://dist.repoze.org/zope2/latest
    http://dist.repoze.org/zope2/dev
    http://dist.plone.org/release/3.3rc3
    http://download.zope.org/ppix/
    http://download.zope.org/distribution/
    http://effbot.org/downloads
     
develop =

eggs =
    Plone
    stxnext.pdb
    Products.DocFinderTab
    elementtree
    repoze.debug

versions = versions


[zope2]
recipe = plone.recipe.zope2install
url = ${versions:zope2-url}
fake-zope-eggs = true
additional-fake-eggs =
    ZODB3
    ZConfig
    pytz


[paster]
recipe = repoze.recipe.egg
scripts = paster
eggs =
   ${buildout:eggs}
   repoze.zope2


[instance]
recipe = plone.recipe.zope2instance
zope2-location = ${zope2:location}
user = admin:admin
effective-user = zope
http-address = 8080
debug-mode = on
verbose-security = on
eggs = ${buildout:eggs}
zcml =
    stxnext.pdb
        
zope-conf-additional =
    &lt;cgi-environment&gt;
    HTTP_ACCEPT_CHARSET utf-8
    &lt;/cgi-environment&gt;</pre>
Paster to run needs development.ini file:
<pre>[DEFAULT]
debug = True

[app:zope2]
paste.app_factory = repoze.obob.publisher:make_obob
repoze.obob.get_root = repoze.zope2.z2bob:get_root
repoze.obob.initializer = repoze.zope2.z2bob:initialize
repoze.obob.helper_factory = repoze.zope2.z2bob:Zope2ObobHelper
zope.conf = %(here)s/parts/instance/etc/zope.conf

[filter:errorlog]
use = egg:repoze.errorlog#errorlog
path = /__error_log__
keep = 20
ignore = 
    paste.httpexceptions:HTTPUnauthorized
    paste.httpexceptions:HTTPNotFound
    paste.httpexceptions:HTTPFound

[pipeline:main]
pipeline =
    egg:repoze.debug#pdbpm
    egg:Paste#httpexceptions
    egg:repoze.retry#retry
    egg:repoze.tm#tm
    egg:repoze.vhm#vhm_xheaders
    errorlog
    zope2

[server:main]
use = egg:Paste#http
host = 127.0.0.1
port = 8080</pre>
<p>To start web server use command:</p>
<pre>./bin/paster serve development.ini</pre>
<p>Voilà :)</p>
</p:payload>
            <dc:date>2009-07-04T13:55:00-07:00</dc:date>
            <dcterms:modified>2009-07-05T12:29:52-07:00</dcterms:modified>
            <dc:creator>Wojciech Lichota</dc:creator>
            
            
            <dc:subject>wsgi</dc:subject>
            
            
            <dc:subject>buildout</dc:subject>
            
            
            <dc:subject>python</dc:subject>
            
            
            <dc:subject>repoze</dc:subject>
            
            
            <dc:subject>zope</dc:subject>
            
            
            <dc:subject>plone</dc:subject>
            
        </item>
        
    </items>
</Channel>

