<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">
    <title>Philipp Bosch. Web &amp; Mobile Development</title>
    
    <link href="http://pb.io/" />
    <updated>2011-12-09T09:52:01+01:00</updated>
    <id>http://pb.io/</id>
    <author>
        <name>Philipp Bosch</name>
        <email>hello@pb.io</email>
    </author>
    
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/philippbosch" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="philippbosch" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
        <title>West || Ost – on which side are you?</title>
        <link href="http://pb.io/2011/11/27/westost-on-which-side-are-you/" />
        <updated>2011-11-27T00:00:00+01:00</updated>
        <id>http://pb.io/2011/11/27/westost-on-which-side-are-you</id>
        <content type="html">&lt;a href='http://westost.io/'&gt;&lt;img class='right' src='http://media.pb.io.s3.amazonaws.com/posts/2011-11-27-westost.png' alt='Screenshot WestOst app' /&gt;&lt;/a&gt;
&lt;p&gt;For a long time I&amp;#8217;ve been wanting to do this. Now I finally found the time.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve been living in Berlin for exactly five years now. As you probably know this city was divided into two parts by the Berlin Wall from 1961 until 1989. Nowadays there are almost no relics of the wall anymore. For I live only a few hundred meters from the former inner-city border, often times when I wander around here I ask myself on which side of the wall I would be if it still existed.&lt;/p&gt;

&lt;p&gt;For that reason I created &lt;a href='http://westost.io/'&gt;West || Ost&lt;/a&gt;. It&amp;#8217;s a simple web app for your mobile phone, and it will tell you if you are in the former Western or Eastern part of Berlin (or that you are not in Berlin at all) – nothing more, nothing less. I hope it is of use for someone else.&lt;/p&gt;

&lt;p&gt;iOS users: add the app to your homescreen to see it in all its minimalistic glory.&lt;/p&gt;</content>
    </entry>
    
    <entry>
        <title>Major upgrade to haz.io</title>
        <link href="http://pb.io/2011/11/27/haz-io-update/" />
        <updated>2011-11-27T00:00:00+01:00</updated>
        <id>http://pb.io/2011/11/27/haz-io-update</id>
        <content type="html">&lt;p&gt;It&amp;#8217;s been over four months that I launched &lt;a href='http://haz.io/'&gt;haz.io&lt;/a&gt; back in July. Four months is a long time in web development nowadays, and quite a lot has changed in the browser space. To catch up with that I gave haz.io an overhaul today. haz.io has made use of all available tests in the default Modernizr build. And Modernizr did not have an official release for a while. But a whole bunch of &lt;a href='https://github.com/Modernizr/Modernizr/tree/master/feature-detects'&gt;community add-ons&lt;/a&gt; have been contributed, and we are adding most of them to haz.io today.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;That means that you can now use haz.io to check your browser for support of:&lt;/p&gt;

&lt;h3 id='css'&gt;CSS&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;background-repeat: round&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;&lt;code&gt;background-repeat: space&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;&lt;code&gt;background-size: cover&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;&lt;code&gt;box-sizing&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;&lt;code&gt;cubic-bezier()&lt;/code&gt; values &amp;gt; 1.0&lt;/li&gt;

&lt;li&gt;&lt;code&gt;display: table&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;&lt;code&gt;overflow-scrolling: touch&lt;/code&gt; (momentum scrolling introduced with iOS 5)&lt;/li&gt;

&lt;li&gt;&lt;code&gt;pointer-events&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;&lt;code&gt;user-select&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='html5'&gt;HTML5&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; element&lt;/li&gt;

&lt;li&gt;Device Motion Event&lt;/li&gt;

&lt;li&gt;Device Orientation Event&lt;/li&gt;

&lt;li&gt;File API&lt;/li&gt;

&lt;li&gt;&lt;code&gt;&amp;lt;meter&amp;gt;&lt;/code&gt; element&lt;/li&gt;

&lt;li&gt;&lt;code&gt;&amp;lt;progress&amp;gt;&lt;/code&gt; element&lt;/li&gt;

&lt;li&gt;Shared Workers&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='miscellaneous'&gt;Miscellaneous&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Cookies&lt;/li&gt;

&lt;li&gt;Custom Protocol Handlers&lt;/li&gt;

&lt;li&gt;data URIs&lt;/li&gt;

&lt;li&gt;Emoji&lt;/li&gt;

&lt;li&gt;Fullscreen API&lt;/li&gt;

&lt;li&gt;WebP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also a minor styling issue introduced with iOS 5 has been resolved.&lt;/p&gt;

&lt;p&gt;Check out the updated &lt;a href='http://haz.io/'&gt;haz.io&lt;/a&gt;.&lt;/p&gt;</content>
    </entry>
    
    <entry>
        <title>Some Alfred extensions</title>
        <link href="http://pb.io/2011/08/10/alfred-extensions/" />
        <updated>2011-08-10T00:00:00+02:00</updated>
        <id>http://pb.io/2011/08/10/alfred-extensions</id>
        <content type="html">&lt;p&gt;For a few months now I have been a huge fan of &lt;a href='http://www.alfredapp.com/'&gt;Alfred&lt;/a&gt;, the super smart application launcher (and more) for Mac OS X. After having used &lt;a href='http://qsapp.com/'&gt;Quicksilver&lt;/a&gt;, &lt;a href='http://manytricks.com/butler/'&gt;Butler&lt;/a&gt; and &lt;a href='http://www.obdev.at/products/launchbar/'&gt;LaunchBar&lt;/a&gt; before, I now feel at home with Alfred.&lt;/p&gt;

&lt;p&gt;With the latest release (0.9.9) came a long-awaited feature: &lt;a href='http://blog.alfredapp.com/2011/07/31/alfred-0-9-9-brings-extensions-new-free-theme/'&gt;extensions&lt;/a&gt;! Before you were already able to create custom queries – something like &lt;code&gt;jq foo&lt;/code&gt; being translated into a URL like &lt;code&gt;http://docs.jquery.com/Special:Search?search=foo&lt;/code&gt; that is then opened in your browser. And that was already cool. But now you can create custom extensions that trigger Shell Scripts, AppleScripts, Automator Workflows, etc. And it could not be easier. What&amp;#8217;s even cooler is that you can easily import others&amp;#8217; extensions or export yours and share them with others.&lt;/p&gt;

&lt;p&gt;I have recently created a few extensions for myself which I want to share with you here. Maybe there&amp;#8217;s something useful in it for you.&lt;/p&gt;
&lt;!--more--&gt;&lt;hr /&gt;
&lt;h3 id='generate_password'&gt;Generate Password&lt;/h3&gt;

&lt;p&gt;Generate a random password (12 characters long) and copy it to the clipboard.&lt;/p&gt;

&lt;p&gt;Keyword: &lt;code&gt;password&lt;/code&gt;&lt;br /&gt;Download: &lt;a href='http://stuff.pb.io/9C2V'&gt;stuff.pb.io/9C2V&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3 id='free_space'&gt;Free Space&lt;/h3&gt;

&lt;p&gt;Calculate the free space on your hard disk and display it in a Growl notification.&lt;/p&gt;

&lt;p&gt;Keyword: &lt;code&gt;space&lt;/code&gt;&lt;br /&gt;Download: &lt;a href='http://stuff.pb.io/9BWL'&gt;stuff.pb.io/9BWL&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3 id='url_encode'&gt;URL Encode&lt;/h3&gt;

&lt;p&gt;Replace special characters in the given string using the &lt;code&gt;%xx&lt;/code&gt; escape suitable for using in a URL and copy the resulting string to the clipboard.&lt;/p&gt;

&lt;p&gt;Keyword: &lt;code&gt;urlencode&lt;/code&gt;&lt;br /&gt;Example: &lt;code&gt;urlencode some text with sp€ciäl çhåráctêrs&lt;/code&gt;&lt;br /&gt;Output: &lt;code&gt;some+text+with+sp%E2%82%ACcia%CC%88l+c%CC%A7ha%CC%8Ara%CC%81cte%CC%82rs&lt;/code&gt;&lt;br /&gt;Download: &lt;a href='http://stuff.pb.io/9BvD'&gt;stuff.pb.io/9BvD&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3 id='say'&gt;Say&lt;/h3&gt;

&lt;p&gt;Read the given string out loud.&lt;/p&gt;

&lt;p&gt;Keyword: &lt;code&gt;say&lt;/code&gt;&lt;br /&gt;Example: &lt;code&gt;say Hello world&lt;/code&gt;&lt;br /&gt;Download: &lt;a href='http://stuff.pb.io/9BaK'&gt;stuff.pb.io/9BaK&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3 id='work_on'&gt;Work On&lt;/h3&gt;

&lt;p&gt;This one is probably a bit specific to my workflow but may give you some ideas on how to create a similar extension for your needs.&lt;/p&gt;

&lt;p&gt;Open a new terminal, activate virtual environment (Python), start development server, start &lt;a href='http://compass-style.org/'&gt;&lt;code&gt;compass watch&lt;/code&gt;&lt;/a&gt;, open the corresponding folder in TextMate and open the local website in the browser. This extensions makes some assumptions that probably do not hold true for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I&amp;#8217;m using &lt;a href='http://www.iterm2.com/'&gt;iTerm2&lt;/a&gt; instead of the OSX Terminal.app&lt;/li&gt;

&lt;li&gt;I&amp;#8217;m developing in Python and using &lt;a href='http://pypi.python.org/pypi/virtualenv'&gt;virtualenv&lt;/a&gt; and &lt;a href='http://www.doughellmann.com/projects/virtualenvwrapper/'&gt;virtualenvwrapper&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;I&amp;#8217;m making use of virtualenvwrapper&amp;#8217;s &lt;code&gt;postactivate&lt;/code&gt; hook to initiate a &lt;a href='http://www.gnu.org/s/screen/'&gt;screen&lt;/a&gt;/&lt;a href='https://launchpad.net/byobu'&gt;byobu&lt;/a&gt; session that in turn opens virtual terminals with the development server, &lt;code&gt;compass watch&lt;/code&gt;, etc.&lt;/li&gt;

&lt;li&gt;I have my project sources in &lt;code&gt;~/Sites/projectname&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;I have my development server running at &lt;code&gt;http://projectname:8000/&lt;/code&gt; (doing this using &lt;a href='https://github.com/bjeanes/ghost'&gt;ghost&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keyword: &lt;code&gt;workon&lt;/code&gt;&lt;br /&gt;Example: &lt;code&gt;workon myproject&lt;/code&gt;&lt;br /&gt;Download: &lt;a href='http://stuff.pb.io/9D88'&gt;stuff.pb.io/9D88&lt;/a&gt;&lt;br /&gt;Source: &lt;a href='https://gist.github.com/1139327'&gt;gist.github.com/1139327&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;I will try to update this post when I create new extensions. Many more helpful extensions can be found on the &lt;a href='http://blog.alfredapp.com/2011/08/02/alfred-extensions/'&gt;Alfred blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update 1 (2011-08-11):&lt;/strong&gt;&lt;br /&gt;«Work On» extension added.&lt;/p&gt;</content>
    </entry>
    
    <entry>
        <title>haz.io – what does my browser support?</title>
        <link href="http://pb.io/2011/07/08/haz-io/" />
        <updated>2011-07-08T00:00:00+02:00</updated>
        <id>http://pb.io/2011/07/08/haz-io</id>
        <content type="html">&lt;p&gt;Quite often I find myself looking at a browser I&amp;#8217;m not 100% familiar with and wondering which of the fancy new HTML5 oder CSS3 features does it support. Does IE9 support SVG – or do I need to use a &lt;a href='https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills'&gt;polyfill&lt;/a&gt;? Can I use the Geolocation API in Opera?&lt;/p&gt;

&lt;p&gt;Until recently what I did was simply go to the &lt;a href='http://www.modernizr.com/'&gt;Modernizr&lt;/a&gt; website because on the frontpage they had this table of features they are able to detect with their awesome library, and next to each a green checkmark if the browser you were using supports this feature.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;img src='http://media.pb.io/posts/2011-07-08-haz-io-01.png' alt='Screenshot of former Modernizr website' /&gt;&lt;/p&gt;

&lt;p&gt;Well, with the relase of &lt;a href='http://www.modernizr.com/news/modernizr-2'&gt;Modernizr 2&lt;/a&gt; came a new website and sadly the feature table disappeared completely. I don&amp;#8217;t know why they did that or if it will ever come back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update 1:&lt;/strong&gt; &lt;em&gt;Read &lt;a href='https://twitter.com/modernizr/status/86521308854222848'&gt;this tweet&lt;/a&gt; from the Modernizr team.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Last week I installed &lt;a href='http://seas0npass.com/'&gt;Seas0nPass&lt;/a&gt; on my AppleTV2. And with it comes a Webkit-based browser app. Me being the curious fellow I wanted to know how decent the support for the recent browser technologies is in that app in order to get an idea what I could do with that device.&lt;/p&gt;

&lt;p&gt;That&amp;#8217;s when I decided to put together a small website I could go to from any browser on any device, and that would tell me what this browser is capable of. The result of about two hours of hackery is this: &lt;a href='http://haz.io/'&gt;haz.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://haz.io/'&gt;&lt;img src='http://media.pb.io/posts/2011-07-08-haz-io-02.jpg' alt='Screenshot of haz.io website' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s very simple. I have a &lt;a href='http://haz.io/capabilities.json'&gt;JSON file&lt;/a&gt; with a list of features that should be tested for. I&amp;#8217;m looping through that with jQuery and building the HTML from it. Each item representing one feature gets a class attribute with the feature name. Utilizing the fact that Modernizr adds the same class names to the &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; element and using some nice &lt;a href='https://github.com/philippbosch/haz/blob/92240ee236c0dfd2b14f/sass/screen.scss#L171-L189'&gt;Sass trickery&lt;/a&gt; I&amp;#8217;m able to put either a green «Yep» or a red «Nope» next to each item.&lt;/p&gt;

&lt;p&gt;I also threw in a bit of &lt;a href='http://www.alistapart.com/articles/responsive-web-design/'&gt;responsiveness&lt;/a&gt; in there in order to make the feature tables look nice on mobile devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update 2:&lt;/strong&gt; &lt;em&gt;I added support for &lt;a href='http://jdrop.org/'&gt;Jdrop&lt;/a&gt; because I wanted to be able to save the data from a mobile device and review it on my computer. But unfortunately Steve Souders has not yet picked it up so for now you&amp;#8217;ll get an error message when you press the «Jdrop» button at the bottom of the page.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update 3:&lt;/strong&gt; &lt;em&gt;I recently removed Jdrop support again because I was unable to find the time to implement it properly. And maybe it wasn&amp;#8217;t such a good idea to begin with. Thanks, Steve, for your support anyways.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What do you think about haz.io? Let me know in the comments.&lt;/p&gt;

&lt;p&gt;The source is on &lt;a href='http://github.com/philippbosch/haz'&gt;GitHub&lt;/a&gt;.&lt;/p&gt;</content>
    </entry>
    
    <entry>
        <title>django-geoposition – a tiny app to store geopositions in Django models</title>
        <link href="http://pb.io/2011/04/04/django-geoposition/" />
        <updated>2011-04-04T00:00:00+02:00</updated>
        <id>http://pb.io/2011/04/04/django-geoposition</id>
        <content type="html">&lt;p&gt;Yesterday I was looking for a simple way to add a geoposition (latitude and longitude) field to a Django model without the whole &lt;a href='http://docs.djangoproject.com/en/dev/ref/contrib/gis/'&gt;GeoDjango aka django.contrib.gis&lt;/a&gt; hassle but unfortunately was not successful. The approaches I found were either too minimal, overloaded or outdated. So I came up with a simple solution myself.&lt;/p&gt;

&lt;p&gt;May I present to you: &lt;strong&gt;django-geoposition&lt;/strong&gt;.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h3 id='installation'&gt;Installation&lt;/h3&gt;

&lt;p&gt;Say you want to store a geoposition in one of your models. It&amp;#8217;s three simple steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step #1&lt;/strong&gt;&lt;br /&gt;Add &lt;code&gt;geoposition&lt;/code&gt; to your &lt;code&gt;INSTALLED_APPS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step #2&lt;/strong&gt;&lt;br /&gt;Add a &lt;code&gt;GeopositionField&lt;/code&gt; to one of your models.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='kn'&gt;from&lt;/span&gt; &lt;span class='nn'&gt;django.db&lt;/span&gt; &lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='n'&gt;models&lt;/span&gt;
&lt;span class='kn'&gt;from&lt;/span&gt; &lt;span class='nn'&gt;geoposition.fields&lt;/span&gt; &lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='n'&gt;GeopositionField&lt;/span&gt;

&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;PointOfInterest&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;models&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
    &lt;span class='n'&gt;name&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;models&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;CharField&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;max_length&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='mi'&gt;100&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;position&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;GeopositionField&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Step #3&lt;/strong&gt;&lt;br /&gt;There is no step #3.&lt;/p&gt;

&lt;h3 id='usage'&gt;Usage&lt;/h3&gt;

&lt;p&gt;Also very simple:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='kn'&gt;from&lt;/span&gt; &lt;span class='nn'&gt;myapp.models&lt;/span&gt; &lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='n'&gt;PointOfInterest&lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;poi&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;PointOfInterest&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;objects&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;id&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;poi&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;position&lt;/span&gt;
&lt;span class='n'&gt;Geoposition&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mf'&gt;52.522906&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mf'&gt;13.41156&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;poi&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;position&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;latitude&lt;/span&gt;
&lt;span class='mf'&gt;52.522906&lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;poi&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;position&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;longitude&lt;/span&gt;
&lt;span class='mf'&gt;13.41156&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='widget'&gt;Widget&lt;/h3&gt;

&lt;p&gt;If used in a form (e.g. in the admin) the field is displayed together with a Google Maps widget looking like this:&lt;/p&gt;

&lt;p&gt;&lt;img src='http://django-geoposition.readthedocs.org/en/latest/_images/geoposition-widget-admin.jpg' alt='Screenshot' /&gt;&lt;/p&gt;

&lt;p&gt;… and that&amp;#8217;s basically it.&lt;/p&gt;

&lt;p&gt;The source is on &lt;a href='http://github.com/philippbosch/django-geoposition'&gt;GitHub&lt;/a&gt; and &lt;a href='http://pypi.python.org/pypi/django-geoposition'&gt;PyPI&lt;/a&gt;. Basic documentation is available on &lt;a href='http://django-geoposition.rtfd.org/'&gt;Read the docs&lt;/a&gt;.&lt;/p&gt;</content>
    </entry>
    
    <entry>
        <title>Consume iCalendar data as JSON</title>
        <link href="http://pb.io/2011/02/05/consume-ical-data-as-json/" />
        <updated>2011-02-05T00:00:00+01:00</updated>
        <id>http://pb.io/2011/02/05/consume-ical-data-as-json</id>
        <content type="html">&lt;p&gt;While building this website I wanted to incorporate an overview of conferences that I&amp;#8217;m going to. The data is already out there at &lt;a href='http://lanyrd.com/people/philippbosch'&gt;Lanyrd&lt;/a&gt; but unfortunately there is no API yet. There are &lt;a href='http://lanyrd.com/services/badges/'&gt;badges&lt;/a&gt; available to embed in your site but that didn&amp;#8217;t cut it for me.&lt;/p&gt;

&lt;p&gt;I then saw that they are offering iCalendar files on the &lt;a href='http://lanyrd.com/calendar/yours/'&gt;calendar page&lt;/a&gt; (in the end it turned out not to be what I want because this data also includes conferences that I&amp;#8217;m &lt;em&gt;tracking&lt;/em&gt; and not only those I&amp;#8217;m &lt;em&gt;attending&lt;/em&gt;, but that&amp;#8217;s another story). Maybe I could take advantage of this somehow using &lt;a href='http://developer.yahoo.com/yql/'&gt;YQL&lt;/a&gt;. Turns out you can consume Atom, RSS, CSV, and tons of other formats, but no luck with iCalendar data.&lt;/p&gt;

&lt;p&gt;So I sat down and put together a tiny web service that pulls in iCalendar data from a URL and converts it to JSON. Here&amp;#8217;s how to use it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://ical2json.pb.io/the-website.com/path/to/file.ics&lt;/code&gt;&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;So for example let&amp;#8217;s take some events from &lt;a href='http://www.last.fm/'&gt;Last.fm&lt;/a&gt;. They provide iCalendar data at URLs like this: &lt;code&gt;http://ws.audioscrobbler.com/1.0/artist/Shout+Out+Louds/events.ics&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To get this data in JSON format use a URL like this: &lt;code&gt;http://ical2json.pb.io/ws.audioscrobbler.com/1.0/artist/Shout+Out+Louds/events.ics&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The response will look like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='s1'&gt;&amp;#39;VCALENDAR&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;VEVENT&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;
      &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='s1'&gt;&amp;#39;DTSTAMP&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;20110328T203000&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;UID&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;LFMEVENT-1748422&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;URL&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;http://www.last.fm/event/1748422+Shout+Out+Louds+at+La+Machine+du+Moulin+Rouge+on+28+March+2011&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;SUMMARY&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Shout Out Louds at La Machine du Moulin Rouge&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;LOCATION&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;La Machine du Moulin Rouge, Paris, France&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;DTEND&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;20110328T235900&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;DTSTART&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;20110328T203000&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;GEO&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;2.332258;48.884008&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;DESCRIPTION&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Shout Out Louds\n\nhttp://www.last.fm/event/1748422+Shout+Out+Louds+at+La+Machine+du+Moulin+Rouge+on+28+March+2011&amp;quot;&lt;/span&gt;
      &lt;span class='p'&gt;},&lt;/span&gt; 
      &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='s1'&gt;&amp;#39;DTSTAMP&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;20110329T203000&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;UID&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;LFMEVENT-1755031&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;URL&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;http://www.last.fm/event/1755031+Shout+Out+Louds+at+La+Nef+on+29+March+2011&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;SUMMARY&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Shout Out Louds + Hello Bye Bye at La Nef&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;LOCATION&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;La Nef, Angoul\u00eame, France&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;DTEND&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;20110329T235900&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;DTSTART&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;20110329T203000&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;GEO&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;0.130579;45.640423&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
        &lt;span class='s1'&gt;&amp;#39;DESCRIPTION&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Shout Out Louds, Hello Bye Bye\n\nhttp://www.last.fm/event/1755031+Shout+Out+Louds+at+La+Nef+on+29+March+2011&amp;quot;&lt;/span&gt;
      &lt;span class='p'&gt;}&lt;/span&gt;
      &lt;span class='c1'&gt;// …&lt;/span&gt;
    &lt;span class='p'&gt;],&lt;/span&gt; 
    &lt;span class='s1'&gt;&amp;#39;VERSION&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;2.0&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
    &lt;span class='s1'&gt;&amp;#39;X-WR-CALNAME&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Last.fm Events&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
    &lt;span class='s1'&gt;&amp;#39;PRODID&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;-//Last.fm Limited Event Feeds//NONSGML//EN&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
    &lt;span class='s1'&gt;&amp;#39;X-WR-CALDESC&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Event listing - supplied by http://www.Last.fm&amp;quot;&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Of course there&amp;#8217;s also support for JSON-P callbacks (?callback=foo).&lt;/p&gt;

&lt;p&gt;The source and some documentation can be found on &lt;a href='http://github.com/philippbosch/ical2json'&gt;GitHub&lt;/a&gt;.&lt;/p&gt;</content>
    </entry>
    
    <entry>
        <title>My first app on PyPI: django-tellafriend</title>
        <link href="http://pb.io/2010/08/06/my-first-app-on-pypi/" />
        <updated>2010-08-06T00:00:00+02:00</updated>
        <id>http://pb.io/2010/08/06/my-first-app-on-pypi</id>
        <content type="html">&lt;p&gt;I should have done this much earlier, but a few minutes ago I uploaded my first Django app to &lt;a href='http://pypi.python.org/'&gt;PyPI&lt;/a&gt;, the Python Package Index a.k.a. &lt;em&gt;«The Cheese Shop»&lt;/em&gt;. The app itself is nothing more than a simple tell-a-friend functionality that I extracted from &lt;a href='http://polygonbaby.com/'&gt;some client project&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While writing the &lt;code&gt;setup.py&lt;/code&gt; file (which was really easy in the end) I found &lt;a href='http://packages.python.org/an_example_pypi_project/setuptools.html'&gt;this tutorial&lt;/a&gt; to be very helpful. The most exciting and surprising part was that &lt;code&gt;python setup.py register&lt;/code&gt; is all you need to do to register the package with PyPI, and &lt;code&gt;python setup.py sdist upload&lt;/code&gt; to create a source distribution and upload it. After that it&amp;#8217;s only a matter of &lt;code&gt;pip install django-tellafriend&lt;/code&gt; for anyone to install the app.&lt;/p&gt;

&lt;p&gt;And as if that was not already enough new insights for today, I even created some &lt;a href='http://philippbosch.github.com/django-tellafriend/'&gt;basic documenation&lt;/a&gt; using &lt;a href='http://sphinx.pocoo.org/'&gt;Sphinx&lt;/a&gt;. Woohoo!&lt;/p&gt;

&lt;p&gt;The app does not (yet) have its own page on this site, but the source is available on &lt;a href='http://github.com/philippbosch/django-tellafriend'&gt;GitHub&lt;/a&gt; and on &lt;a href='http://pypi.python.org/pypi/django-tellafriend'&gt;PyPI&lt;/a&gt;.&lt;/p&gt;</content>
    </entry>
    
    <entry>
        <title>Cross-browser RGBA background colors</title>
        <link href="http://pb.io/2010/07/26/cross-browser-rgba-background-colors/" />
        <updated>2010-07-26T00:00:00+02:00</updated>
        <id>http://pb.io/2010/07/26/cross-browser-rgba-background-colors</id>
        <content type="html">&lt;p&gt;For a website I&amp;#8217;m currently working on I needed a way to have an image and on top of that a text box with a partly transparent background color. I didn&amp;#8217;t want to use any hacks with AlphaImageLoader and stuff but preferred a pure CSS solution. And I found a nice one, I think.&lt;/p&gt;

&lt;p&gt;First, this is what the designer wanted it to look like:&lt;/p&gt;

&lt;p&gt;&lt;img src='http://media.pb.io/posts/2010-07-26-cross-browser-rgba-background-colors-01.jpg' alt='Website header design' /&gt;&lt;/p&gt;

&lt;p&gt;The problem is the partly-transparent background of the tabs and the darker section with the inactive tab titles. For modern Browsers that&amp;#8217;s just a matter of &lt;code&gt;background-color: rgba(134,161,11,0.6);&lt;/code&gt;. But of course Internet Explorer is a bit late to the party and does not support this.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;So I stumpled upon an &lt;a href='http://yatil.de/Weblog/cross-browser-rgba'&gt;article by Erig Eggert&lt;/a&gt; (sorry, German only) where he describes an approach using a gradient &lt;code&gt;filter&lt;/code&gt;. The thing is that this filter allows not only opaque but also partly-transparent colors to be used. Use the same non-opaque color twice for start and end color and you effectively have a partly-transparent area. The syntax is as follows:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nt'&gt;filter&lt;/span&gt;&lt;span class='nd'&gt;:progid:DXImageTransform&lt;/span&gt;&lt;span class='nc'&gt;.Microsoft.gradient&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;
    &lt;span class='nt'&gt;startColorstr&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='nf'&gt;#9986A10B&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;&lt;span class='nt'&gt;endColorstr&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='nf'&gt;#9986A10B&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The values for &lt;code&gt;startColorstr&lt;/code&gt; and &lt;code&gt;endColorstr&lt;/code&gt; consist of two parts (after the &lt;code&gt;#&lt;/code&gt;): the first – &lt;code&gt;99&lt;/code&gt; – is the alpha transparency (0.6 * 255 = 153, in hexadecimal: 99), the second – &lt;code&gt;86A10B&lt;/code&gt; – is the hexadecimal representation of the color&amp;#8217;s RGB values (161, 161, 11). That&amp;#8217;s it.&lt;/p&gt;

&lt;p&gt;Combine this with the RGBA version and maybe an opaque fallback, and you get this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nt'&gt;background-color&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nf'&gt;#86A10B&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='nt'&gt;background-color&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nt'&gt;rgba&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='nt'&gt;134&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;&lt;span class='nt'&gt;161&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;&lt;span class='nt'&gt;11&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;&lt;span class='nt'&gt;0&lt;/span&gt;&lt;span class='nc'&gt;.6&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
&lt;span class='nt'&gt;background-color&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nt'&gt;transparent&lt;/span&gt;&lt;span class='err'&gt;\&lt;/span&gt;&lt;span class='nt'&gt;9&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='c'&gt;/* reset the background color in IE only */&lt;/span&gt;
&lt;span class='nt'&gt;filter&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nt'&gt;progid&lt;/span&gt;&lt;span class='nd'&gt;:DXImageTransform&lt;/span&gt;&lt;span class='nc'&gt;.Microsoft.gradient&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;
    &lt;span class='nt'&gt;startColorstr&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='nf'&gt;#9986A10B&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;&lt;span class='nt'&gt;endColorstr&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='nf'&gt;#9986A10B&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
&lt;span class='nt'&gt;zoom&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nt'&gt;1&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='c'&gt;/* trigger hasLayout in IE6 */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;As I&amp;#8217;m using &lt;a href='http://compass-style.org/'&gt;Compass&lt;/a&gt; in this project I put this in a small mixin:&lt;/p&gt;

&lt;p&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sass'&gt;&lt;span class='k'&gt;@mixin&lt;/span&gt;&lt;span class='nf'&gt; rgba-background&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$color&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='nv'&gt;$opacity&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='err'&gt;{&lt;/span&gt;
    &lt;span class='na'&gt;background-color&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nv'&gt;$color&lt;/span&gt;&lt;span class='err'&gt;;&lt;/span&gt;
    &lt;span class='na'&gt;background-color&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nf'&gt;rgba&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$color&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='nv'&gt;$opacity&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='err'&gt;;&lt;/span&gt;
    &lt;span class='na'&gt;background-color&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='no'&gt;transparent&lt;/span&gt;&lt;span class='err'&gt;\&lt;/span&gt;&lt;span class='mi'&gt;9&lt;/span&gt;&lt;span class='err'&gt;;&lt;/span&gt;
    &lt;span class='na'&gt;filter&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;progid&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='n'&gt;DXImageTransform&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Microsoft&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='nf'&gt;gradient&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;startColorstr&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&lt;/span&gt;&lt;span class='s2'&gt;#&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;+&lt;/span&gt;&lt;span class='nf'&gt;hex&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;round&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$opacity&lt;/span&gt;&lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='mi'&gt;255&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&lt;/span&gt;&lt;span class='s2'&gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nf'&gt;hex&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;red&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$color&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&lt;/span&gt;&lt;span class='s2'&gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nf'&gt;hex&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;green&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$color&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&lt;/span&gt;&lt;span class='s2'&gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nf'&gt;hex&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;blue&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$color&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;&lt;span class='n'&gt;endColorstr&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&lt;/span&gt;&lt;span class='s2'&gt;#&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;+&lt;/span&gt;&lt;span class='nf'&gt;hex&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;round&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$opacity&lt;/span&gt;&lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='mi'&gt;255&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&lt;/span&gt;&lt;span class='s2'&gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nf'&gt;hex&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;red&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$color&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&lt;/span&gt;&lt;span class='s2'&gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nf'&gt;hex&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;green&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$color&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&lt;/span&gt;&lt;span class='s2'&gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nf'&gt;hex&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;blue&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$color&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='err'&gt;;&lt;/span&gt;
    &lt;span class='na'&gt;zoom&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='err'&gt;;&lt;/span&gt;
&lt;span class='err'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;In order to make this work we need to add a &lt;code&gt;hex()&lt;/code&gt; function to SASS which you can for example put inside of your &lt;code&gt;config.rb&lt;/code&gt;. The code is this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;Sass::Script::Functions&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;hex&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;decimal&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='no'&gt;Sass&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Script&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='nb'&gt;String&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;%02x&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='n'&gt;decimal&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; The site is online now and you can see this technique in action at &lt;a href='http://www.universum-group.de/'&gt;Universum Group&lt;/a&gt;.&lt;/p&gt;</content>
    </entry>
    
    <entry>
        <title>Leave a Comment</title>
        <link href="http://pb.io/2010/05/21/leave-a-comment/" />
        <updated>2010-05-21T00:00:00+02:00</updated>
        <id>http://pb.io/2010/05/21/leave-a-comment</id>
        <content type="html">&lt;p&gt;Tonight will be the opening reception of a group exhibition called &lt;strong&gt;«Locate Me»&lt;/strong&gt; at the &lt;a href='http://www.kunstraumkreuzberg.de/prog_2.html'&gt;Kunstraum Kreuzberg&lt;/a&gt; inside the Künstlerhaus Bethanien. My dear office mates &lt;a href='http://the-product.org/'&gt;Patrick and Dennis&lt;/a&gt; will show their project &lt;a href='http://the-product.org/leave-a-comment-toolkit'&gt;«Leave a Comment»&lt;/a&gt; there.&lt;/p&gt;

&lt;p&gt;The main intention of this project is to cast an invisible layer of subjective, unauthored information on public space.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To achieve this, we hand out prepared «toolkits», comprised of an ultraviolet-fluorescent pen (UV-pen), a speech-bubble-shaped stencil, and an ultraviolet-torch (UV-torch). The UV-pen and the stencil function as the «authoring tool» while the UV-torch plays the role of the «imaging device». The UV-pen works in a way that allows for leaving a message on a surface, invisible to the human eye, until the message is illuminated with the UV-torch, revealing it fluorescing, temporarily visible to the human eye.&lt;/p&gt;

&lt;p&gt;Equipped with the toolkit participants now tag, flag, or comment on things, spaces and places by invisibly but physically writing or drawing on them. Eventually the invisible layer grows into a secret parallel world, with messages potentially lurking in corners, comments unknowingly on display right in front of one&amp;#8217;s face, subversively augmenting public space.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!--more--&gt;
&lt;p&gt;Also part of this project is an &lt;a href='http://lacmap.com/'&gt;iPhone app&lt;/a&gt; that helps people find tagged spots around the city and also file spots that they tagged themselves making it easier for others to find those. I built this app based on HTML5 technology and a &lt;a href='http://couchdb.org/'&gt;CouchDB&lt;/a&gt; server component for storing the spots.&lt;/p&gt;
&lt;object height='393' width='640'&gt;
    &lt;param name='movie' value='http://www.youtube.com/v/K1WN1KPNAfA?fs=1' /&gt;
    &lt;param name='allowFullScreen' value='true' /&gt;
    &lt;param name='allowscriptaccess' value='always' /&gt;
    &lt;embed src='http://www.youtube.com/v/K1WN1KPNAfA?fs=1' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='393' width='640' /&gt;
&lt;/object&gt;</content>
    </entry>
    
</feed>

