<?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>Leong</title>
	<atom:link href="http://www.leong.nl/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.leong.nl</link>
	<description>enjoy life</description>
	<lastBuildDate>Wed, 09 Nov 2011 09:03:19 +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>Plone conference 2011 &#8211; day 2 and 3</title>
		<link>http://www.leong.nl/2011/11/plone-conference-day-2-and-3/</link>
		<comments>http://www.leong.nl/2011/11/plone-conference-day-2-and-3/#comments</comments>
		<pubDate>Wed, 09 Nov 2011 08:36:09 +0000</pubDate>
		<dc:creator>Kim Chee Leong</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Plone]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.leong.nl/?p=297</guid>
		<description><![CDATA[My notes for the second and third day at the Plone conference in San Francisco. How to think in Plone (when those  about you think in Drupal) Dan Jacka Let&#8217;s make switching to Plone easier Plone content is naturally structured, drupal content has nodes indentified by numbers. For Plone lots of content is a prerequisite Confusions [...]]]></description>
			<content:encoded><![CDATA[<p>My notes for the second and third day at the <a href="http://ploneconf.org/">Plone conference in San Francisco</a>.</p>
<p><span style="text-decoration: underline;">How to think in Plone (when those  about you think in Drupal)</span></p>
<p>Dan Jacka</p>
<ul>
<li>Let&#8217;s make switching to Plone easier</li>
<li>Plone content is naturally structured, drupal content has nodes indentified by numbers.</li>
<li>For Plone lots of content is a prerequisite</li>
<li>Confusions when coming from Drupal; content &#8216;lives&#8217; where it appears and restrict locals adds with permission</li>
<li>&#8216;micro components&#8217; are powerful ways to add functionality</li>
<li>Use micro components like dexterity behaviours, <a href="http://plone.org/products/content-lead-image">collective.contentleadimage</a>, <a href="http://pypi.python.org/pypi/collective.watcherlist">collective.watcherlist</a>. Small <wbr>products are good!</wbr></li>
<li>Big products are bad, if you only need to use a part and get unnecessary stuff you don&#8217;t need.</li>
<li>With <a title="ZCA" href="http://pypi.python.org/pypi/zope.component">Zope Component Architecture</a> you <wbr>can override specific parts <wbr>in Plone, like the <wbr>breadcrumbs </wbr></wbr></wbr></li>
<li>Store data; With context use <a href="http://pypi.python.org/pypi/zope.annotation">zope annotations</a> and <a href="http://pypi.python.org/pypi/archetypes.schemaextender">archetypes.schemaextender</a>. <wbr>Without context use plone.app.<wbr>registry, portal_properties <wbr>and local utilities</wbr></wbr></wbr></li>
<li>See:  <a title="http://www.martinaspeli.net/articles/dcworkflows-hidden-gems" href="http://www.martinaspeli.net/articles/dcworkflows-hidden-gems" target="_blank">http://www.martinaspeli.net/<wbr>articles/dcworkflows-hidden-<wbr>gems</wbr></wbr></a></li>
</ul>
<p><span style="text-decoration: underline;">ZODB tips and tricks</span></p>
<p>Carlos de la Guardia</p>
<ul>
<li>See <a href="http://pypi.python.org/pypi/collective.zodbbrowser">collective.zodbbrowser</a> <wbr>Provides access to all objects <wbr>and their attributes</wbr></wbr></li>
<li>Eye is an external tool to <wbr>browse the database, without <wbr>having to install (in buildout)</wbr></wbr></li>
<li>OMG POSKey error: first backup! Fire up debugger, see  <a href="http://plonechix.blogspot.com/2009/12/definitive-guide-to-poskeyerror.html" target="_blank">http://plonechix.blogspot.<wbr>com/2009/12/definitive-guide-<wbr>to-poskeyerror.html</wbr></wbr></a></li>
<li>Get rid of persistent utilities, see <a href="http://pypi.python.org/pypi/wildcard.fixpersistentutilities">wildcard.<wbr>fixpersistentutilities</wbr></a></li>
<li>Always backup first before trying to fix anything!</li>
<li>Restore data / do an undo from data that is deleted a long time ago. Use <a href="http://pypi.python.org/pypi/zc.beforestorage">zc.beforestorage</a>, a wrapper around storage to show site like it was on a certain date</li>
<li><a href="http://pypi.python.org/pypi/RelStorage">RelStorage</a>, drop in replacement for file storage. Designed for high volume sites, multiple zodb instances can share the same database. Starts quickly regardless of db size. Supports undo, packing blobs. Capable of fail-over to replicated databases.</li>
<li><a href="http://pypi.python.org/pypi/zc.zodbactivitylog">Zc.zodbactivitylog</a> (track db actvity), <a href="http://pypi.python.org/pypi/zodbshootout">zodbshootout</a> (benchmarks zeo vs relstorage), <a href="http://pypi.python.org/pypi/zodbupdate">zodbupdate</a> (<wbr>helps you rename classes), <a href="http://pypi.python.org/pypi/dm.historical">dm.<wbr>historical</wbr></a> (get history of <wbr>objects), <a href="http://pypi.python.org/pypi/dm.zodb.repair">dm.zodb.repair</a> (<wbr>restore lost objects)</wbr></wbr></wbr></li>
<li>See <a href="http://pypi.python.org/pypi/Products.ZMIntrospection">Products.ZMIntrospection</a> to look in objects</li>
<li>Use PersistentDict for small amount of items, use OOBTree (and friends) for large amounts</li>
<li>Use BTrees.length instead of len, much faster and avoids conflict <wbr>errors</wbr></li>
<li>Use <a href="http://pypi.python.org/pypi/zc.zlibstorage">zc.zlibstorage</a> for dbs with lots of text, saves 60/70% of storage</li>
<li>Use <a href="http://pypi.python.org/pypi/zc.zodbdgc">zc.zodbgc</a> an inverse graph of db</li>
<li>Increase the ZEO client cache size, when everything is crumbeling around you. When increasing round <wbr>trips to ZODB are increased   </wbr></li>
</ul>
<p>Carlos is writing a book on <wbr>the zodb: <a href="http://zodb.readthedocs.org/en/latest/index.html" target="_blank">http://zodb.<wbr>readthedocs.org/en/latest/<wbr>index.html</wbr></wbr></a> </wbr></p>
<p>&nbsp;</p>
<p><span style="text-decoration: underline;">Mistakes made and lessons learnt</span></p>
<p>Matt Hammilton And Matt Sital-Singh</p>
<ul>
<li>Use case a e-learning system, lot of content, users editing content but not necessary aware of it, lots of clustering of <wbr>load on resources</wbr></li>
<li> 30.000 user accounts, 160.<wbr>000 messages, QA objects etc</wbr></li>
<li>Don&#8217;t create  ghost content. If you need shared content, it can be a good idea to don&#8217;t use subsites but sync the content</li>
<li>Use optimization products. See experimental namespace; queryplan, contentcreation, daterangeindexoptimisations, aggresiveopaquesetup, indexing. Most of them aren&#8217;t <wbr>experimental anymore and are <wbr>included in plone 4.2</wbr></wbr></li>
<li>Lot&#8217;s of answers/questions in catalog. Up to 1.400.000 qa objects. Uhm sql? Or catalog <wbr>multiplex tool, separate <wbr>these objects from main <wbr>catalog.</wbr></wbr></wbr></li>
<li>Pre-load Catalog QueryPlan</li>
<li>Keep things you don&#8217;t need out of the catalog</li>
<li>If you know where something is &#8211; Don&#8217;t search for it. Hardcoding is ok</li>
<li>Use unrestrictedSearchResults if possible, the catalog has a <wbr>lot less work to do</wbr></li>
<li>Maybe should not have used Plone. A lot of the data is relational.</li>
</ul>
<p><span style="text-decoration: underline;">Beginner mistakes. Expert failures</span></p>
<p>Alan Runyan</p>
<p>Beginners:</p>
<ul>
<li>Use logging/sending email or long term persistence for error logs</li>
<li>Don&#8217;t mix dev/stage/prd concept/concerns</li>
<li>Don&#8217;t use directlyProvides or using the ZMI to apply marker interfaces</li>
<li>Do learn the profiler, see collective.stats (how many load/stores per request)</li>
<li>Don&#8217;t attempt to &#8216;normalize&#8217; the model</li>
<li>Willing to claim defeat and backtrack; <wbr>sometimes you simply do</wbr></li>
<li>When beginning development use an alpha, beta or RC. If the project is finished, chances are big a stable version is released.</li>
<li>Don&#8217;t be willing to take pain. Give feedback!</li>
</ul>
<p>Experts:</p>
<ul>
<li>Using components early, not writing reusable code is ok.</li>
<li>Overloading too much functionality in view</li>
<li>Mounting / splitting ZODB in effort to make things faster</li>
<li>Using Plone inappropriately. Security, workflows, staging/versioning, content, add-on components.</li>
<li>See book <a href="http://www.amazon.com/Scalability-Rules-Principles-Scaling-Sites/dp/0321753887" target="_blank">scalability rules</a></li>
<li>Unwilling to thorougly understand tradeoffs between ZODB/RDBMS</li>
<li>Masking over performance problems with caching</li>
</ul>
<p>Check out <a href="http://ploud.com/" target="_blank">ploud</a> and  <a href="https://github.com/ptahproject/ptah" target="_blank">ptah</a> .</p>
<p><a href="http://pypi.python.org/pypi/RelStorage">RelStorage</a> is stable and is used in many production sites. It works with PostgreSQL, MySQL and Oracle. The rationale to <wbr>use it is replication. SQL datbases can do this, the <wbr>ZODB can&#8217;t.</wbr></wbr></p>
]]></content:encoded>
			<wfw:commentRss>http://www.leong.nl/2011/11/plone-conference-day-2-and-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Plone Conference 2011 &#8211; day 1</title>
		<link>http://www.leong.nl/2011/11/plone-conference-2011-day-1/</link>
		<comments>http://www.leong.nl/2011/11/plone-conference-2011-day-1/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 05:17:13 +0000</pubDate>
		<dc:creator>Kim Chee Leong</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Plone]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.leong.nl/?p=286</guid>
		<description><![CDATA[My notes for the first day at the Plone conference in San Francisco. Dextery in the wild David Glick Case study of a complex Dexterity based solution, Net Impact Sales Force integration Membrane is used to represent users as content items. See dexterity.membrane Membrane the ugly: extra catalog with unneeded index Using dexterity with grok saves writing ZCML Content items [...]]]></description>
			<content:encoded><![CDATA[<p>My notes for the first day at the <a href="http://ploneconf.org">Plone conference in San Francisco</a>.</p>
<p><span style="text-decoration: underline;">Dextery in the wild</span></p>
<p>David Glick</p>
<ul>
<li>Case study of a complex <a href="http://pypi.python.org/pypi/plone.app.dexterity">Dexterity</a> based solution, Net Impact</li>
<li>Sales Force integration</li>
<li>Membrane is used to represent users as content items. See <a href="http://pypi.python.org/pypi/collective.salesforce.content">dexterity.membrane</a></li>
<li>Membrane the ugly: extra catalog with unneeded index</li>
<li>Using dexterity with grok saves writing ZCML</li>
<li>Content items are defined in (super) models</li>
<li>Content items have multiple forms with different fields. Auto form can&#8217;t be used, dexterity.EditForm class view is used.</li>
<li>See <em><a href="http://pypi.python.org/pypi/collective.z3cform.datagridfield/">collective.z3cform.datagridfield</a>,</em> <em><a href="http://pypi.python.org/pypi/eea.facetednavigation">eea.facetednavigation</a>, <a href="http://pypi.python.org/pypi/collective.salesforce.content">collective.salesforce.content </a></em> (dexterity behaviour)</li>
<li>Dexterity content types is only used for custom content. Existing content type are modified using schema extender.</li>
</ul>
<p>&nbsp;</p>
<p><span style="text-decoration: underline;">Tsunami proof Plone</span></p>
<p>Adam Terrey</p>
<ul>
<li>Building high available &#8220;web scale&#8221; Plone platform for emergency services</li>
<li>Requirements; scale-ability, multisite, 99,99% reliability</li>
<li>The cloud isn&#8217;t reliable enough</li>
<li>CDNs are used for serving content</li>
<li>Even the slightest amount of caching let&#8217;s Plone &#8216;breathe&#8217; under heavy load</li>
<li>Everything in the hosting stack must be redundant. Expensive!</li>
<li>Datacenter should have multiple backbones</li>
<li>DB redundancy is done with <em><a href="http://pypi.python.org/pypi/RelStorage">relstorage</a></em></li>
<li>Funkload is used for stress testing</li>
</ul>
<p><span style="text-decoration: underline;">Progressive enhancement with wsgi </span></p>
<p>Matthew Wilkes</p>
<ul>
<li>Wsgi is just an API for handeling http requests</li>
<li>Use wsgi as middleware to add functionality to your application</li>
<li>Good wsgi libraries: <a href="http://docs.webob.org/en/latest/index.html">WebOb</a>, makes requests easy to deal with / <a href="http://docs.python.org/library/wsgiref.html">wsgirefWSGI</a> web server is in the std lib</li>
<li>The ZopeSkel equivilent for wsgi: <a href="http://code.google.com/p/wsgitemplates/">wsgitemplates</a></li>
<li>Example captcha&#8217;s, most form libraries have a different way to implement captcha&#8217;s</li>
<li>Uses wsgi middleware to rewrite the form</li>
<li>The backend application has a checkbox to see if the user is human. Middleware inserts a captcha widget. If theform is submitted the middleware checks the captcha input and on valid input the &#8217;is human&#8217; box is checked. On valid captcha input the form is stored, else an error is shown.</li>
<li>Probably overkill, more initial effort but can be easy to apply to customer sites.</li>
<li>Example for how to use wsgi middleware</li>
<li>See <a href="https://github.com/MatthewWilkes/islay.hardercaptcha">islay.simplecaptcha </a>and <a href="https://github.com/MatthewWilkes/islay.simplecaptcha">islay.hardercaptcha</a></li>
</ul>
<p>&nbsp;</p>
<p><span style="text-decoration: underline;">Multiplayer Plone : Realtime collaboration </span></p>
<p>Geir Bækholt</p>
<ul>
<li>Jabber/XMPP protocol is used, realtime and asyn</li>
<li>Presence (status), message, iq (subscription),</li>
<li>Communication not directly thru Plone, but via javascript</li>
<li>Scales to large amount of users</li>
<li>Collaborative writing like Google Docs in ATContent and dexterity</li>
<li>Probably same diff match patch algorithm as in google docs</li>
<li>Future: content notifications, async queues with xmpp in plone, conferencing, video and audio chat.</li>
<li>See<a href="http://www.google.com/url?sa=t&amp;rct=j&amp;q=jarn.xmpp.buildout&amp;source=web&amp;cd=1&amp;ved=0CB4QFjAA&amp;url=https%3A%2F%2Fgithub.com%2Fggozad%2Fjarn.xmpp.buildout&amp;ei=S3KzTtKNK6_HsQLQxLD0Aw&amp;usg=AFQjCNGJcJs8H2rpVoTt4_GBBrcP2R6UTw&amp;sig2=g99rNqX0Udz8mRnyzhNIwg"> jarn.xmpp.buildout </a></li>
</ul>
<p>Killer feature/selling point for intranets and sites with lots of authors.</p>
<p>&nbsp;</p>
<p><span style="text-decoration: underline;">Clone to Plone</span></p>
<p>Adam Terrey</p>
<ul>
<li>How to move from older &#8216;systems&#8217; to Plone. Migrating content, it&#8217;s pretty hard.</li>
<li>Funnelweb <a id="" href="http://plone.org/products/funnelweb" target="_blank">http://plone.org/products/funnelweb</a></li>
<li>A web crawler, uses mr.migrator and transmogrifyer</li>
<li>Buildout, command line or Plone TTW</li>
</ul>
<ul>
<li>Crawler is configurable; ignore regex, drop content using tal, amount of items, ignore robots meta</li>
<li>Crawler saves in cache on disk</li>
<li>Content extraction using xpath</li>
<li>Restructure content, tidy titles</li>
<li>Upload to Plone</li>
</ul>
<ul>
<li>What&#8217;s not converted: dynamic content, front pages, collections, portlets.</li>
<li>Diazo is used to create to look and feel of the old site</li>
<li>Used to migrate big sites, est time to migrate a big site is 3 / 4 days</li>
</ul>
<p>&nbsp;</p>
<p><span style="text-decoration: underline;">Making Plone Mobile using Responsive Web Design</span></p>
<p>Rob Porter</p>
<ul>
<li>Responsive design, geared towards lot&#8217;s of devices (and screen sizes!)</li>
<li>Why design websites for mobile? Because there&#8217;s a huge increase on mobile device usage.</li>
<li>See <a id="" href="http://bostonglobe.com/" target="_blank">http://bostonglobe.com</a> <a id="" href="http://forefathersgroup.com/" target="_blank">http://forefathersgroup.com</a> and make the browser window smaller. The layout changes but content stays the same.</li>
<li>See <a id="" href="http://mediaqueri.es/" target="_blank">http://mediaqueri.es</a></li>
<li>Define a range of screen resolutions with @media, to cater different devices. Each resolution range has an own layout/style/css.</li>
<li>See <em><a href="http://plone.org/products/plonetheme.responsivetheme">plonetheme.responsivetheme</a></em>, makes Plone responsive</li>
<li>Book to buy Responsive Web design &#8211; Ethan Marcotte</li>
<li>First start with smallest screen sizes and then go bigger</li>
</ul>
<p>Creating websites using responsive desgn better than creating specific iDevice, Android, Blackberry apps.</p>
<p><span style="text-decoration: underline;">The future search of Plone</span></p>
<p>Sally Kleinfelt, Hanno Schlichting and someone from six feet up <img src='http://www.leong.nl/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<ul>
<li>Information retrieval</li>
<li>Two search engines ZCatalog and <a href="http://lucene.apache.org/solr/">Solr</a></li>
<li> ZCTextIndex is very simple, TextIndexNG adds multilingual, better parsing, binary transforms, synonyms.</li>
<li>Solr, based on Lucene Java search library. RESTful APIs. Powers twitter and wikipedia. An army of engineers working on it</li>
<li>Solr has way more search features than ZCatalog</li>
<li><a href="http://plone.org/products/collective.solr">Collective.solr</a> and <a href="http://pypi.python.org/pypi/alm.solrindex">alm.solrindex</a> are available add-ons. <a href="http://pypi.python.org/pypi/collective.recipe.solrinstance">Collective.recipe.solrinstance</a> as buildout recipe</li>
<li>Solr indexing is not done transactional, it takes a while before the contt is indexed</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.leong.nl/2011/11/plone-conference-2011-day-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Buildout presentation @ PyGrunn2011</title>
		<link>http://www.leong.nl/2011/06/buildout-presentation-pygrunn2011/</link>
		<comments>http://www.leong.nl/2011/06/buildout-presentation-pygrunn2011/#comments</comments>
		<pubDate>Thu, 30 Jun 2011 20:52:09 +0000</pubDate>
		<dc:creator>Kim Chee Leong</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Plone]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.leong.nl/?p=271</guid>
		<description><![CDATA[Van GW20e nieuws De PyGrunn &#8216;Python and friends&#8217; conferentie is gehouden in Het Paleis in Groningen en is bezocht door ruim 80 personen. ﻿Voorafgaand aan de conferentie was er een masterclass van Armin Ronacher. De conferentie is gericht op de Python programmeertaal en verwante technologie. Met sprekers uit Nederland en het buitenland was de Python-community [...]]]></description>
			<content:encoded><![CDATA[<p>Van <a href="http://www.goldmund-wyldebeast-wunderliebe.com/over-ons/news/pygrunn-2011-een-groot-succes">GW20e nieuws</a></p>
<blockquote><p>De PyGrunn &#8216;Python and friends&#8217; conferentie is gehouden in Het Paleis in Groningen en is bezocht door ruim 80 personen. ﻿Voorafgaand aan de conferentie was er een masterclass van Armin Ronacher. De conferentie is gericht op de Python programmeertaal en verwante technologie. Met sprekers uit Nederland en het buitenland was de Python-community goed vertegenwoordigd op PyGrunn. Vanuit Goldmund, Wyldebeast &#038; Wunderliebe heeft Kim Chee Leong een presentatie gegeven over buildout, dit is een tool voor het uitrollen van applicaties.</p>
<p>Goldmund, Wyldebeast &#038; Wunderliebe en Paylogic hebben de conferentie georganiseerd. Vanwege het grote success zal PyGrunn er ook volgend jaar weer zijn.</p></blockquote>
<div style="width:425px" id="__ss_8039168"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/kaceeleong/buildout-presentation" title="Buildout presentation" target="_blank">Buildout presentation</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/8039168" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/kaceeleong" target="_blank">kaceeleong</a> </div>
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.leong.nl/2011/06/buildout-presentation-pygrunn2011/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Plone content with Google Maps API</title>
		<link>http://www.leong.nl/2010/08/plone-content-with-google-maps-api/</link>
		<comments>http://www.leong.nl/2010/08/plone-content-with-google-maps-api/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 10:00:01 +0000</pubDate>
		<dc:creator>Kim Chee Leong</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Plone]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[maps]]></category>

		<guid isPermaLink="false">http://www.leong.nl/?p=193</guid>
		<description><![CDATA[For Plone there a few Google Maps packages available. I could get any of these working in Plone 4. I ended up writing my own jQuery code that allows setting a location in edit mode and shows the information when you view you view your content. I&#8217;m using the latest Google Maps API v3 for [...]]]></description>
			<content:encoded><![CDATA[<p>For <a href="http://www.plone.org">Plone</a> there a few Google Maps packages available. I could get any of these working in Plone 4. I ended up writing my own jQuery code that allows setting a location in edit mode and shows the information when you view you view your content. I&#8217;m using the latest <a href="http://code.google.com/intl/nl/apis/maps/documentation/javascript/reference.html">Google Maps API v3</a> for geolocation and drawing maps.</p>
<p>This example is applicable to Plone 3 and 4. But the jQuery/Maps API are generic, so if you&#8217;re not interested in the Plone stuff just skip to the jQuery code.<br />
<br/><br />
<img class="size-full wp-image-203 alignnone" title="Select a location" src="http://www.leong.nl/wp-content/screenshot3.png" alt="Selecting a locaiton in Google Maps" width="423" height="377" /></p>
<h2>Use case:</h2>
<ul>
<li>Select a location based on an address or by dragging a marker in the map. Store latitude, longitude and zoom level.</li>
<li>Display a Google Map widget on your content type that show a stored location</li>
</ul>
<h2>Prequisites</h2>
<ul>
<li>You know how to create your custom content type in Plone (if you want to integrate this example in Plone).</li>
<li>Basic javascript/jQuery skills</li>
</ul>
<h2>Getting started</h2>
<h3>Your custom content type</h3>
<p>We want to store the longitude, latitude and zoom level in the content.</p>
<p>Create you own custom content types and add the following fields:</p>
<ul>
<li> longitude and latitude in a string field</li>
<li>zoomLevel in a integer field</li>
</ul>
<h3>Include necessary javascript and CSS</h3>
<p>We are including jQuery. jQuery UI with only the live search function included, this allows direct results when searching for a location. The Google Maps API v3. And some CSS for the map canvas and the live search field.</p>
<p>If you&#8217;re planning to use the jquery libraries from my site, please download the files and host these on your own site.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;script src=&quot;http://www.leong.nl/wp-content/jquery-1.4.2.min_.js&quot; type=&quot;text/javascript&quot;&gt;&lt;!--mce:0--&gt;&lt;/script&gt;
&nbsp;
&lt;script src=&quot;http://www.leong.nl/wp-content/jquery-ui-1.8.1.custom.min_.js&quot; type=&quot;text/javascript&quot;&gt;&lt;!--mce:1--&gt;&lt;/script&gt;
&nbsp;
&lt;script src=&quot;http://maps.google.com/maps/api/js?sensor=false&quot; type=&quot;text/javascript&quot;&gt;&lt;!--mce:2--&gt;&lt;/script&gt;
&nbsp;
&lt;style type=&quot;text/css&quot;&gt;
#map_canvas {        
  width: 650px;    
  height: 500px;        
  margin-bottom: 2em;  
} 
&nbsp;
.ui-autocomplete  {        
  background-color: white;       
  width: 300px;        
  border: 1px solid #cfcfcf;        
  list-style-type: none;        
  padding-left: 0px;        
  cursor: pointer; 
}  
&lt;/style&gt;</pre></div></div>

<h3>The Google Maps jQuery code</h3>
<p>This is jQuery code for displaying and selecting locations in Google Maps. Most of the Maps API code used in this example comes from <a title="Geocode with Google Maps API v3" href="http://tech.cibul.org/geocode-with-google-maps-api-v3/">this article on cibul.org</a>. The article has a good explanation how the Maps API works.</p>
<p>Short explanation on the code below. The inserting of the Maps and search field is all done in javascript code. Without this code you can still save or view the lat/long coordinates. Based on editing or viewing content different functions are called.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">&nbsp;
<span style="color: #006600; font-style: italic;">// based on: http://tech.cibul.org/geocode-with-google-maps-api-v3/</span>
<span style="color: #006600; font-style: italic;">// replace jq with $ character if you're using this code outside Plone</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> DEFAULT_LATITUDE <span style="color: #339933;">=</span> <span style="color: #CC0000;">53.21310</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> DEFAULT_LONGITUDE <span style="color: #339933;">=</span> <span style="color: #CC0000;">5.71713</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> DEFAULT_ZOOM_LEVEL <span style="color: #339933;">=</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> ploneMaps <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">/**
     *  Show the map based on saved location
     */</span>
    googleMapsView<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>message<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#archetypes-fieldname-latitude'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#archetypes-fieldname-longitude'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#archetypes-fieldname-zoomLevel'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #003366; font-weight: bold;">var</span> html <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&lt;label&gt;Location:&lt;/label&gt;&lt;br/&gt;&quot;</span><span style="color: #339933;">;</span>
        html <span style="color: #339933;">+=</span> <span style="color: #3366CC;">&quot;&lt;div id='map_canvas'&gt;&lt;/div&gt;&quot;</span><span style="color: #339933;">;</span>
        jq<span style="color: #009900;">&#40;</span>html<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">insertBefore</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#archetypes-fieldname-latitude'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #003366; font-weight: bold;">var</span> longitude <span style="color: #339933;">=</span> parseFloat<span style="color: #009900;">&#40;</span>jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#parent-fieldname-longitude&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003366; font-weight: bold;">var</span> latitude <span style="color: #339933;">=</span> parseFloat<span style="color: #009900;">&#40;</span>jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#parent-fieldname-latitude&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003366; font-weight: bold;">var</span> zoom <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#parent-fieldname-zoomLevel&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        ploneMaps.<span style="color: #660066;">googleMapsDraw</span><span style="color: #009900;">&#40;</span>longitude<span style="color: #339933;">,</span> latitude<span style="color: #339933;">,</span> zoom<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #006600; font-style: italic;">/**
     *  Show the saved location or starting point.
     *  Set-up a search widget for address geocoding
     */</span>
    googleMapsEdit<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>message<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#archetypes-fieldname-latitude'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#archetypes-fieldname-longitude'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#archetypes-fieldname-zoomLevel'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #006600; font-style: italic;">// create search field</span>
        <span style="color: #003366; font-weight: bold;">var</span> html <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&lt;div class='field' id='google-map-search'&gt;&quot;</span><span style="color: #339933;">;</span>
        html <span style="color: #339933;">+=</span> <span style="color: #3366CC;">&quot;&lt;label for='map-search'&gt;Location&lt;/label&gt;&quot;</span><span style="color: #339933;">;</span>
        html <span style="color: #339933;">+=</span> <span style="color: #3366CC;">&quot;&lt;div class='formHelp'&gt;Use the marker to select a location &quot;</span><span style="color: #339933;">;</span>
        html <span style="color: #339933;">+=</span> <span style="color: #3366CC;">&quot;or search field to select a location.&lt;/div&gt;&quot;</span><span style="color: #339933;">;</span>
        html <span style="color: #339933;">+=</span> <span style="color: #3366CC;">&quot;&lt;input name='map-search' type='text' size='45'&gt;&lt;/input&gt;&quot;</span><span style="color: #339933;">;</span>
        html <span style="color: #339933;">+=</span> <span style="color: #3366CC;">&quot;&lt;div id='map_canvas'&gt;&lt;/div&gt;&quot;</span><span style="color: #339933;">;</span>
        html <span style="color: #339933;">+=</span> <span style="color: #3366CC;">&quot;&lt;/div&gt;&quot;</span><span style="color: #339933;">;</span>
&nbsp;
        jq<span style="color: #009900;">&#40;</span>html<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">insertBefore</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#archetypes-fieldname-latitude'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #006600; font-style: italic;">// no form submit when an enter is given in search field</span>
        jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#google-map-search'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">keypress</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
           <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>e.<span style="color: #660066;">which</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">13</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
               e.<span style="color: #660066;">preventDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
           <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #006600; font-style: italic;">// save zoomlevel on submit</span>
        jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'form#plaats-base-edit'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">submit</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
           jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#zoomLevel&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span>map.<span style="color: #660066;">getZoom</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #006600; font-style: italic;">// saved location</span>
        <span style="color: #003366; font-weight: bold;">var</span> latitude <span style="color: #339933;">=</span> jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#latitude'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003366; font-weight: bold;">var</span> longitude <span style="color: #339933;">=</span> jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#longitude'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003366; font-weight: bold;">var</span> zoomLevel <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#zoomLevel'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #006600; font-style: italic;">// use default location if nothing is saved</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>latitude <span style="color: #339933;">||</span> <span style="color: #339933;">!</span>longitude<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            latitude <span style="color: #339933;">=</span> DEFAULT_LATITUDE<span style="color: #339933;">;</span>
            longitude <span style="color: #339933;">=</span> DEFAULT_LONGITUDE<span style="color: #339933;">;</span>
            zoomLevel <span style="color: #339933;">=</span> DEFAULT_ZOOM_LEVEL<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #003366; font-weight: bold;">var</span> data <span style="color: #339933;">=</span> ploneMaps.<span style="color: #660066;">googleMapsDraw</span><span style="color: #009900;">&#40;</span>longitude<span style="color: #339933;">,</span> latitude<span style="color: #339933;">,</span> zoomLevel<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003366; font-weight: bold;">var</span> map <span style="color: #339933;">=</span> data<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #003366; font-weight: bold;">var</span> markerObj <span style="color: #339933;">=</span> data<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
        ploneMaps.<span style="color: #660066;">googleMapsHelper</span><span style="color: #009900;">&#40;</span>map<span style="color: #339933;">,</span> markerObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #006600; font-style: italic;">/**
     * Draw the location based on specific parameters
     */</span>
    googleMapsDraw<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>longitude<span style="color: #339933;">,</span> latitude<span style="color: #339933;">,</span> zoomLevel<span style="color: #339933;">,</span> marker<span style="color: #339933;">,</span> drag<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> map <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>isNaN<span style="color: #009900;">&#40;</span>longitude<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>isNaN<span style="color: #009900;">&#40;</span>latitude<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #003366; font-weight: bold;">var</span> location <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> google.<span style="color: #660066;">maps</span>.<span style="color: #660066;">LatLng</span><span style="color: #009900;">&#40;</span>latitude<span style="color: #339933;">,</span> longitude<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #003366; font-weight: bold;">var</span> myOptions <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
              zoom<span style="color: #339933;">:</span> zoomLevel<span style="color: #339933;">,</span>
              center<span style="color: #339933;">:</span> location<span style="color: #339933;">,</span>
              mapTypeId<span style="color: #339933;">:</span> google.<span style="color: #660066;">maps</span>.<span style="color: #660066;">MapTypeId</span>.<span style="color: #660066;">ROADMAP</span>
            <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
            map <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> google.<span style="color: #660066;">maps</span>.<span style="color: #660066;">Map</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;map_canvas&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> myOptions<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>marker<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                marker  <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> google.<span style="color: #660066;">maps</span>.<span style="color: #660066;">Marker</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>position<span style="color: #339933;">:</span> location<span style="color: #339933;">,</span> map<span style="color: #339933;">:</span> map<span style="color: #339933;">,</span> draggable<span style="color: #339933;">:</span> drag<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#91;</span>map<span style="color: #339933;">,</span> marker<span style="color: #009900;">&#93;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #006600; font-style: italic;">/**
     * Helper function, ajax address search and marker event listener
     */</span>
    googleMapsHelper<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>map<span style="color: #339933;">,</span> marker<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">//GEOCODER</span>
        geocoder <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> google.<span style="color: #660066;">maps</span>.<span style="color: #660066;">Geocoder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #006600; font-style: italic;">// Form auto completion</span>
        jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;input[name='map-search']&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">autocomplete</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> 
            <span style="color: #006600; font-style: italic;">//This bit uses the geocoder to fetch address values</span>
            source<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>request<span style="color: #339933;">,</span> response<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                geocoder.<span style="color: #660066;">geocode</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'address'</span><span style="color: #339933;">:</span> request.<span style="color: #660066;">term</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'region'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'NL'</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>results<span style="color: #339933;">,</span> <span style="color: #000066;">status</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                  response<span style="color: #009900;">&#40;</span>jq.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span>results<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span>
                      label<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">formatted_address</span><span style="color: #339933;">,</span>
                      value<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">formatted_address</span><span style="color: #339933;">,</span>
                      latitude<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">geometry</span>.<span style="color: #660066;">location</span>.<span style="color: #660066;">lat</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                      longitude<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">geometry</span>.<span style="color: #660066;">location</span>.<span style="color: #660066;">lng</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
                    <span style="color: #009900;">&#125;</span>
                  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
            <span style="color: #006600; font-style: italic;">// This bit is executed upon selection of an address</span>
            select<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #339933;">,</span> ui<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#latitude&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span>ui.<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">latitude</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#longitude&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span>ui.<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">longitude</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #003366; font-weight: bold;">var</span> location <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> google.<span style="color: #660066;">maps</span>.<span style="color: #660066;">LatLng</span><span style="color: #009900;">&#40;</span>ui.<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">latitude</span><span style="color: #339933;">,</span> ui.<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">longitude</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                marker.<span style="color: #660066;">setPosition</span><span style="color: #009900;">&#40;</span>location<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                map.<span style="color: #660066;">setCenter</span><span style="color: #009900;">&#40;</span>location<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                map.<span style="color: #660066;">setZoom</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">11</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #006600; font-style: italic;">// Reverse Geocoding, when the marker is being dragged on the map update the fields.</span>
        google.<span style="color: #660066;">maps</span>.<span style="color: #660066;">event</span>.<span style="color: #660066;">addListener</span><span style="color: #009900;">&#40;</span>marker<span style="color: #339933;">,</span> <span style="color: #3366CC;">'drag'</span><span style="color: #339933;">,</span>  <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            geocoder.<span style="color: #660066;">geocode</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'latLng'</span><span style="color: #339933;">:</span> marker.<span style="color: #660066;">getPosition</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>results<span style="color: #339933;">,</span> <span style="color: #000066;">status</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
              <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066;">status</span> <span style="color: #339933;">==</span> google.<span style="color: #660066;">maps</span>.<span style="color: #660066;">GeocoderStatus</span>.<span style="color: #660066;">OK</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>results<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                  jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;input[name='map-search']&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span>results<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">formatted_address</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                  jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#latitude&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span>marker.<span style="color: #660066;">getPosition</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">lat</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                  jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#longitude&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span>marker.<span style="color: #660066;">getPosition</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">lng</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
              <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
jq<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// match this jquery selector on the view template of your content type</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body.template-plaats_view.portaltype-plaats'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">length</span> <span style="color: #339933;">&gt;=</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        ploneMaps.<span style="color: #660066;">googleMapsView</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #006600; font-style: italic;">// match this jquery selector on the edit template of your content type</span>
    <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>jq<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body.template-base_edit.portaltype-plaats'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">length</span> <span style="color: #339933;">&gt;=</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        ploneMaps.<span style="color: #660066;">googleMapsEdit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.leong.nl/2010/08/plone-content-with-google-maps-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zope import/export in Plone, not a good idea&#8230;</title>
		<link>http://www.leong.nl/2010/08/zope-importexport-in-plone-not-a-good-idea/</link>
		<comments>http://www.leong.nl/2010/08/zope-importexport-in-plone-not-a-good-idea/#comments</comments>
		<pubDate>Tue, 03 Aug 2010 09:59:25 +0000</pubDate>
		<dc:creator>Kim Chee Leong</dc:creator>
				<category><![CDATA[Plone]]></category>
		<category><![CDATA[ArchivistUnregisteredError]]></category>
		<category><![CDATA[CMFEditions]]></category>
		<category><![CDATA[zope]]></category>

		<guid isPermaLink="false">http://www.leong.nl/?p=197</guid>
		<description><![CDATA[For a Plone portal I needed to restore a deleted folder. The deleted folder was not found in the undo tab, so I decided to use Zope import/export functionality with the binary ZEXP format. I exported a ZEXP file from a back-up using the import/export tab in the ZMI. On the Plone instance I imported [...]]]></description>
			<content:encoded><![CDATA[<p>For a Plone portal I needed to restore a deleted folder. The deleted folder was not found in the undo tab, so I decided to use Zope import/export functionality with the binary ZEXP format. I exported a ZEXP file from a back-up using the import/export tab in the ZMI. On the Plone instance I imported the ZEXP export to restore the folder.</p>
<p>This was not a good solution for restoring specific items because the version history was broken/corrupt for all items. Saving an item that was restored the following exception was shown: &#8220;<em>ArchivistUnregisteredError: The object &#8230;</em>&#8220;. When accessing the history this error was shown &#8220;<em>AttributeError: &#8216;list&#8217; object has no attribute &#8216;getLength&#8217;</em>&#8220;.</p>
<p>The solution was resetting the version history using the CMFEditions tool. You can reset the version history for an item this way:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">hist = getToolByName(context, 'portal_archivist')
prepared =  hist.prepare(obj)
hist.register(prepared)</pre></div></div>

<p>This solved the ArchivistUnregisteredError for me.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leong.nl/2010/08/zope-importexport-in-plone-not-a-good-idea/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hardening Debian Linux</title>
		<link>http://www.leong.nl/2010/03/hardening-debian-linux/</link>
		<comments>http://www.leong.nl/2010/03/hardening-debian-linux/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 15:12:39 +0000</pubDate>
		<dc:creator>Kim Chee Leong</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[debian ubuntu sysadmin security]]></category>

		<guid isPermaLink="false">http://www.leong.nl/?p=166</guid>
		<description><![CDATA[Last updated: 9 November 2010 Here are a few tips for hardening your Debian/Ubuntu server. SSH key based authentication Only allow logins using public SSH keys. This way we prevent brute force attacks. Create private and public keys using the ssh-keygen command. First copy the public key from your pc to the server using: $ [...]]]></description>
			<content:encoded><![CDATA[<p><em>Last updated: 9 November 2010</em><br />
</p>
<p>Here are a few tips for hardening your Debian/Ubuntu server.</p>
<h2>SSH key based authentication</h2>
<p>Only allow logins using public SSH keys. This way we prevent brute force attacks. Create private and public keys using the <em>ssh-keygen</em> command. First copy the public key from your pc to the server using:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ ssh-copy-id <span style="color: #660033;">-i</span> .ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa.pub user<span style="color: #000000; font-weight: bold;">@</span>host</pre></div></div>

<p>Test if you can login with your public key. The public key is stored in <em>.ssh/authorized_keys</em>. So if you add a new user ask them their pub key and copy this into authorized keys.</p>
<p>Change <em>/etc/sshd_config</em> to disable password based logins:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ChallengeResponseAuthentication no
PasswordAuthentication no</pre></div></div>

<h2>Filesystem permissions</h2>
<p>The default user permission has umask 022 where other/world user also have access. Using umask 007 the owner en group has rw access, other/world hasn&#8217;t got any access.</p>
<p>Change default umask 022 to 007:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>profile
<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>login.defs
<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>rc</pre></div></div>

<h2>Mounted volumes must have proper permissions</h2>
<p>Add two mount options in <em>/etc/fstab</em> for partitions that have no suid programs and no device nodes. Options are called nosuid and nodev.</p>
<p>Example:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sda5       <span style="color: #000000; font-weight: bold;">/</span>tmp            ext3    defaults,nosuid,nodev        <span style="color: #000000;">0</span>       <span style="color: #000000;">2</span>
<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sda6       <span style="color: #000000; font-weight: bold;">/</span>var            ext3    defaults,nosuid,nodev        <span style="color: #000000;">0</span>       <span style="color: #000000;">2</span>
<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sda7       <span style="color: #000000; font-weight: bold;">/</span>data2          ext3    defaults,nosuid,nodev        <span style="color: #000000;">0</span>       <span style="color: #000000;">2</span></pre></div></div>

<h2>Dedicated group for su</h2>
<p>Only allow users in adm group to become root using pam_wheel.</p>
<p>In /etc/pam.d/su uncomment this line and add group part.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">auth       required   pam_wheel.so <span style="color: #007800;">group</span>=adm</pre></div></div>

<p>Add sysadmins to adm group</p>
<pre>usermod -a -G adm [username]
</pre>
<h2>Separate temp directories for users</h2>
<p>Using pam tmpdir modules each user has a separate tmp dir. So instead of using /tmp for everyone, each user gets a /tmp/user/USERID directory. A user cannot see the temp files of other users.</p>
<p>Install the tmpdir pam module:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> libpam-tmpdir</pre></div></div>

<p>Add the following line to <em>/etc/pam.d/common-session</em></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">session    optional     pam_tmpdir.so</pre></div></div>

<h2>Know when security updates are available</h2>
<p>Keep the packages on the server up to date. Use the mail* to  functionality in crontab to get a automated warning when an update is  available. It saves the hassle for checking manually. It&#8217;s not recommended to run the updates unattended.</p>
<p>Add this script in <em>/usr/local/bin/check_security.sh</em></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> update <span style="color: #660033;">-qq</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt; <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">1</span>
&nbsp;
<span style="color: #007800;">LISTFILE</span>=<span style="color: #007800;">$TMP</span><span style="color: #000000; font-weight: bold;">/</span>check_security.lock
<span style="color: #007800;">UPGRADE_CMD</span>=<span style="color: #ff0000;">&quot;apt-get upgrade -qq -s&quot;</span>
<span style="color: #007800;">MACHINE</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">hostname</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">LIST</span>=<span style="color: #ff0000;">&quot;&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> package <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">`</span><span style="color: #007800;">$UPGRADE_CMD</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'^Inst'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{ print $2 }'</span><span style="color: #000000; font-weight: bold;">`</span>;
<span style="color: #000000; font-weight: bold;">do</span>
  <span style="color: #007800;">LIST</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$LIST</span> <span style="color: #007800;">$package</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$LIST</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-e</span> <span style="color: #007800;">$LISTFILE</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-f</span> <span style="color: #007800;">$LISTFILE</span>
  <span style="color: #000000; font-weight: bold;">fi</span>
  <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span>
<span style="color: #000000; font-weight: bold;">else</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-e</span> <span style="color: #007800;">$LISTFILE</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$LIST</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt; <span style="color: #007800;">$LISTFILE</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Please run security updates on <span style="color: #007800;">${MACHINE}</span>!&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;==========================================&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$LIST</span>
  <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>Add the script to crontab for root user.  Enter your e-mail address in the mailto variable. Add the script to crontab. Check each hour is an update is available:</p>
<pre>MAILTO='me@domain.com'
5 * * * * /usr/local/bin/check_security.sh</pre>
<p>Install the nullmailer and  mailutils package to allow mail relaying. Enter the hostname and smtp server in install dialog.</p>
<pre>apt-get install nullmailer mailutils</pre>
<h2>Clean old files/dirs in temp directory</h2>
<p>Remove files and directories older than 30 days. The tmp dir is for temporary files!</p>
<p>Add a shell script in /usr/local/bin/clean_tmp.sh</p>
<pre>#!/bin/bash
# GW20e - KC
# Clean tmp directory, we don't want files/dirs older
# than 30 days.
find /tmp/* -type f -mtime +30 -exec rm -f {} \;
find /tmp/* -type d -mtime +30 -exec rm -rf {} \;
</pre>
<p>Add the script in crontab so it&#8217;s executed every night:</p>
<pre>0  5 * * * /usr/local/bin/clean_tmp.sh &gt; /dev/null</pre>
<h2>Only a minimal set of network services must be provided</h2>
<p>Only run the network services that are needed. Each service can bring in a security risk. Configure the network services so they only listen on specific interfaces.<br />
Run netstat to check which service is listening on what interface. Example:</p>
<pre>server:~# netstat -nlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 91.194.xxx.xxx:18080    0.0.0.0:*               LISTEN      9544/python2.6
tcp        0      0 91.194.xxx.xxx:5666     0.0.0.0:*               LISTEN      3515/nrpe
tcp        0      0 127.0.0.1:111           0.0.0.0:*               LISTEN      9035/portmap
tcp        0      0 192.168.3.45:8080       0.0.0.0:*               LISTEN      3876/python2.6
tcp        0      0 192.168.3.45:28080      0.0.0.0:*               LISTEN      3875/python2.6
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3714/apache2
tcp        0      0 192.168.3.45:8081       0.0.0.0:*               LISTEN      3877/python2.6
tcp        0      0 192.168.3.45:22         0.0.0.0:*               LISTEN      3505/sshd
tcp        0      0 127.0.0.1:761           0.0.0.0:*               LISTEN      3553/famd
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      3714/apache2
udp        0      0 127.0.0.1:111           0.0.0.0:*                           9035/portmap</pre>
<p>Disable network services or bind  the service to a specific interface. Normally portmap is listening on all interfaces.</p>
<h3>Bind portmap to localhost loopback</h3>
<p>In the above example portmap is only listening on the localhost loopback. Bind the portmap service to localhost, edit &#8221;/etc/default/portmap&#8221;. Uncomment this line:</p>
<pre>OPTIONS="-i 127.0.0.1"</pre>
<h3>Disable IPv6</h3>
<p>If you&#8217;re not using IPv6, disable it to prevent possible vulnerabilities. Add the following file /etc/modprobe.d/00local</p>
<pre>alias net-pf-10 off
alias ipv6 off
</pre>
<h2>Apache webserver</h2>
<p>Don&#8217;t allow directory indexes by disabling autoindex module</p>
<pre>a2dismod autoindex
/etc/init.d/apache2 restart</pre>
<p>Apache has a separte config file for security. Edit /etc/apache2/conf.d/security and change the following settings:</p>
<pre># Don't give away info about OS and compiled in modules
ServerTokens Prod
# Don't show server version in server-generated pages
ServerSignature Off
# Disables HTTP trace, only used for debuging purposes. Potential security vulnerability.
TraceEnable Off</pre>
<p>This article has good tips for securing the Apache webserver: <a title="Apache security tips" href="http://www.ducea.com/2006/06/08/apache-tips-tricks/">MDLog:/sysadmin &#8211; Apache Tips &amp; Tricks</a>.</p>
<h2>Do a security audit for the system</h2>
<p><a title="lynis security audit" href="http://rootkit.nl/projects/lynis.html">Lynis</a> is an excellent tool to audit the system. Download the latest tarball, decompress and run. Lynis is an auditing tool which tests and gathers (security) information for *nix based systems.</p>
<p>If you want to be on the safe side, and be sure your server is secure, hire an independent company for a security audit.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leong.nl/2010/03/hardening-debian-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cloud storage</title>
		<link>http://www.leong.nl/2009/12/cloud-storage/</link>
		<comments>http://www.leong.nl/2009/12/cloud-storage/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 21:18:20 +0000</pubDate>
		<dc:creator>Kim Chee Leong</dc:creator>
				<category><![CDATA[cloud]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[storage]]></category>
		<category><![CDATA[cloud amazon s3 storage dropbox]]></category>

		<guid isPermaLink="false">http://www.leong.nl/?p=147</guid>
		<description><![CDATA[There are many services to store your data online. I&#8217;m using Dropbox to store and exchange files with others. It&#8217;s a pretty good online storage service with a client to sync the files. But with this and with similar (free) services you a have limited amount of storage. You can pay for the extra space [...]]]></description>
			<content:encoded><![CDATA[<p>There are many services to store your data online. I&#8217;m using <a title="Dropbox online storage" href="http://www.dropbox.com">Dropbox </a>to store and exchange files with others. It&#8217;s a pretty good online storage service with a client to sync the files. But with this and with similar (free) services you a have limited amount of storage. You can pay for the extra space but there&#8217;s a better and cheaper way to storing your files in the cloud.</p>
<h2>Amazon S3 storage</h2>
<p>Amazon is offering a wide array of cloud services. The storage service is called <a title="Amazon S3, Simple Storage Service" href="http://aws.amazon.com/s3/">Amazon S3</a> (simple storage services). The storage is really cheap, approximately  $0.15 per GB/month for storage and $0.10 GB/month for data transfer. Dropbox and <a title="Online storage for Ubuntu Linux" href="http://one.ubuntu.com">Ubuntu One</a> are using S3 as storage facility, Twitter and Slideshare are using S3 to host images.</p>
<p>Using S3 as online storage isn&#8217;t that hard, it takes a bit more effort than using a service like Dropbox. But you&#8217;ll get unlimited storage for a bargain. Amazon isn&#8217;t offering a client to mount S3 storage on your computer. It provides an interface for developers, allowing connection to the storage. Luckily others have done the heavy lifting and there is software available to use the S3 storage on your computer. I don&#8217;t know the specific clients for Mac or Windows, google is your friend. I&#8217;m using <a title="Command line Amazon S3 client to mount the storage" href="http://code.google.com/p/s3fs/wiki/FuseOverAmazon">FuseOverAmazon</a> (<a title="S3fs fork allow to mount european S3 bucket" href="http://github.com/tractis/s3fs-fork">this specific fork for EU buckets</a>) on Ubuntu Linux.</p>
<p>So <a href="http://aws.amazon.com/s3/">sign up</a> for Amazon S3 and do some googling which client you need for your operating system. Now I only need a faster internet connection so I don&#8217;t have to wait when uploading gigabytes of photo&#8217;s to S3!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leong.nl/2009/12/cloud-storage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Plone Conference 2009 &#8211; Hardening Plone</title>
		<link>http://www.leong.nl/2009/10/plone-conference-2009/</link>
		<comments>http://www.leong.nl/2009/10/plone-conference-2009/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 14:17:38 +0000</pubDate>
		<dc:creator>Kim Chee Leong</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Plone]]></category>

		<guid isPermaLink="false">http://www.leong.nl/?p=137</guid>
		<description><![CDATA[This year I&#8217;m attending the Plone Conference 2009 in Budapest. Today is the second day and as always with Plone conferences the vibe is great and it&#8217;s interesting to see the different talks. Together with my collegue Kees Hink we gave a presentation about Hardening Plone. For a customer who needed a DMS to exchange [...]]]></description>
			<content:encoded><![CDATA[<p>This year I&#8217;m attending the <a title="Plone Conference 2009 - Budapest" href="http://temp.ploneconf2009.org/">Plone Conference 2009</a> in Budapest. Today is the second day and as always with Plone conferences the vibe is great and it&#8217;s interesting to see the different talks.</p>
<p>Together with my collegue <a title="Blog Kees Hink" href="http://keeshink.blogspot.com/">Kees Hink</a> we gave a presentation about Hardening Plone.</p>
<p>For a customer who needed a DMS to exchange documents with third parties we hardened the Plone stack. Several highlights of the hardening part are modifcations in the OS,� two technical audits, a process audit and adding some extra products in Plone. Here&#8217;s is the recorded stream of the presentation: <a href="http://www.ustream.tv/recorded/2446265">http://www.ustream.tv/recorded/2446265</a>. Here are the slides:</p>
<div id="__ss_2595885" style="width: 425px;"><strong style="display: block; margin: 12px 0 4px;"><a title="Hardening Plone, a military-strength CMS" href="http://www.slideshare.net/khink/hardening-plone-a-militarystrength-cms-2595885">Hardening Plone, a military-strength CMS</a></strong><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=ploneconf2009hardeningplone-091127062001-phpapp02&amp;rel=0&amp;stripped_title=hardening-plone-a-militarystrength-cms-2595885" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=ploneconf2009hardeningplone-091127062001-phpapp02&amp;rel=0&amp;stripped_title=hardening-plone-a-militarystrength-cms-2595885" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="padding: 5px 0 12px;">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/khink">khink</a>.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.leong.nl/2009/10/plone-conference-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu Karmic Koala and Python setuptools</title>
		<link>http://www.leong.nl/2009/10/ubuntu-karmic-koala-and-python-setuptools/</link>
		<comments>http://www.leong.nl/2009/10/ubuntu-karmic-koala-and-python-setuptools/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 12:06:46 +0000</pubDate>
		<dc:creator>Kim Chee Leong</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[python setuptools eggs bug]]></category>

		<guid isPermaLink="false">http://www.leong.nl/?p=131</guid>
		<description><![CDATA[This weekend I&#8217;ve upgrade my laptop to Ubuntu Karmic Koala. The upgrade was easy and Karmic looks and runs smoother than the previous version. I encountered one small problem with Python setuptools and subversion. I use Setuptools 0.6c9 to create Python eggs. It happens that the latest Setuptools won&#8217;t play well with subversion 1.6 (shipped [...]]]></description>
			<content:encoded><![CDATA[<p>This weekend I&#8217;ve upgrade my laptop to Ubuntu <a title="Ubuntu Linux" href="http://www.ubuntu.com/" target="_blank">Karmic Koala</a>. The upgrade was easy and Karmic looks and runs smoother than the previous version. I encountered one small problem with Python setuptools and subversion.</p>
<p>I use <a title="setuptools" href="http://pypi.python.org/pypi/setuptools/0.6c9" target="_blank">Setuptools 0.6c9 </a>to create Python eggs. It happens that the latest Setuptools won&#8217;t play well with subversion 1.6 (shipped with Karmic).</p>
<p>When creating an egg with:</p>
<p><strong>python setup.py bdist_egg </strong></p>
<p>I got this error:</p>
<p><strong>subversion unrecognized .svn/entries format</strong></p>
<p>You can fix this by running a patch from the setuptools team, <a title="Python setuptools error, Subversion 1.6 entries format 'unrecognized'" href="http://bugs.python.org/setuptools/issue64" target="_blank">download the most recent patch</a> from the issue page. Find out where setuptools lives in your site-packages and apply the patch. <a title="Details on fixing Subversion 1.6 entries format 'unrecognized'" href="http://www.leong.nl/oss/fix-svn1.6-with-setuptools.txt" target="_blank">More details here</a> if you&#8217;re not familiar with site-packages and applying patches.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leong.nl/2009/10/ubuntu-karmic-koala-and-python-setuptools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTC Magic rooting and custom ROMS</title>
		<link>http://www.leong.nl/2009/06/htc-magic-rooting-and-custom-roms/</link>
		<comments>http://www.leong.nl/2009/06/htc-magic-rooting-and-custom-roms/#comments</comments>
		<pubDate>Sat, 20 Jun 2009 21:58:10 +0000</pubDate>
		<dc:creator>Kim Chee Leong</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[android phone root htc magic sapphire]]></category>

		<guid isPermaLink="false">http://www.leong.nl/?p=106</guid>
		<description><![CDATA[Update 25 May 2010 &#8211; This information is outdated. Please refer to this page on the XDA Developers forum: http://forum.xda-developers.com/showthread.php?t=529062 Here are the steps to the how-to&#8217;s to get root access to your HTC Magic and load a custom ROM. I took me some time to find all the needed info to do the job. [...]]]></description>
			<content:encoded><![CDATA[<p><img class="attachment wp-att-116 alignright" style="float: right;" src="http://www.leong.nl/wp-content/htc_magic.jpg" alt="htc_magic" width="100" height="100" /></p>
<p><strong>Update 25 May 2010 &#8211; This information is outdated. Please refer to this page on the XDA Developers forum:</strong></p>
<p><strong><a href="http://forum.xda-developers.com/showthread.php?t=529062">http://forum.xda-developers.com/showthread.php?t=529062</a></strong></p>
<p>Here are the steps to the how-to&#8217;s to get root access to your <a title="HTC Magic" href="http://en.wikipedia.org/wiki/HTC_Magic">HTC Magi</a>c and load a custom ROM. I took me some time to find all the needed info to do the job. So I&#8217;m hapy to share it. There&#8217;s a lot of (cluttered) info but most of it is found in multiple page forums. Really great that there lot&#8217;s of people developing and using this stuff but a forum isn&#8217;t the right place for documentation.</p>
<p><em>Note 30-03-2010, the information below is outdated. Please look at the following wiki&#8217;s for more up to date info:</em></p>
<p><em><a title="XDA Developers Wiki about HTC Magic" href="http://wiki.xda-developers.com/index.php?pagename=HTC_Sapphire_Hacking"><span style="color: #000000;">http://wiki.xda-developers.com/index.php?pagename=HTC_Sapphire_Hacking</span></a></em></p>
<p><em><a title="Cyanogenmod custom Android ROM - Wiki" href="http://wiki.cyanogenmod.com/index.php/Main_Page">http://wiki.cyanogenmod.com/index.php/Main_Page</a></em></p>
<h2>Got root?</h2>
<p>Getting root access on the Magic isn&#8217;t so hard. Just install the SDK and USB drivers and push the images to the phone. In the last step is to install haykuro&#8217;s SPL update. This is the bootloader (correct?) and has a very usefull <a title="Nandroid info" href="http://androidcommunity.com/forums/f28/nandroid-v2-0-full-nand-backup-and-restore-tool-9336/">back-up option</a>. It&#8217;s called nandroid and creates back-up images of the system.  After this you have root access from the android debugger on your computer.</p>
<p><a title="Root how-to for HTC Magic" href="http://android-dls.com/wiki/index.php?title=Magic_Rooting">http://android-dls.com/wiki/index.php?title=Magic_Rooting</a></p>
<p>The second step is enabling root access from the phone. This allows you to su from the phone. Needed for installing rooted apps. It opens a security risk as mentioned in the how-to. But there a sudo-like app <a title="Superuser whitelist" href="http://www.cyrket.com/package/org.zenthought.android.su">SuperUser whitelist</a> to prevent unwanted root access (preinstalled on most custom roms). :</p>
<p><a title="Can I haz root?" href="http://android-dls.com/wiki/index.php?title=Magic_Root_Access">http://android-dls.com/wiki/index.php?title=Magic_Root_Access</a></p>
<h2>Custom ROMS</h2>
<p>So now you&#8217;ve got full access to the Magic but stuck with a stock rom from your provider. There are lots of roms floating around for Android but most of them are for the HTC Dream (G1). I found out the hard way by installing a G1 rom, WiFi and other hardware functions aren&#8217;t working. Not so strange with a different kernel etc&#8230;</p>
<p>These are the ROMs that are available at the moment:</p>
<ul>
<li>Google/HTC original stock rom</li>
<li><a title="Hero rom" href="http://forum.xda-developers.com/showthread.php?t=521544">Hero Rom</a>. Android with an updated ui. Shiney and new but it&#8217;s slow and laggy</li>
<li>Google ION rom. ION is a developer phone. <a title="nk02 Google ION (orginal from Haykuro)" href="http://forum.xda-developers.com/showthread.php?t=523971">Customized rom available.</a></li>
<li><a title="Haykuro's HTC Magic roms" href="http://code.google.com/p/sapphire-port-dream/">Haykuro&#8217;s Rom</a>. Haykuro&#8217;s roms are excellent but it seems that he has stopped developing.</li>
<li><a title="smartphone france htc magic rom" href="http://wiki.smartphonefrance.info/(X(1)S(sdzw0c2jcgoe2o55v2lepg45))/firmware-htcmagic.ashx">Smartphone France</a> (<a title="translation in English" href="http://babelfish.yahoo.com/translate_url?doit=done&amp;tt=url&amp;intl=1&amp;fr=bf-home&amp;trurl=http%3A%2F%2Fwiki.smartphonefrance.info%2F(X(1)S(sdzw0c2jcgoe2o55v2lepg45))%2Ffirmware-htcmagic.ashx&amp;lp=fr_en&amp;btnTrUrl=Translate">translation</a>). Customized ION rom, available in EU languages.</li>
</ul>
<p>Sending a rom is really easy, just like in the rooting process with an update.zip on the SD card. Always take care when installing a new rom. Better safe than sorry and check if it works on your Magic/Sapphire/ION. The last thing you want is a bricked phone&#8230;</p>
<p>I tried the Google ION rom and it works well. The benefits of this custom rom are; it&#8217;s faster, rooted, voice commands and more!� This is a good rom but there&#8217;s a HTC soft keyboard instead of Google&#8217;s. I didn&#8217;t like it and replaced it. <a title="Replace HTC keyboard with Google's" href="http://forum.xda-developers.com/showpost.php?p=3965137&amp;postcount=100">Instructions here</a>, you&#8217;ll need a <a href="http://www.droiddeveloper.com/hrbuilds/ionr2-sapphire-signed.zip">specific rom</a> (for extracting system files) or it won&#8217;t work!</p>
<p>I&#8217;m now using the Smartphone France version. The main advantage between above ION rom is this one is, tethering works and a higher version update rate. You won&#8217;t notice anything of the French language (beside a few small apps on the rom).</p>
<p>Also check out my <a title="Delicious" href="http://delicious.com/kcleong/android">Android bookmarks</a>!</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 326px; width: 1px; height: 1px;">Haykuro&#8217;s roms are excellent but it seems that he has stopped developing.</div>
]]></content:encoded>
			<wfw:commentRss>http://www.leong.nl/2009/06/htc-magic-rooting-and-custom-roms/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

