<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>mFabrik - mobile sites, apps, HTML5 and CMS software development &#187; django</title>
	<atom:link href="http://blog.mfabrik.com/tag/django/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mfabrik.com</link>
	<description>Freedom delivered.</description>
	<lastBuildDate>Wed, 03 Aug 2011 09:47:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Generic Python validation frameworks?</title>
		<link>http://blog.mfabrik.com/2011/07/07/generic-python-validation-frameworks/</link>
		<comments>http://blog.mfabrik.com/2011/07/07/generic-python-validation-frameworks/#comments</comments>
		<pubDate>Thu, 07 Jul 2011 14:48:15 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[plone]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://blog.mfabrik.com/?p=1308</guid>
		<description><![CDATA[All Python ORM and form frameworks love to define own field/schema model. This seems to lead to a situation where they define their own validation functions too. Some examples: Django local flavour defines phone number validations for different countries Misc. regular expression validators in Plone&#8217;s Archetypes content type subsystem Every framework define their own email [...]]]></description>
			<content:encoded><![CDATA[<p>All Python ORM and form frameworks love to define own field/schema model. This seems to lead to a situation where they define their own validation functions too.</p>
<p>Some examples:</p>
<ul>
<li><a href="https://docs.djangoproject.com/en/dev/ref/contrib/localflavor/">Django local flavour defines phone number validations for different countries</a></li>
<li><a href="http://svn.plone.org/svn/archetypes/Products.validation/trunk/Products/validation/validators/BaseValidators.py">Misc. regular expression validators in Plone&#8217;s Archetypes content type subsystem</a></li>
<li>Every framework define their own email validator, with various regular expressions</li>
</ul>
<p>Isn&#8217;t writing one&#8217;s own validation code a bit redundant and exactly &#8220;reinventing the wheel&#8221; what open source principles so hard try to avoid? Could validation be a low hanging fruit to share among fellow Python projects? As I see it, for the simple data validation, like email and URL, the core code could be easily shared and different Python projects. You basically want just method is_valid_phonenumber(str) and then framework specific way to raise the error to the user.</p>
<p>Do such frameworks already exist? At least I haven&#8217;t seen one being used in any big Python project yet <img src='http://blog.mfabrik.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>&#8230; or is validation so complex thing, so that validation functions must be tightly integrated with the parent framework and I am missing some big things (like locales, etc.) here?</p>
<p>&nbsp;
<p class="signature">
<a href="http://mfabrik.com/@@zoho-contact-form"><img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/mfabrik-24.png"></a> <a href="http://mfabrik.com/@@zoho-contact-form">Get developers</a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml"><img valign="middle" src="http://www.feedburner.com/fb/images/pub/feed-icon16x16.png" alt="" style="vertical-align:middle;border:0"/></a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml">Subscribe mFabrik blog in a reader</a> <a href="http://twitter.com/mfabrik"> <img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/twitter-24.png"></a> <a href="http://twitter.com/moo9000">Follow me on Twitter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2011/07/07/generic-python-validation-frameworks/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Reducing MySQL memory usage on Ubuntu / Debian Linux</title>
		<link>http://blog.mfabrik.com/2011/03/31/reducing-mysql-memory-usage-on-ubuntu-debian-linux/</link>
		<comments>http://blog.mfabrik.com/2011/03/31/reducing-mysql-memory-usage-on-ubuntu-debian-linux/#comments</comments>
		<pubDate>Thu, 31 Mar 2011 10:56:46 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[plone]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[mtop]]></category>
		<category><![CDATA[ram]]></category>
		<category><![CDATA[res]]></category>
		<category><![CDATA[top]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[virt]]></category>
		<category><![CDATA[virtual memory]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://blog.mfabrik.com/?p=1149</guid>
		<description><![CDATA[If you are running your services on a low end virtual hosting every byte of memory you can save is important. The memory is often the limiting factor of how many applications you can run on VPS: CPUs are shared, memory not, on the same physical host. Low-end VPS come with 512 MB memory or [...]]]></description>
			<content:encoded><![CDATA[<p>If you are running your services on a low end virtual hosting every byte of memory you can save is important. The memory is often the limiting factor of how many applications you can run on VPS: CPUs are shared, memory not, on the same physical host.</p>
<ul>
<li>Low-end VPS come with 512 MB memory or less</li>
<li>Front front-end server Apache / Nginx / Varnish takes &gt; 100 MB +  min. 20 MB for each child process</li>
<li>Memecached takes its toll</li>
<li>MySQL takes 200 &#8211; 400 MB</li>
<li>Each Python / PHP process takes at least 15 MB and you need parallel processes for paraller HTTP requests (FCGI, pre-fork, others&#8230; )</li>
<li>Operating system processes need some memory (SSH, cron, sendmail)</li>
</ul>
<p>As you can see it gets very crowded in 512 MB.</p>
<p>It&#8217;s especially troublesome since the memory is allocated lazily and the memory usage builds up slowly. In some point caches are no longer caches, but swapped to a disk &#8211; virtual memory usage grows beyond available RAM. To keep the server response, everything time critical should fit to RAM once and if the processes themselves don&#8217;t know how to release memory in this situation you need to tune a memory cap for them.</p>
<h2>MySQL memory consumption</h2>
<p>MySQL can be a greedy bastard what comes to memory consumption. Here on this server MySQL seems to take 417M virtual memory which seems to be little excessive for just running two WordPress instances and one Django / Python application:</p>
<pre>1310 mysql     20   0  417M 21100  2776 S  0.0  1.2  0:00.00 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-file=/v</pre>
<p>After some tuning I was able to bring it down a bit</p>
<pre>3354 mysql     20   0  276m  19m 2848 S    0  1.2   3:41.19 mysqld</pre>
<p>A reduction of 130 MB, or 1/4 of the server total memory. Not bad.</p>
<p><a href="http://ubuntu-snippets.blogspot.com/2009/02/mtop-mysql-monitor.html">Use mtop to monitor running MySQL</a>, its querieries, etc. so you know what&#8217;s going on. As you can see this MySQL has very good cache rate meaning that basically it is keeping everything in memory. If the content of the sites is less than 10 MBytes total, 400 MB contains plenty of space to cache the content:</p>
<pre>load average: 0.05, 0.08, 0.16 mysqld 5.0.51a-3ubuntu5.8-log up 1 day(s), 19:47 hrs                                                             
2 threads: 1 running, 6 cached. Queries/slow: 187.1K/0 Cache Hit: 99.39%</pre>
<h2>What eats memory</h2>
<p>I am not an expert on MySQL, so I hope someone with more insight could post comments regarding how to tune MySQL for low memory situations and how it is expected to behave.</p>
<p>Some ideas I run through my head</p>
<ul>
<li>MySQL default cache settings are not too tight on Ubuntu/Debian, making it suitable for moderate loads, not low loads. If you don&#8217;t have much content, everything is just kept in memory (even if not needed)</li>
<li>MySQL uses round robin for connections and if there is 100 max connections it will allocate a thread stack for each connection (someone please confirm this &#8211; I found contracting infos).</li>
</ul>
<h2>Configuring MySQL</h2>
<p>Here are listed some methods how to reduce the memory usage. This is what I done on this little box</p>
<p>MySQL is mostly configured in <em>/etc/mysql/my.cnf</em> on Ubuntu / Debian.</p>
<ul>
<li>Let&#8217;s halve key_buffer from 16M to 8M. <a href="http://dev.mysql.com/doc/refman/5.0/en/myisam-key-cache.html">It is used by MyISAM table cache</a>.</li>
<li>Halve <a href="http://techgurulive.com/2010/10/20/query_cache_size-tuning-optimizing-my-cnf-file-for-mysql/">query_cache_size</a>. query_cache_size  = 8M. Also, decrease query_cache_limit to 512 K.</li>
<li><a href="http://www.mysqlperformanceblog.com/2006/05/17/mysql-server-memory-usage/">Each connection, even if idle, will have 256 KB buffer</a>. Decrease the number of max. connections. (XXX: not sure about this). Drop max connections from 100 -&gt; 30, as we do not have that many concurrent visitors on the site. Also, set less aggressive thread_stack size.</li>
</ul>
<p>The final adjustments</p>
<pre>key_buffer              = 8M
max_connections         = 30
query_cache_size        = 8M
query_cache_limit       = 512K
thread_stack            = 128K</pre>
<h2>More info</h2>
<ul>
<li><a href="http://www.zimbio.com/Linux/articles/692/Fine+Tuning+MYSQL+Reducing+Memory+Usage">Fine-tuning MySQL</a></li>
<li><a href="http://www.electrictoolbox.com/mysql-table-storage-engine/">Showing what database engine MySQL tables are using</a></li>
<li><a href="http://www.mysqlperformanceblog.com/2006/05/17/mysql-server-memory-usage/">MySQL server memory usage</a></li>
<li><a href="http://www.lowendbox.com/blog/reducing-mysql-memory-usage-for-low-end-boxes/">Reducing MySQL memory usage for low end boxes</a></li>
</ul>
<p>Send in more tips please! Is 32-bit better than 64-bit for low end VPS, how much this affects MySQL?
<p class="signature">
<a href="http://mfabrik.com/@@zoho-contact-form"><img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/mfabrik-24.png"></a> <a href="http://mfabrik.com/@@zoho-contact-form">Get developers</a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml"><img valign="middle" src="http://www.feedburner.com/fb/images/pub/feed-icon16x16.png" alt="" style="vertical-align:middle;border:0"/></a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml">Subscribe mFabrik blog in a reader</a> <a href="http://twitter.com/mfabrik"> <img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/twitter-24.png"></a> <a href="http://twitter.com/moo9000">Follow me on Twitter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2011/03/31/reducing-mysql-memory-usage-on-ubuntu-debian-linux/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>When Python sucks: how you call a function and document it</title>
		<link>http://blog.mfabrik.com/2011/03/29/when-python-sucks-how-you-call-a-function-and-document-it/</link>
		<comments>http://blog.mfabrik.com/2011/03/29/when-python-sucks-how-you-call-a-function-and-document-it/#comments</comments>
		<pubDate>Tue, 29 Mar 2011 09:11:38 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[plone]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[epytext]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[zope]]></category>

		<guid isPermaLink="false">http://blog.mfabrik.com/?p=1175</guid>
		<description><![CDATA[Though maybe written tongue-in-cheek, this Python Makes Me Nervous article has some excellent points. Because of duck-typing, you should rigorously document how methods should be called (try epytext and its fields). Most open source Python projects do the exact opposite Even Python standard library is poorly documented and sets a very bad example (missing manual [...]]]></description>
			<content:encoded><![CDATA[<p>Though maybe written tongue-in-cheek, this <a href="http://teddziuba.com/2008/12/python-makes-me-nervous.html">Python Makes Me Nervous article</a> has some excellent points.</p>
<ul>
<li>Because of duck-typing, you should rigorously document how methods should be called (try <a href="http://epydoc.sourceforge.net/epytext.html">epytext</a> and its fields).</li>
<li>Most open source Python projects do the exact opposite</li>
<li>Even Python standard library is poorly documented and sets a very bad example (<a href="http://www.voidspace.org.uk/python/articles/urllib2.shtml">missing manual</a> ???)</li>
<li>Thus, programming in Python becomes nightmare of grepping through source code (the implementation) or stepping into it in pdb just to figure out how APIs should work (<a href="http://collective-docs.plone.org/security/permission_lists.html#listing-different-available-permissions">Plone/Zope,</a> anyone?)</li>
</ul>
<p>Should Python community stop in some point to focus on delivering better documentation instead of focusing on new features and goodies (like the syntax moratorium which was recently lifted)?</p>
<p>﻿﻿From my personal experience</p>
<ul>
<li>The best, and the only, person to document the code adequately is the person how originally wrote it</li>
<li>Because the author already knows how to use the code he doesn&#8217;t need to care about the fact how to enable the code for other users.  Many libraries and projects are driven by &#8220;scratching your own need&#8221; mentality, not by &#8220;let&#8217;s make this a happy community&#8221; mentality. The exception is something like Facebook or Google whose sole purpose is to attract new users their platform bringing in new €€€.</li>
<li>If you are developing a framework or community project make the documentation a requirement for deliverable and stick with it. If you let one person to skip one hour of writing documentation you are making 10 persons spending one hour figuring out how to use the damn thing.</li>
<li>Doctests are not documentation. They are tests. They are extremely unreadable way to say &#8220;how I should use this thing&#8221;, because doctests are often executed in the context of test stubs which do not reflect connections to the other parts of the framework or real contexts.</li>
<li>&#8220;Buy a book &#8211; it tells you everything&#8221; business model is not feasible in long run. Books get old. Books are not searchable. People don&#8217;t buy books.</li>
</ul>
<p>The good documentation is a way to differentiate, and win, in the situation where there are competing frameworks. I believe the success of Django was mostly driven by its good documentation.</p>
<p>This points could be applied to other duck-typed, open source driven programming languages (PHP anyone?). With good documentation we can reduce the need of Valium recipes for everyone of us.</p>
<p>&nbsp;
<p class="signature">
<a href="http://mfabrik.com/@@zoho-contact-form"><img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/mfabrik-24.png"></a> <a href="http://mfabrik.com/@@zoho-contact-form">Get developers</a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml"><img valign="middle" src="http://www.feedburner.com/fb/images/pub/feed-icon16x16.png" alt="" style="vertical-align:middle;border:0"/></a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml">Subscribe mFabrik blog in a reader</a> <a href="http://twitter.com/mfabrik"> <img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/twitter-24.png"></a> <a href="http://twitter.com/moo9000">Follow me on Twitter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2011/03/29/when-python-sucks-how-you-call-a-function-and-document-it/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Apple push notifications (APN) with Python</title>
		<link>http://blog.mfabrik.com/2011/01/29/apple-push-notifications-apn-with-python/</link>
		<comments>http://blog.mfabrik.com/2011/01/29/apple-push-notifications-apn-with-python/#comments</comments>
		<pubDate>Sat, 29 Jan 2011 14:14:39 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[ios]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[plone]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[Android Cloud to Device Messaging (C2DM)]]></category>
		<category><![CDATA[apn]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[apple push notification]]></category>
		<category><![CDATA[atom]]></category>
		<category><![CDATA[bitbucket]]></category>
		<category><![CDATA[bitreader]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[froyo]]></category>
		<category><![CDATA[google cloud push]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://blog.mfabrik.com/?p=942</guid>
		<description><![CDATA[We have created a middleware service which inputs RSS feeds and outputs Apple Push Notification. This allows integrate push notification support for your existing content management system easily. This blog post should give you some ideas if you are planning to create similar services. To have the über-experience of customer engagement with mobile push notifications [...]]]></description>
			<content:encoded><![CDATA[<p>We have created a middleware service which inputs RSS feeds and outputs Apple Push Notification. This allows integrate push notification support for your existing content management system easily. This blog post should give you some ideas if you are planning to create similar services.</p>
<p>To have the über-experience of <em>customer engagement</em> with mobile push notifications you need</p>
<ul>
<li>A mobile application (iOS, Android 2.2)</li>
<li>RSS feed to notifications middleware server (our solution)</li>
<li>RSS feeds themselves</li>
<li>Windows/UNIX server running the middleware</li>
</ul>
<h2>How it is put together</h2>
<p><a href="http://www.tornadoweb.org/">Tornado</a> web server is used to handle incoming HTTP requests in scalable manner.</p>
<p><a href="http://code.google.com/p/feedparser/">feedparser</a> library fetches RSS feeds and processes them to client notifications.</p>
<p>BitReader (<a href="http://blog.mfabrik.com/2010/09/08/bitreader-python-module-for-reading-bits-from-bytes/">post</a>, <a href="https://bitbucket.org/jtoivola/bitreader/wiki/Home">source</a>) library is used to create messages to interact with <a href="http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html">Apple push notification service</a> (APNs). The protocol is bit based protocol running directly over TCP/IP. Apple service has been designed to handle high volumes of traffic &#8211; it does not use anything like stateless HTTP to waste bandwidth.</p>
<p>Django models are used to store the state of each individual subscriber. Django&#8217;s ORM abstraction allows us to use the same middleware for small distributions (&lt; 1000 clients, SQLite database) or big ones (millions of clients, MySQL database). The stored state information includes the subscriber id and the current badge number &#8211; the red circle on the app icon showing the count unread posts. When the application is launched, it can decrease its badge number by doing a HTTP call to the server.</p>
<p>Django settings are used to put together required certificates and whether the application is run in sandbox mode.</p>
<h2>Walkthrough</h2>
<p>There is a core IO loop, running in a separate process, called <em>stream observer</em>. This loops updates fetches RSS feeds&#8217; status and passes updates to Tornado server over HTTP.  With this arrangement, any HTTP capable client can send push notifications.</p>
<p>Tornado handles incoming updates, updates the related subscribe status &#8211; how many unread notifications, etc. through exposed Django views. The notification is formatted according to the variables available on the subscriber mobile platform. In Apple&#8217;s case, the notification message gets title, badge, sound and a launch image. Payload is checked against hard 256 byte limit.</p>
<p>Then the payload is pushed to <a href="http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html">Apple servers</a> over TCP/IP protocol. SSL certificaties needed.</p>
<p>A subscriber is registered  when the mobile application is launched. The application asks a subscriber id from Apple servers. Then, this subscriber id is delivered to our middleware over normal HTTP call.</p>
<p>The middleware also handles feedback service which gives you list of devices which have unsubscribed from your service. This way you can cut off notifications from unsubscribed clients. This is also done using BitReader and TCP/IP.</p>
<h2>Future</h2>
<p>The architecture is built so that different push backends can be included in the service. Android support is on the roadmap and we probably will have Blackberry and Meego support (when/if Nokia announces such a service).</p>
<p>We have currently tested this solution with RSS streams from WordPress and Plone.</p>
<p>We may release source code when it&#8217;s ready.</p>
<h2>More info</h2>
<ul>
<li><a href="http://blog.boxedice.com/2009/07/10/how-to-build-an-apple-push-notification-provider-server-tutorial/">http://blog.boxedice.com/2009/07/10/how-to-build-an-apple-push-notification-provider-server-tutorial/</a></li>
</ul>
<p class="signature">
<a href="http://mfabrik.com/@@zoho-contact-form"><img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/mfabrik-24.png"></a> <a href="http://mfabrik.com/@@zoho-contact-form">Get developers</a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml"><img valign="middle" src="http://www.feedburner.com/fb/images/pub/feed-icon16x16.png" alt="" style="vertical-align:middle;border:0"/></a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml">Subscribe mFabrik blog in a reader</a> <a href="http://twitter.com/mfabrik"> <img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/twitter-24.png"></a> <a href="http://twitter.com/moo9000">Follow me on Twitter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2011/01/29/apple-push-notifications-apn-with-python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Python Interest Group Finland (PIG FI) &#8211; join now</title>
		<link>http://blog.mfabrik.com/2010/08/13/python-interest-group-finland-pig-fi-join-now/</link>
		<comments>http://blog.mfabrik.com/2010/08/13/python-interest-group-finland-pig-fi-join-now/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 09:00:24 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[django]]></category>
		<category><![CDATA[plone]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[finland]]></category>
		<category><![CDATA[sig]]></category>
		<category><![CDATA[user group]]></category>

		<guid isPermaLink="false">http://blog.mfabrik.com/?p=625</guid>
		<description><![CDATA[I have started a mailing list / Google group for Python Finnish community. http://groups.google.com/group/pigfi As far as I know such thing didn&#8217;t exist before. We discussed about the establishment of Python Finnish user group with several Python activists in Sauna Sprint few days ago (the event arranged by EESTEC and Plonistans, mid term report, final [...]]]></description>
			<content:encoded><![CDATA[<p>I have started a mailing list / Google group for Python Finnish community.</p>
<p><a href="http://groups.google.com/group/pigfi">http://groups.google.com/group/pigfi</a></p>
<p>As far as I know such thing didn&#8217;t exist before. We discussed about the establishment of Python Finnish user group with several Python activists in Sauna Sprint few days ago (the event arranged by EESTEC and Plonistans, <a href="http://eestec.net/news-and-offers/plone-sauna-sprint-mid-term-report">mid term</a> report, <a href="http://eestec.net/news-and-offers/plone-sauna-sprint-final-report">final report</a>). There used to exist Plone-related mailing list, but that&#8217;s pretty much dead now. If there are other parallel efforts I am not aware of them, but I really like to merge with the existing work whether it exists. I know at least Nokia, Finnish universities and several small enterprises are very active Python users in Finland.</p>
<p>Our goal is to establish a vibrant, self-sustaining, Python community of Finland. We want to promote the sharing of Python knowledge across organizational borders, the adoption of Python in corporate and hobbyist cultures and have jolly good time with other Python enthusiasts. This probably means discussion (in Finnish), events and  lots of, lots of, sauna. After all, the community will take the shape what suits it for the best, it is not forced externally.</p>
<p>The short term goal is to gather enough participants to have a meaningful community. So, <strong><a href="http://groups.google.com/group/pigfi">Join now!</a></strong>. You can use web interface, email or RSS to follow the discussion. Spread the word to make sure that the message reaches everyone. Tweet it. IRC it. Email it to your friends. SMS it to your parents. Go to streets and cry aloud &#8220;Rakastan Pythonia.&#8221;</p>
<p>For most of us being Python programmer is a choice you have made  or would like to take. Let&#8217;s together create an environment where this choice is fun and will generate great personal wealth for all of us.
<p class="signature">
<a href="http://mfabrik.com/@@zoho-contact-form"><img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/mfabrik-24.png"></a> <a href="http://mfabrik.com/@@zoho-contact-form">Get developers</a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml"><img valign="middle" src="http://www.feedburner.com/fb/images/pub/feed-icon16x16.png" alt="" style="vertical-align:middle;border:0"/></a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml">Subscribe mFabrik blog in a reader</a> <a href="http://twitter.com/mfabrik"> <img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/twitter-24.png"></a> <a href="http://twitter.com/moo9000">Follow me on Twitter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2010/08/13/python-interest-group-finland-pig-fi-join-now/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Applying monkey patches in Django middleware layer</title>
		<link>http://blog.mfabrik.com/2010/08/12/applying-monkey-patches-in-django-middleware-layer/</link>
		<comments>http://blog.mfabrik.com/2010/08/12/applying-monkey-patches-in-django-middleware-layer/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 22:04:19 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[django]]></category>
		<category><![CDATA[plone]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[cufon]]></category>
		<category><![CDATA[decompose]]></category>
		<category><![CDATA[django-cms]]></category>
		<category><![CDATA[fcgi]]></category>
		<category><![CDATA[middleware]]></category>
		<category><![CDATA[monkey patch]]></category>
		<category><![CDATA[normalization]]></category>
		<category><![CDATA[umlaut]]></category>
		<category><![CDATA[unicode]]></category>

		<guid isPermaLink="false">http://blog.mfabrik.com/?p=619</guid>
		<description><![CDATA[Monkey patching is a technique to modify module functions or class methods in Python and other dynamic languages run-time. It differs from the traditional source code patching that it does not need separate utility or compilation process to become effective. This means that you can deploy patches to codebase not under your control with your [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Monkey_patch">Monkey patching</a> is a technique to modify module functions or class methods in Python and other dynamic languages run-time. It differs from the traditional source <a href="http://en.wikipedia.org/wiki/Patch_(Unix)">code patching</a> that it does not need separate utility or compilation process to become effective. This means that you can deploy patches to codebase not under your control with your application without extra effort. Monkey patching has been made famous by <a href="http://plone.org">Plone/Zope</a> community where there is even <a href="http://pypi.python.org/pypi/collective.monkeypatcher">collective.monkeypatcher add-on for managed monkey patching</a>.</p>
<p>Because monkey patches do not need a compilation stage, the patch will work with the future versions of the application, assuming the patched function or method is not changed. So you can &#8220;safely&#8221; update the patched software and the patch will apply to the new version without need to go to command-line to perform some cumbersome commands. However, it is the best practice of open source community to report the bugs and submit the fixing patches, as source code patch, in the corresponding issue trackers.</p>
<p>In Django context, you can use monkey patching to</p>
<ul>
<li>Fix bugs or modify features of Django core without touching the source code</li>
<li>Fix bugs or modify features of Django plug-ins (TinyMCE, filebrowser, Django CMS) without touching the source code</li>
</ul>
<p>Patches are usually applied when Python does module imports. You have a special module called &#8220;monkeypatches.py&#8221; and when that is imported, it applies the patches when the module body level code runs. However, it is difficult to find stable import point in Django to run monkey patching. Django does some really evil magic to initialize INSTALLED_APPS, database models and stuff and doing any kind of work during import causes headache.</p>
<p>So I figured out that you can apply monkey patches using middleware. Middleware applies the monkey patch when the first HTTP request hits the process (note that if you run preforked web server like FCGI every process has its own run-time code in memory). This technique, of course, cannot be used to monkey-patch things that happen before middleware processing, but it is not often needed.</p>
<p>Below is an example how to monkey-patch Django CMS to normalize its unicode output. <a href="http://github.com/sorccu/cufon/issues/issue/133">There was an issue with unicode characters</a> and this is a stop-gap measure to fix it. (I think the proper fix would be fix related <a href="http://cufon.shoqolate.com/generate/">Cufon </a> font renderin Javascript library).</p>
<p>We add our monkey patcher to loaded middleware in settings.py.</p>
<pre>MIDDLEWARE_CLASSES = (
    ...
    'foobar.middleware.FixCufonUnicodeNormalization',
)</pre>
<p>The actual monkey patching happens by fiddling with the class code in process_request(). Note that in this particular case we only need to transform the output of the original function, we can simply hold a reference into it, call it and perform our transformation on the result. This way our monkey patch do not hinder the orignal function and is update safe (it does not matter if the code of PlaceholderNode.render method changes).</p>
<pre>import unicodedata

# Orignal function we monkey-patched away
_orignal_render = None

def _patched_render(self, context):
    """ Normalize all unicode output of Placeholder nodes in Django templates """

    content = _orignal_render(self, context)

    # http://docs.python.org/library/unicodedata.html
    return unicodedata.normalize("NFC", content)

class FixCufonUnicodeNormalization(object):
    """ Fix issue with Cufon, user-generated HTML and unicode decomposed characters.

http://github.com/sorccu/cufon/issues/issue/133

    """ 

    def process_request(self, request):
        """ Install monkey-patch on demand.

        If monkey-patch has not been run in for this process (assuming multiple preforked processes),
        then do it now.

        """
        from cms.templatetags.cms_tags import PlaceholderNode

        global _orignal_render, _patched_render

        if not _orignal_render:
            # replace one of the class's method with own fixed version
            _orignal_render = PlaceholderNode.render
            PlaceholderNode.render = _patched_render</pre>
<p>As far as I know, monkey patching is something PHP cannot do <img src='http://blog.mfabrik.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
<p class="signature">
<a href="http://mfabrik.com/@@zoho-contact-form"><img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/mfabrik-24.png"></a> <a href="http://mfabrik.com/@@zoho-contact-form">Get developers</a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml"><img valign="middle" src="http://www.feedburner.com/fb/images/pub/feed-icon16x16.png" alt="" style="vertical-align:middle;border:0"/></a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml">Subscribe mFabrik blog in a reader</a> <a href="http://twitter.com/mfabrik"> <img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/twitter-24.png"></a> <a href="http://twitter.com/moo9000">Follow me on Twitter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2010/08/12/applying-monkey-patches-in-django-middleware-layer/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Building a mobile site and applications with Django and Python</title>
		<link>http://blog.mfabrik.com/2009/09/30/building-a-mobile-site-and-applications-with-django-and-python/</link>
		<comments>http://blog.mfabrik.com/2009/09/30/building-a-mobile-site-and-applications-with-django-and-python/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 08:46:52 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[pys60]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[apex vertex]]></category>
		<category><![CDATA[augmented reality]]></category>
		<category><![CDATA[bicycling]]></category>
		<category><![CDATA[bilingual]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[browsercontrol]]></category>
		<category><![CDATA[capabilities]]></category>
		<category><![CDATA[darwin]]></category>
		<category><![CDATA[django-cms]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[google maps]]></category>
		<category><![CDATA[gps]]></category>
		<category><![CDATA[handset]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[lbs]]></category>
		<category><![CDATA[localhost]]></category>
		<category><![CDATA[location based]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[media]]></category>
		<category><![CDATA[mobile profile]]></category>
		<category><![CDATA[mod_python]]></category>
		<category><![CDATA[multichannel]]></category>
		<category><![CDATA[multilingual]]></category>
		<category><![CDATA[nokia]]></category>
		<category><![CDATA[oulu]]></category>
		<category><![CDATA[phonegap]]></category>
		<category><![CDATA[premium]]></category>
		<category><![CDATA[print]]></category>
		<category><![CDATA[publishing]]></category>
		<category><![CDATA[rtsp]]></category>
		<category><![CDATA[series 40]]></category>
		<category><![CDATA[series 60]]></category>
		<category><![CDATA[sniffing]]></category>
		<category><![CDATA[streaming]]></category>
		<category><![CDATA[symbiansigned]]></category>
		<category><![CDATA[tourism]]></category>
		<category><![CDATA[traffic statistics]]></category>
		<category><![CDATA[twinapex]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[upnorth]]></category>
		<category><![CDATA[user agent]]></category>
		<category><![CDATA[webkit]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://blog.twinapex.fi/?p=248</guid>
		<description><![CDATA[Recently we created a mobile site for an interactive bicycle tour. oulugo.mobi (you need to use mobile browser to access the site or you&#8217;ll get a redirect) is a multimedia enriched bicycle tour through the historic parts of the city of Oulu. All content is provided by OnGo. The route, which you can bicycle through is [...]]]></description>
			<content:encoded><![CDATA[<p>Recently <a href="http://www.twinapex.com">we</a> created a mobile site for an interactive bicycle tour. <a href="http://oulugo.mobi">oulugo.mobi</a> (you need to use mobile browser to access the site or you&#8217;ll get a redirect) is a multimedia enriched bicycle tour through the historic parts of <a href="http://ouka.fi/english/index.asp">the city of Oulu</a>. All content is provided by <a href="http://www.ongo.fi/en/index.htm">OnGo</a>.</p>
<p>The route, which you can bicycle through is drawn on Google Maps. There are nine  action points where the user can listen to streaming audio clips, with still images, in his/her mobile phone. This is sort of  augmented reality experience: The user sees the real world (where he/she is now bicycling) combined with the historic events (audio playback narrative). For example, at Linnansaari (a location on the route) you&#8217;ll see the actual 17th century castle ruins and the narrator tells how the castle exploded when fire, caused by a lighting, reached gunpowder warehouse&#8230; boom. The explosion caused stones fly over 400 meters.</p>
<p>Alternatively, the clips are available as podcasts from <a href="http://www.oulutourism.fi/oulugo/en_default.aspx">Oulu Tourism pages</a>. You can download them into your iPod for offline listening and use in conjuction with a paper map. This demostrates interesting mix of multichannel publishing: paper, web, mobile and podcasts.</p>
<p>The tour is bilingual in Finnish and English.</p>
<p>There exists unreleased iPhone application, based on <a href="http://phonegap.com">PhoneGap</a>, which allows the user to track his/her location real-time on the web page. We didn&#8217;t see it worth of trouble to go through Apple iPhone application review process. When location based service support comes for the browser this feature is indended to be included as the standard HTML5 feature of the service.</p>
<p>There also exists Nokia Series 60 mobile application, based on<a href="http://wiki.opensource.nokia.com/projects/PyS60"> PyS60</a> and Series 60<a href="http://www.forum.nokia.com/info/sw.nokia.com/id/47d8a7fe-768c-44e5-bc26-fcba0a05e35e/S60_Platform_Browser_Control_API_Guide_v2_0_en.pdf.html"> BrowserControl API</a>, which allows the user to track his/her location in real-time. The application provides wrapper around Series 60 WebKit control and allows Javascript to access phone native functions (GPS) over localhost socket communication. Like with Apple, we didn&#8217;t see real-time tracking feature interesting enough to go through Symbian Signed process to get our application released. Also, BrowserControl had seriousquality problems and we didn&#8217;t consider it stable enough for the end users. <a href="https://code.launchpad.net/~august-joki/pys60community/browsercontrol">Some work is available in PyS60 Community Edition repository</a>.</p>
<p>The service is hosted <a href="http://www.twinapex.com/solutions/outsourcing-hosting-and-maintenance-of-internet-and-mobile-systems">on Python specific virtual server on Twinapex services server farm</a>.</p>
<h2>Features</h2>
<ul>
<li>Premium content tailored for audio listening</li>
<li>Dubbed in English and Finnish by a professional voice actor</li>
<li>Bilingual: English/Finnish</li>
<li>Adapts for smartphones (WebKit based browsers) and low end phones (XHTML mobile profile browsers)</li>
<li>Streaming video and audio (RTSP / progressive HTTP download forv iPhone). Different audio quality is provided on depending on the handset features.</li>
<li>Screen resolution detection based on <a href="http://en.wikipedia.org/wiki/User_Agent">user agent sniffing</a>. Three different version of images are used.</li>
<li>Custom Google Maps component for mobile is used. The component adapts for different mobile phones based on sniffing. Features include zoom, show action point, show the current location, search street address name. This component can be published on a request.</li>
<li>Management interface features include video upload, video transcoding different mobile versions and editing bilingual content</li>
<li><a href="http://www.twinapex.com/products/mobile-publishing/apex-vertex/handset-database">Apex Vertex handset database is used to detect the user&#8217;s mobile phone capabilities</a></li>
<li><a href="http://www.twinapex.com/products/mobile-publishing/apex-vertex/reporting">Apex Vertex logging and traffic analytics capabilities are used for the site statistics</a></li>
</ul>
<h2>Software stack</h2>
<ul>
<li><a href="http://www.ubuntu.com">Ubuntu 8.04 Hardy Heron virtual server</a></li>
<li><a href="http://www.apache.org">Apache 2.2 / mod_python</a></li>
<li><a href="http://python.org">Python 2.5</a></li>
<li><a href="http://djangoproject.com">Django 1.0</a></li>
<li><a href="http://django-cms.org/">Django-CMS 1.0</a></li>
<li><a href="http://code.google.com/p/mobilesniffer/">mobile.sniffer Python package to provide abstraction over different handset databases</a></li>
<li><a href="http://www.twinapex.com/products/mobile-publishing/apex-vertex">Apex Vertex streaming</a> solution (RTSP based on Darwin streaming server by Apple)</li>
<li><a href="http://tinymce.moxiecode.com/">TinyMCE WYSIWYG editor</a></li>
<li><a href="http://developer.apple.com/opensource/server/streaming/index.html">Darwin streaming server</a></li>
<li><a href="http://extjs.com/">ExtJS</a> is extensively used in Apex Vertext management interface</li>
</ul>
<h2>Development effort</h2>
<p>Development time: Around 100 hours. Three different developers where involved. Used development tools: <a href="http://www.eclipse.org">Eclipse</a>, <a href="http://pydev.sourceforge.net/">PyDev</a>, <a href="http://subclipse.tigris.org/">Subclipse</a>, <a href="http://subversion.tigris.org/">Subversion</a>. There were around five meetings between the content provider and the technology provider. Few beta testing rounds using iPhone application were performed by bicycling in -10 celcius degrees weather (north and so on&#8230;). No polar bears were harmed during the creation of this mobile service.</p>
<p>The service is linked in from Oulu Tourism pages and thousands of paper brochures printed for Oulu summer season 2009.</p>
<p><strong style="font-weight: bold;">About the author Mikko Ohtamaa</strong></p>
<ul>
<li><a href="http://www.linkedin.com/in/ohtis  ">LinkedIn</a></li>
<li><a href="http://twitter.com/moo9000">Twitter</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2009/09/30/building-a-mobile-site-and-applications-with-django-and-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Putting views, like sitemap, into Plone content tree using Easy Template add-on</title>
		<link>http://blog.mfabrik.com/2009/07/30/putting-views-like-sitemap-into-plone-content-tree-using-easy-template-add-on/</link>
		<comments>http://blog.mfabrik.com/2009/07/30/putting-views-like-sitemap-into-plone-content-tree-using-easy-template-add-on/#comments</comments>
		<pubDate>Wed, 29 Jul 2009 21:42:29 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[plone]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[browserview]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[jinja]]></category>
		<category><![CDATA[sitemap]]></category>
		<category><![CDATA[template]]></category>
		<category><![CDATA[view]]></category>
		<category><![CDATA[wysiwyg]]></category>

		<guid isPermaLink="false">http://blog.twinapex.fi/?p=235</guid>
		<description><![CDATA[Plone has two kind of pages Content pages which have a path and will appear in the navigation and in the sitemap. These are stored in the database. View based pages and template based pages which usually present an action  (accessibility, sitemap, contact info form). They do not appear in the navigation. They are stored [...]]]></description>
			<content:encoded><![CDATA[<p>Plone has two kind of pages</p>
<ul>
<li>Content pages which have a path and will appear in the navigation and in the sitemap. These are stored in the database.</li>
<li>View based pages and template based pages which usually present an action  (accessibility, sitemap, contact info form). They do not appear in the navigation. They are stored as source code on the file system. You cannot navigate to view based pages and just click edit. To change them you need to use various customization methods (add-on product, Zope management interface) to modify the code.</li>
</ul>
<p>Sometimes it is desirable, for the sake of uniformness, to put view based pages (accessibility, sitemap) into the content tree. For example, one could want to have the sitemap link appearing only in the navigation tree under the site section &#8220;About this site&#8221;.</p>
<p>Plone add-on product <a href="http://plone.org/products/easy-template">Easy Template</a> provides an easy method to show any Plone view(s) on a normal page. Easy Template uses Django like template syntax (<a href="http://jinja.pocoo.org/2/documentation/">Jinja 2 engine</a>). It gives you great power to drop dynamic content easily on pages. Easy Template also has some security awarness ensuring the members using it cannot escape from their sandbox.</p>
<p>Easy Template works in WYSIWYG and non-WYSIWYG modes</p>
<ul>
<li>You can directly mix templates into text in Visual Editor (Kupu). This is mostly useful for non-HTML aware content editors, who use WYSIWYG editor and can use snippets from a reference card prepared by a developer. Note: Visual Editor has some limitations or undesired behavior. Sometimes it tries to put arbitary HTML tags into text (&amp;nbsp; which breaks the template code).</li>
<li>You can write templatized HTML source code in &#8220;raw&#8221; mode. You can write source code on &#8220;Template&#8221; schemata in Edit view.</li>
</ul>
<h2>Example how to show a sitemap on an arbitary Plone page</h2>
<ol>
<li>Install Easy Template (if you are a developer I suggest you to try trunk version)</li>
<li>Create a <em>Templated document</em> content</li>
<li>Write some arbitary text in Kupu</li>
<li>Put in the code snippet <em>{{ view(&#8220;sitemap&#8221;, &#8220;createSiteMap&#8221;) }} </em>which triggers the sitemap view rendering</li>
<li>Save and view the document in View mode</li>
</ol>
<p><img class="alignnone size-full wp-image-238" title="Picture 1" src="http://blog.twinapex.fi/wp-content/uploads/2009/07/Picture-1.png" alt="Picture 1" width="574" height="434" /></p>
<p>It turns out to be:</p>
<p><img class="alignnone size-full wp-image-239" title="Picture 3" src="http://blog.twinapex.fi/wp-content/uploads/2009/07/Picture-3.png" alt="Picture 3" width="496" height="402" /></p>
<p>There is no such thing as a &#8220;views reference&#8221; for Plone. View names and functions can be figured out by searching and reading through ZCML and Python files in Plone source tree. Some developer insight is needed. For example. for sitemap we can do the grep search:</p>
<pre>grep -Ri --include="*.zcml" sitemap *</pre>
<p>Then read <em>Products/CMFPlone/browser/configure.zcml</em> and <em>Products/CMFPlone/browser/sitemap.py</em>.</p>
<p>The same thing works in portlets. Use <em>Templated Portlet </em>portlet type. See <a href="http://pypi.python.org/pypi/collective.easytemplate/">Easy Template PyPi homepage</a> for the full reference of the product&#8217;s potential.</p>
<p><strong>About the author Mikko Ohtamaa</strong></p>
<ul>
<li><a href="http://www.linkedin.com/in/ohtis  ">LinkedIn</a></li>
<li><a href="http://twitter.com/moo9000">Twitter</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2009/07/30/putting-views-like-sitemap-into-plone-content-tree-using-easy-template-add-on/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Userland templates for Plone &#8211; template engine abstraction layer for Python</title>
		<link>http://blog.mfabrik.com/2008/11/09/userland-templates-for-plone-template-engine-abstraction-layer-for-python/</link>
		<comments>http://blog.mfabrik.com/2008/11/09/userland-templates-for-plone-template-engine-abstraction-layer-for-python/#comments</comments>
		<pubDate>Sun, 09 Nov 2008 20:50:13 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[Plone (old)]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[zope]]></category>
		<category><![CDATA[cheetah]]></category>
		<category><![CDATA[content rules]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[engine]]></category>
		<category><![CDATA[kupu]]></category>
		<category><![CDATA[metal]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[tal]]></category>
		<category><![CDATA[tales]]></category>
		<category><![CDATA[template]]></category>

		<guid isPermaLink="false">http://blog.redinnovation.com/?p=146</guid>
		<description><![CDATA[I have been working with collective.easytemplate product which allows users to use template tags on various places on Plone site. Currently supporting Kupu Outgoing email actions (Content rules ones) The users can place ${title}, ${object_url} and other template in the edit mode. These variables which are directly mapped from Archetypes fields when the content is [...]]]></description>
			<content:encoded><![CDATA[<p>I have been working with <a href="http://plone.org/products/easy-template">collective.easytemplate</a> product which allows users to use template tags on various places on Plone site. Currently supporting</p>
<ul>
<li>Kupu</li>
<li>Outgoing email actions (Content rules ones)</li>
</ul>
<p>The users can place ${title}, ${object_url} and other template in the edit mode. These variables which are directly mapped from Archetypes fields when the content is viewed/sent. Also, one can register custom snippet generators like $list_folder_content.</p>
<p>I hope Easy Template to cover some more actions in the future. I have noted PloneFormGen and Singing &amp; Dancing product authors that we could add some mixed in functionality together.</p>
<p>Currently Easy Template uses Cheetah template backend. Cheetah is not Zope security friendly and exposing templated actions should be allowed only to trusted members. I am not huge fan of Plone&#8217;s TAL template language which is based on XML attributes and thus suitable only be used in XML context &#8211; this language is aimed only for hardcore hackers and software designers and ordinary folk really cannot wrap their minds around it.</p>
<p>Because I am not sure which will be the chosen template backend in the future I chose to abstract the template engine layer away. I created <a href="http://pypi.python.org/pypi/collective.templateengines/0.1">collective.templateengines</a> product. It is a bunch of Zope interfaces and utility functions to abstract away common template actions like</p>
<ul>
<li>Applying a template</li>
<li>Adding a template context variables</li>
<li>Registering custom template tags</li>
</ul>
<p>Currently collective.templateengines supports Cheetah and Django templates.</p>
<p>So, dear audience, what do you think of all this? What template engine would you suggest which would be Kupu friendly &#8211; you can edit the template language in WYSIWYG editor? Do you see any other usages for collective.templateengines? Which other projects could adopt template engine abstraction layer?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2008/11/09/userland-templates-for-plone-template-engine-abstraction-layer-for-python/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Python code management &amp; deployment &#8211; a glance at zc.buildout and few others</title>
		<link>http://blog.mfabrik.com/2008/09/02/python-code-management-deployment-a-glance-at-zcbuildout-and-few-others/</link>
		<comments>http://blog.mfabrik.com/2008/09/02/python-code-management-deployment-a-glance-at-zcbuildout-and-few-others/#comments</comments>
		<pubDate>Tue, 02 Sep 2008 08:24:47 +0000</pubDate>
		<dc:creator>Tuukka Mustonen</dc:creator>
				<category><![CDATA[development tools]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[zope]]></category>
		<category><![CDATA[buildout]]></category>
		<category><![CDATA[code management]]></category>
		<category><![CDATA[paver]]></category>
		<category><![CDATA[virtualenv]]></category>
		<category><![CDATA[zc.buildout]]></category>

		<guid isPermaLink="false">http://blog.redinnovation.com/?p=104</guid>
		<description><![CDATA[We&#8217;ve been using zc.buildout for Plone deployment and it&#8217;s working out great. A few days ago implemented a buildout recipe for Django project deployment, automatic web configuration, symlinking, media-folder structuring etc. and while I got it working, I came up with twisted feelings. Buildout is from the creators of Zope (I suppose) so you can [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve been using <a href="http://pypi.python.org/pypi/zc.buildout/1.1.1">zc.buildout</a> for <a href="http://www.plone.org">Plone</a> deployment and it&#8217;s working out great. A few days ago implemented a buildout recipe for <a href="http://www.djangoproject.org">Django</a> project deployment, automatic web configuration, symlinking, media-folder structuring etc. and while I got it working, I came up with twisted feelings.</p>
<p>Buildout is from the creators of <a href="http://www.zope.org/">Zope</a> (I suppose) so you can expect a powerful project code management tool. The question is, however, whether or not it suits your needs. In my case I found out it too heavy. I mean, to add even a simple task you have to create a new &#8220;recipe&#8221; (a package) that does the tricks. Of course some recipes are generic (found from <a href="http://pypi.python.org">PyPi</a>) and you can just run them with your own INI options, but in my case I had to do some custom implementation. Creating a new python package isn&#8217;t that hard for sure <img src='http://blog.mfabrik.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  but there&#8217;s of course some learning curve, so the <em>real</em> question is should you spend time to learn it or not?</p>
<p>I found out that zc.buildout has some nice features like:</p>
<ul>
<li> Automatic requirements processing through setuptools</li>
<li>Automatic (yet simple) removal of directories during recipe uninstall</li>
<li>Clear structure (install(), update() &amp; uninstall() methods)</li>
<li>INI-syntax, python does have a clear syntax but INI is always clearer for a newbie</li>
<li>Easy script creation (adjust python paths somewhat automatically)</li>
<li>Easily repeatable</li>
<li>Passing of arguments from one recipe to another</li>
<li>etc.</li>
</ul>
<p>The problems?</p>
<ul>
<li>It takes a while to learn zc.buildout</li>
<li>It takes &#8216;another while&#8217; to learn to write recipes</li>
<li>Too much hassle for little things</li>
<li>INI-syntax is very limited in features</li>
<li>Buildout easily updates all your packages (that means also the ones you didn&#8217;t want to!)</li>
<li>Lack of documentation (it has good docs to get you going.. but after a while it leaves you with open questions)</li>
<li>Unnecessary overhead (for each script you launch, you&#8217;ll need a launcher script created via buildout)</li>
</ul>
<p>There&#8217;s no denying zc.buildout is powerful, but I wouldn&#8217;t use it for projects which need reasonable amount of customization. It&#8217;s just plain easier and quicker to write shell scripts and while those won&#8217;t provide you with any sort of ready tools you won&#8217;t propably need them. For bringing up somewhat static environment, where you don&#8217;t need to hack things (like that for Plone) it&#8217;s quite a decent option, however.</p>
<p>I also explored alternatives to zc.buildout. I&#8217;ve been reading about earlier virtualenv but haven&#8217;t really tried it out until now. It looks very promising and creates a more flexible environment compared to zc.buildout. Of course their goals are not exactly the same. Also, there are a few other alternatives out there, among them a new Python code management tool called <a href="http://www.blueskyonmars.com/projects/paver/">Paver</a> (just look at that cool logo.. it does remind you of Indiana Jones, does it not?). I glanced through the Paver docs and it looks like it <em>might</em> be the way to go (Paver also supports virtualenv), but didn&#8217;t quite get the grasp of the benefits just yet. Anyway, if you are still interested in code management and deployment, I&#8217;d recommend you to read the <a href="http://www.blueskyonmars.com/2008/04/22/paver-and-the-building-distribution-deployment-etc-of-python-projects/">Paver release announcement</a> and also <a href="http://www.blueskyonmars.com/projects/paver/foreword.html">Paver forewords</a>. They should clear things up.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2008/09/02/python-code-management-deployment-a-glance-at-zcbuildout-and-few-others/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

