<?xml version="1.0" encoding="utf-8"?>
<!-- generator="FeedCreator 1.7.6(BH)" -->
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Planet Midgard</title>
    <subtitle>Blog postings from the Midgard community</subtitle>
    <link rel="alternate" type="text/html" href="http://www.midgard-project.org/planet/"/>
    <id>http://www.midgard-project.org/planet/</id>
    <updated>2012-02-04T13:24:21+00:00</updated>
    <author>
        <name>henri.bergius@iki.fi</name>
    </author>
    <generator>FeedCreator 1.7.6(BH) (info@mypapit.net)</generator>
    <link rel="self" type="application/atom+xml" href="http://www.midgard-project.org/planet/atom.xml" />
    <entry>
        <title>Composer solves the PHP code-sharing problem</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/composer_solves_the_php_code-sharing_problem/"/>
        <published>2011-11-02T00:01:06+00:00</published>
        <updated>2011-11-02T00:01:06+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-fe0c079e053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>In PHP we've had <a href="http://bergie.iki.fi/blog/php-finally_getting_an_ecosystem/">a lousy culture</a> of code-sharing. Because depending on code from others as been tricky, every major PHP application or framework has practically had to reimplement the whole world. Only some tools, like <a href="https://github.com/sebastianbergmann/phpunit/">PHPUnit</a>, have managed to break over this barrier and become de-facto standards across project boundaries. But for the rest: just write it yourself.</p>

<p>But now <a href="http://packagist.org/about-composer">Composer</a>, and its repository counterpart <a href="http://packagist.org/">Packagist</a>, promise to change all that. And obviously new conventions like PHP's <a href="http://www.php.net/manual/en/language.namespaces.rationale.php">namespacing support</a> and the <a href="https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md">PSR-0</a> standard autoloader help.</p>

<p>Composer is heavily inspired by <a href="http://npmjs.org/">NPM</a> which has built a strong culture of code-sharing and easy deployment in the Node.js community.</p>

<h2>Easy for users</h2>

<p>With Composer, managing dependencies in your project is very easy. Simply create a <code>composer.json</code> file where you state your dependencies, and let the package management system worry about the rest.</p>

<p>Packages that are registered with packagist.org are obviously easiest to depend on, but you can also state packages coming from custom repositories (like your company's internal version control system), or PHP extensions that you need.</p>

<p>Here is for example the <code>composer.json</code> from the <a href="https://github.com/bergie/phpcr-midgard2">Midgard PHPCR provider</a>:</p>

<pre><code>{
    "name": "midgard/phpcr",
    "type": "library",
    "require": {
        "php": "&gt;=5.3.0",
        "ext-midgard2": "&gt;=10.05.5",
        "phpcr/phpcr": "&gt;=2.1.0-beta1"
    }
}
</code></pre>

<p>With this file, Composer knows that our PHPCR provider runs only on PHP 5.3 or newer (as it uses namespaces), and that it needs the <a href="http://new.midgard-project.org/midgard2/">Midgard PHP extension</a> and the <a href="http://phpcr.github.com/">PHPCR interface classes</a> to be available.</p>

<p>Now installing the project is easy:</p>

<pre><code>$ wget http://getcomposer.org/composer.phar 
$ php composer.phar install
</code></pre>

<p>How about autoloading? Traditionally PHP required you to manually <code>include</code> or <code>require</code> all files you wanted to use in your code, with the possibility to <a href="http://php.net/manual/en/language.oop5.autoload.php">write an autoloader</a> to handle it automatically when you call an undefined class. But managing these autoloaders is also a chore.</p>

<p>Composer helps here too, by automatically generating an autoloader that will be able to load your own code, and the code from all your dependencies. So you can get rid of your own autoloaders and <code>include</code> statements, and just include the Composer-generated autoloader in your code:</p>

<pre><code>require 'vendor/.composer/autoload.php';
</code></pre>

<p>After this all the classes you've stated your application needing will be available.</p>

<h2>Easy for developers</h2>

<p>While ease-of-installation is important, it isn't enough to build an ecosystem. The other thing that has to be easy is publishing code. Basically: <em>if you've written a piece of functionality in PHP that you could see yourself using in another project, it should be effortless to publish it as a library.</em></p>

<p>This is where approaches like PEAR mostly failed, by making it too cumbersome to define your packages, to build them, and to upload them to the repository.</p>

<p>With Composer <a href="http://packagist.org/about">this is very easy</a>. You again define a <code>composer.json</code> for your package, and push that to your project's Git repository. Then just <a href="http://packagist.org/packages/submit">register</a> the Git repository URL with packagist.org.</p>

<p>After this Packagist will spider your repository and make it available as a package.</p>

<p>Publishing new versions is very easy: simply keep your <code>composer.json</code> up-to-date, and <a href="http://learn.github.com/p/tagging.html">tag your releases</a> in Git.</p>

<h2>Where are we now?</h2>

<p>It is still early days for Composer, and <a href="https://github.com/composer/composer">the project</a> is being worked on at a hectic pace. However, it is already good enough for managing dependencies to modern, PSR-0 compatible libraries.</p>

<p>What I would like to see happen next is support for custom package roles and autoloaders. This would allow us to handle more specific cases, like for example installation of <a href="http://new.midgard-project.org/midgardmvc/#structure_of_a_component">Midgard MVC components</a> and their non-namespaced autoloading needs. After that we should be able to get rid of our custom installer code and just join the Composer crowd.</p>

<p>But if your code is already fully namespaced, this is a great time to get started with <a href="http://packagist.org/about-composer">Composer</a>.</p>
]]></content>
        <summary type="html"><![CDATA[

<p>In PHP we've had <a href="http://bergie.iki.fi/blog/php-finally_getting_an_ecosystem/">a lousy culture</a> of code-sharing. Because depending on code from others as been tricky, every major PHP application or framework has practically had to reimplement the whole world. Only some tools, like <a href="https://github.com/sebastianbergmann/phpunit/">PHPUnit</a>, have managed to break over this barrier and become de-facto standards across project boundaries. But for the rest: just write it yourself.</p>

<p>But now <a href="http://packagist.org/about-composer">Composer</a>, and its repository counterpart <a href="http://packagist.org/">Packagist</a>, promise to change all that. And obviously new conventions like PHP's <a href="http://www.php.net/manual/en/language.namespaces.rationale.php">namespacing support</a> and the <a href="https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md">PSR-0</a> standard autoloader help.</p>

<p>Composer is heavily inspired by <a href="http://npmjs.org/">NPM</a> which has built a strong culture of code-sharing and easy deployment in the Node.js community.</p>

<h2>Easy for users</h2>

<p>With Composer, managing dependencies in your project is very easy. Simply create a <code>composer.json</code> file where you state your dependencies, and let the package management system worry about the rest.</p>

<p>Packages that are registered with packagist.org are obviously easiest to depend on, but you can also state packages coming from custom repositories (like your company's internal version control system), or PHP extensions that you need.</p>

<p>Here is for example the <code>composer.json</code> from the <a href="https://github.com/bergie/phpcr-midgard2">Midgard PHPCR provider</a>:</p>

<pre><code>{
    "name": "midgard/phpcr",
    "type": "library",
    "require": {
        "php": "&gt;=5.3.0",
        "ext-midgard2": "&gt;=10.05.5",
        "phpcr/phpcr": "&gt;=2.1.0-beta1"
    }
}
</code></pre>

<p>With this file, Composer knows that our PHPCR provider runs only on PHP 5.3 or newer (as it uses namespaces), and that it needs the <a href="http://new.midgard-project.org/midgard2/">Midgard PHP extension</a> and the <a href="http://phpcr.github.com/">PHPCR interface classes</a> to be available.</p>

<p>Now installing the project is easy:</p>

<pre><code>$ wget http://getcomposer.org/composer.phar 
$ php composer.phar install
</code></pre>

<p>How about autoloading? Traditionally PHP required you to manually <code>include</code> or <code>require</code> all files you wanted to use in your code, with the possibility to <a href="http://php.net/manual/en/language.oop5.autoload.php">write an autoloader</a> to handle it automatically when you call an undefined class. But managing these autoloaders is also a chore.</p>

<p>Composer helps here too, by automatically generating an autoloader that will be able to load your own code, and the code from all your dependencies. So you can get rid of your own autoloaders and <code>include</code> statements, and just include the Composer-generated autoloader in your code:</p>

<pre><code>require 'vendor/.composer/autoload.php';
</code></pre>

<p>After this all the classes you've stated your application needing will be available.</p>

<h2>Easy for developers</h2>

<p>While ease-of-installation is important, it isn't enough to build an ecosystem. The other thing that has to be easy is publishing code. Basically: <em>if you've written a piece of functionality in PHP that you could see yourself using in another project, it should be effortless to publish it as a library.</em></p>

<p>This is where approaches like PEAR mostly failed, by making it too cumbersome to define your packages, to build them, and to upload them to the repository.</p>

<p>With Composer <a href="http://packagist.org/about">this is very easy</a>. You again define a <code>composer.json</code> for your package, and push that to your project's Git repository. Then just <a href="http://packagist.org/packages/submit">register</a> the Git repository URL with packagist.org.</p>

<p>After this Packagist will spider your repository and make it available as a package.</p>

<p>Publishing new versions is very easy: simply keep your <code>composer.json</code> up-to-date, and <a href="http://learn.github.com/p/tagging.html">tag your releases</a> in Git.</p>

<h2>Where are we now?</h2>

<p>It is still early days for Composer, and <a href="https://github.com/composer/composer">the project</a> is being worked on at a hectic pace. However, it is already good enough for managing dependencies to modern, PSR-0 compatible libraries.</p>

<p>What I would like to see happen next is support for custom package roles and autoloaders. This would allow us to handle more specific cases, like for example installation of <a href="http://new.midgard-project.org/midgardmvc/#structure_of_a_component">Midgard MVC components</a> and their non-namespaced autoloading needs. After that we should be able to get rid of our custom installer code and just join the Composer crowd.</p>

<p>But if your code is already fully namespaced, this is a great time to get started with <a href="http://packagist.org/about-composer">Composer</a>.</p>
]]></summary>
    </entry>
    <entry>
        <title>DNode: Make PHP and Node.js talk to each other</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/dnode-make_php_and_node-js_talk_to_each_other/"/>
        <published>2011-10-31T11:50:50+00:00</published>
        <updated>2011-10-31T11:50:50+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-fbc918a0053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>If you've been following my blog, you might have noticed that lately I've started doing quite a lot of <a href="http://nodejs.org/">Node.js</a> development alongside PHP. Based on conversations I've had in various conferences, I'm by far not alone in this situation - using Node.js for real-time functionality, and PHP (or Django, or Rails) for the more traditional CRUD stuff.</p>

<p>Both environments have their strong points. Node.js is very fast and flexible, but PHP has a lot more mature tools and libraries available. So in a lot of projects it is hard to choose between the two. But now you might not have to.</p>

<h2>Enter DNode</h2>

<p><a href="http://substack.net/posts/85e1bd/DNode-Asynchronous-Remote-Method-Invocation-for-Node-js-and-the-Browser">DNode</a> is a <em>remote method invocation</em> protocol originally written for Node.js, as the name probably tells. But as <a href="https://github.com/substack/dnode-protocol#readme">the protocol</a> itself is quite simple, just sending newline-terminated JSON packets over TCP connections, implementations have started popping up in other languages. You can talk DNode in <a href="https://github.com/substack/dnode-ruby">Ruby</a>, <a href="https://github.com/substack/dnode-perl">Perl</a>, <a href="https://github.com/jesusabdullah/dnode-python">Python</a>, <a href="https://github.com/aslakhellesoy/dnode-java">Java</a>, and now <a href="https://github.com/bergie/dnode-php">PHP</a>.</p>

<p>I started working on the PHP DNode implementation in the <a href="http://blog.liip.ch/archive/2011/09/30/symfony-cmf-hackday-october-22nd-in-cologne.html">Symfony CMF hackday</a> in Cologne a week ago, and got it into a running stage on a train ride from there to Paris. The implementation isn't yet complete, but works already quite well.</p>

<p>With DNode you can expose Node.js functions to be available on PHP, and PHP class methods to be available on Node.</p>

<p>Like most Node.js functionality, DNode works asynchronously. So instead of waiting for return values you supply a callback function that will be called when the method completes.</p>

<h2>PHP as client</h2>

<p>Here is a simple DNode service for Node.js:</p>

<pre><code>var dnode = require('dnode');
var server = dnode({
    zing: function (n, cb) { cb(n * 100) }
});
server.listen(7070);
</code></pre>

<p>This creates a DNode service running in TCP port 7070 that provides one method: <em>zing</em> that multiplies the value given to it by 100 and sends the result to the callback provided.</p>

<p>Calling this with PHP is easy:</p>

<pre><code>// Connect to DNode server running in port 7070 and call 
// Zing with argument 33
$dnode = new DNode\DNode();
$dnode-&gt;connect(7070, function($remote, $connection) {
    // Remote is a proxy object that provides us all methods
    // from the server
    $remote-&gt;zing(33, function($n) use ($connection) {
        echo "n = {$n}\n";
        // Once we have the result we can close the connection
        $connection-&gt;end();
    });
});
</code></pre>

<p>Now just start the server:</p>

<pre><code>$ node simple/server.js
</code></pre>

<p>And run the client. As you can see from the PHP code above, once we get the result the client will end the connection automatically:</p>

<pre><code>$ php examples/simple/client.php 
n = 3300
</code></pre>

<p>Because only simple TCP connections and JSON packets are used, this is quite fast. Here are time results for the client on my MacBook Air:</p>

<pre><code>real    0m0.064s
user    0m0.050s
sys     0m0.010s
</code></pre>

<h2>PHP as a server</h2>

<p>PHP can also act as a DNode server. You instantiate the DNode class and pass it the object you want to expose via DNode. All public methods of the object will be made available to the DNode clients:</p>

<pre><code>// This is the class we're exposing to DNode
class Zinger
{
    // Public methods are made available to the network
    public function zing($n, $cb)
    {
        // Dnode is async, so we return via callback
        $cb($n * 100);
    }
}

// Create a DNode server
$server = new DNode\DNode(new Zinger());
$server-&gt;listen(7070);
</code></pre>

<p>This DNode service will obviously be visible for both Node.js and PHP clients.</p>

<h2>Bidirectional communications</h2>

<p>A DNode client can also expose methods to the server. In this example the server provides functionality for converting temperatures from Celsius to Fahrenheit, but actually gets the current Celsius temperature by asking it from a client.</p>

<p>Server:</p>

<pre><code>// This is the class we're exposing to DNode
class Converter
{
    // Poll the client's own temperature() in celsius
    // and convert that value to fahrenheit in the supplied 
    // callback
    public function clientTempF($cb)
    {
        // The other side of DNode connection is exposed via
        // $this-&gt;remote proxy object
        $this-&gt;remote-&gt;temperature(function($degC) use ($cb) {
            $degF = round($degC * 9 / 5 + 32);
            $cb($degF);
        });
    }
}

// Create a DNode server that listens to port 6060
$server = new DNode\DNode(new Converter());
$server-&gt;listen(6060);
</code></pre>

<p>Client:</p>

<pre><code>// This is the class we're exposing to DNode
class Temp
{
    // Compute the client's temperature and stuff that value
    // into the callback
    public function temperature($cb)
    {
        $degC = rand(-20, 50);
        echo "{$degC}° C\n";
        $cb($degC);
    }
}

$dnode = new DNode\DNode(new Temp());
$dnode-&gt;connect(6060, function($remote, $connection) {
    // Ask server for temperature in Fahrenheit
    $remote-&gt;clientTempF(function($degF) use ($connection) {
        echo "{$degF}° F\n";
        // Close the connection
        $connection-&gt;end();
    });
});
</code></pre>

<p>Then just start the server:</p>

<pre><code>$ php examples/bidirectional/server.php
</code></pre>

<p>And run the client:</p>

<pre><code>$ php examples/bidirectional/client.php 
28° C
82° F
</code></pre>

<p>The same will obviously work with a Node.js client:</p>

<pre><code>$ node bidirectional/client.js 
23° C
73° F
</code></pre>

<h2>Installing DNode</h2>

<p>dnode-php can be installed using the <a href="http://packagist.org/">Composer</a> tool. You can either add <code>dnode/dnode</code> to your package dependencies, or if you want to install dnode-php as standalone, go to the main directory of its repository and run:</p>

<pre><code>$ wget http://getcomposer.org/composer.phar 
$ php composer.phar install
</code></pre>

<p>You can then use the composer-generated autoloader to access the DNode classes:</p>

<pre><code>require 'vendor/.composer/autoload.php';
</code></pre>

<p>Some DNode examples can be found from the <code>examples</code> folder. They are compatible with the similarly-named examples from <a href="https://github.com/substack/dnode">Node.js DNode</a>.</p>

<h2>Contributing</h2>

<p><a href="https://github.com/bergie/dnode-php">php-dnode</a> is developed under the MIT license in GitHub. If you're interested in it, please watch the repository and send issues or pull requests.</p>
]]></content>
        <summary type="html"><![CDATA[

<p>If you've been following my blog, you might have noticed that lately I've started doing quite a lot of <a href="http://nodejs.org/">Node.js</a> development alongside PHP. Based on conversations I've had in various conferences, I'm by far not alone in this situation - using Node.js for real-time functionality, and PHP (or Django, or Rails) for the more traditional CRUD stuff.</p>

<p>Both environments have their strong points. Node.js is very fast and flexible, but PHP has a lot more mature tools and libraries available. So in a lot of projects it is hard to choose between the two. But now you might not have to.</p>

<h2>Enter DNode</h2>

<p><a href="http://substack.net/posts/85e1bd/DNode-Asynchronous-Remote-Method-Invocation-for-Node-js-and-the-Browser">DNode</a> is a <em>remote method invocation</em> protocol originally written for Node.js, as the name probably tells. But as <a href="https://github.com/substack/dnode-protocol#readme">the protocol</a> itself is quite simple, just sending newline-terminated JSON packets over TCP connections, implementations have started popping up in other languages. You can talk DNode in <a href="https://github.com/substack/dnode-ruby">Ruby</a>, <a href="https://github.com/substack/dnode-perl">Perl</a>, <a href="https://github.com/jesusabdullah/dnode-python">Python</a>, <a href="https://github.com/aslakhellesoy/dnode-java">Java</a>, and now <a href="https://github.com/bergie/dnode-php">PHP</a>.</p>

<p>I started working on the PHP DNode implementation in the <a href="http://blog.liip.ch/archive/2011/09/30/symfony-cmf-hackday-october-22nd-in-cologne.html">Symfony CMF hackday</a> in Cologne a week ago, and got it into a running stage on a train ride from there to Paris. The implementation isn't yet complete, but works already quite well.</p>

<p>With DNode you can expose Node.js functions to be available on PHP, and PHP class methods to be available on Node.</p>

<p>Like most Node.js functionality, DNode works asynchronously. So instead of waiting for return values you supply a callback function that will be called when the method completes.</p>

<h2>PHP as client</h2>

<p>Here is a simple DNode service for Node.js:</p>

<pre><code>var dnode = require('dnode');
var server = dnode({
    zing: function (n, cb) { cb(n * 100) }
});
server.listen(7070);
</code></pre>

<p>This creates a DNode service running in TCP port 7070 that provides one method: <em>zing</em> that multiplies the value given to it by 100 and sends the result to the callback provided.</p>

<p>Calling this with PHP is easy:</p>

<pre><code>// Connect to DNode server running in port 7070 and call 
// Zing with argument 33
$dnode = new DNode\DNode();
$dnode-&gt;connect(7070, function($remote, $connection) {
    // Remote is a proxy object that provides us all methods
    // from the server
    $remote-&gt;zing(33, function($n) use ($connection) {
        echo "n = {$n}\n";
        // Once we have the result we can close the connection
        $connection-&gt;end();
    });
});
</code></pre>

<p>Now just start the server:</p>

<pre><code>$ node simple/server.js
</code></pre>

<p>And run the client. As you can see from the PHP code above, once we get the result the client will end the connection automatically:</p>

<pre><code>$ php examples/simple/client.php 
n = 3300
</code></pre>

<p>Because only simple TCP connections and JSON packets are used, this is quite fast. Here are time results for the client on my MacBook Air:</p>

<pre><code>real    0m0.064s
user    0m0.050s
sys     0m0.010s
</code></pre>

<h2>PHP as a server</h2>

<p>PHP can also act as a DNode server. You instantiate the DNode class and pass it the object you want to expose via DNode. All public methods of the object will be made available to the DNode clients:</p>

<pre><code>// This is the class we're exposing to DNode
class Zinger
{
    // Public methods are made available to the network
    public function zing($n, $cb)
    {
        // Dnode is async, so we return via callback
        $cb($n * 100);
    }
}

// Create a DNode server
$server = new DNode\DNode(new Zinger());
$server-&gt;listen(7070);
</code></pre>

<p>This DNode service will obviously be visible for both Node.js and PHP clients.</p>

<h2>Bidirectional communications</h2>

<p>A DNode client can also expose methods to the server. In this example the server provides functionality for converting temperatures from Celsius to Fahrenheit, but actually gets the current Celsius temperature by asking it from a client.</p>

<p>Server:</p>

<pre><code>// This is the class we're exposing to DNode
class Converter
{
    // Poll the client's own temperature() in celsius
    // and convert that value to fahrenheit in the supplied 
    // callback
    public function clientTempF($cb)
    {
        // The other side of DNode connection is exposed via
        // $this-&gt;remote proxy object
        $this-&gt;remote-&gt;temperature(function($degC) use ($cb) {
            $degF = round($degC * 9 / 5 + 32);
            $cb($degF);
        });
    }
}

// Create a DNode server that listens to port 6060
$server = new DNode\DNode(new Converter());
$server-&gt;listen(6060);
</code></pre>

<p>Client:</p>

<pre><code>// This is the class we're exposing to DNode
class Temp
{
    // Compute the client's temperature and stuff that value
    // into the callback
    public function temperature($cb)
    {
        $degC = rand(-20, 50);
        echo "{$degC}° C\n";
        $cb($degC);
    }
}

$dnode = new DNode\DNode(new Temp());
$dnode-&gt;connect(6060, function($remote, $connection) {
    // Ask server for temperature in Fahrenheit
    $remote-&gt;clientTempF(function($degF) use ($connection) {
        echo "{$degF}° F\n";
        // Close the connection
        $connection-&gt;end();
    });
});
</code></pre>

<p>Then just start the server:</p>

<pre><code>$ php examples/bidirectional/server.php
</code></pre>

<p>And run the client:</p>

<pre><code>$ php examples/bidirectional/client.php 
28° C
82° F
</code></pre>

<p>The same will obviously work with a Node.js client:</p>

<pre><code>$ node bidirectional/client.js 
23° C
73° F
</code></pre>

<h2>Installing DNode</h2>

<p>dnode-php can be installed using the <a href="http://packagist.org/">Composer</a> tool. You can either add <code>dnode/dnode</code> to your package dependencies, or if you want to install dnode-php as standalone, go to the main directory of its repository and run:</p>

<pre><code>$ wget http://getcomposer.org/composer.phar 
$ php composer.phar install
</code></pre>

<p>You can then use the composer-generated autoloader to access the DNode classes:</p>

<pre><code>require 'vendor/.composer/autoload.php';
</code></pre>

<p>Some DNode examples can be found from the <code>examples</code> folder. They are compatible with the similarly-named examples from <a href="https://github.com/substack/dnode">Node.js DNode</a>.</p>

<h2>Contributing</h2>

<p><a href="https://github.com/bergie/dnode-php">php-dnode</a> is developed under the MIT license in GitHub. If you're interested in it, please watch the repository and send issues or pull requests.</p>
]]></summary>
    </entry>
    <entry>
        <title>Where is the future for openness in mobile?</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/where_is_the_future_for_openness_in_mobile/"/>
        <published>2011-10-03T17:53:42+00:00</published>
        <updated>2011-10-03T17:53:42+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-f9affd68053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>These are tough times for fans of open mobile environments. Android is <a href="http://www.zdnet.com/blog/google/google-android-30-honeycomb-open-source-no-more/2845">less and less open</a>, Symbian <a href="http://symbian.nokia.com/blog/2011/04/04/not-open-source-just-open-for-business/">was closed again</a>, HP <a href="http://www.wired.com/gadgetlab/2011/08/hp-webos-tablet-touchpad">stopped making webOS devices</a>, and now Intel <a href="https://meego.com/community/blogs/imad/2011/whats-next-meego">abandoned MeeGo</a> to work with Samsung and operators instead. So, what is the community to do?</p>
<p>One option is to follow the lead of the big companies, hoping that <a href="https://www.tizen.org/">Tizen</a> works, or that Google again sees the benefit of working with others in the open.</p>
<p>The other is to take the matters in our own hands. There is precedent for this. Much of early Linux activity came from the efforts of the community, not on the initiative of corporate interests. And there have been <a href="http://wiki.openmoko.org/wiki/Main_Page">OpenMoko</a> and <a href="http://wiki.maemo.org/Mer">Mer</a>, the latter an attempt to make a fully open version of Nokia's Maemo environment, suspended when <a href="http://mer-project.blogspot.com/2010/02/mer-project-just-bunch-of-redshirts.html">MeeGo promised to bring the same benefits</a>.</p>
<p>Well, now <a href="http://lists.meego.com/pipermail/meego-dev/2011-October/484215.html">Mer is back</a>.</p>
<p><img src="http://bergie.iki.fi/static/1/1e0ede7a7914e20ede711e09b9da90a21eb97ea97ea_mer-400.jpg" border="0" alt="mer-400.jpg" title="mer-400.jpg" /></p>
<p>The goals for <a href="http://www.merproject.org/">Mer</a> align pretty well with what the community would need:</p>
<ul><li>To be openly developed and openly governed as a meritocracy</li>
<li>That primary customers of the platform are device vendors - not end-users.</li>
<li>To provide a device manufacturer oriented structure, processes and tools: make life easy for them</li>
<li>To have a device oriented architecture</li>
<li>To be inclusive of technologies (such as MeeGo/Tizen/Qt/EFL/HTML5)</li>
<li>To innovate in the mobile OS space</li>
</ul><p>There have also been some other invitations to new potential homes for the community, ranging from <a href="http://blog.jospoortvliet.com/2011/09/meego-and-opensuse-invitation.html">openSUSE</a> to <a href="http://losca.blogspot.com/2011/10/from-meego-to-tizen-debian.html">Debian</a>.</p>
<p>It will be interesting to see how this works out. But whatever we as a community do, we should ensure we look at <a href="http://bergie.iki.fi/blog/open_source-free_software-what_we_need_is_open_projects/">more than just licensing</a>.</p>]]></content>
        <summary type="html"><![CDATA[

<p>These are tough times for fans of open mobile environments. Android is <a href="http://www.zdnet.com/blog/google/google-android-30-honeycomb-open-source-no-more/2845">less and less open</a>, Symbian <a href="http://symbian.nokia.com/blog/2011/04/04/not-open-source-just-open-for-business/">was closed again</a>, HP <a href="http://www.wired.com/gadgetlab/2011/08/hp-webos-tablet-touchpad">stopped making webOS devices</a>, and now Intel <a href="https://meego.com/community/blogs/imad/2011/whats-next-meego">abandoned MeeGo</a> to work with Samsung and operators instead. So, what is the community to do?</p>
<p>One option is to follow the lead of the big companies, hoping that <a href="https://www.tizen.org/">Tizen</a> works, or that Google again sees the benefit of working with others in the open.</p>
<p>The other is to take the matters in our own hands. There is precedent for this. Much of early Linux activity came from the efforts of the community, not on the initiative of corporate interests. And there have been <a href="http://wiki.openmoko.org/wiki/Main_Page">OpenMoko</a> and <a href="http://wiki.maemo.org/Mer">Mer</a>, the latter an attempt to make a fully open version of Nokia's Maemo environment, suspended when <a href="http://mer-project.blogspot.com/2010/02/mer-project-just-bunch-of-redshirts.html">MeeGo promised to bring the same benefits</a>.</p>
<p>Well, now <a href="http://lists.meego.com/pipermail/meego-dev/2011-October/484215.html">Mer is back</a>.</p>
<p><img src="http://bergie.iki.fi/static/1/1e0ede7a7914e20ede711e09b9da90a21eb97ea97ea_mer-400.jpg" border="0" alt="mer-400.jpg" title="mer-400.jpg" /></p>
<p>The goals for <a href="http://www.merproject.org/">Mer</a> align pretty well with what the community would need:</p>
<ul><li>To be openly developed and openly governed as a meritocracy</li>
<li>That primary customers of the platform are device vendors - not end-users.</li>
<li>To provide a device manufacturer oriented structure, processes and tools: make life easy for them</li>
<li>To have a device oriented architecture</li>
<li>To be inclusive of technologies (such as MeeGo/Tizen/Qt/EFL/HTML5)</li>
<li>To innovate in the mobile OS space</li>
</ul><p>There have also been some other invitations to new potential homes for the community, ranging from <a href="http://blog.jospoortvliet.com/2011/09/meego-and-opensuse-invitation.html">openSUSE</a> to <a href="http://losca.blogspot.com/2011/10/from-meego-to-tizen-debian.html">Debian</a>.</p>
<p>It will be interesting to see how this works out. But whatever we as a community do, we should ensure we look at <a href="http://bergie.iki.fi/blog/open_source-free_software-what_we_need_is_open_projects/">more than just licensing</a>.</p>]]></summary>
    </entry>
    <entry>
        <title>Business analytics with CouchDB and NoFlo</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/business_analytics_with_couchdb_and_noflo/"/>
        <published>2011-09-21T17:52:53+00:00</published>
        <updated>2011-09-21T17:52:53+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-f7893a2c053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>The purpose of <a href="http://37signals.com/svn/posts/3002-the-three-secrets-of-business-analytics-no-rocket-science-here">business analytics</a> is to find data from the company's information systems that can be used to support decision making. What customers buy most? What do they do before a buying decision? What are the signs that a customer may be leaving?</p>

<p>For the last month we've been working in Salzburg to build such a system, the <a href="http://www.iks-project.eu/resources/intelligent-project-controlling-tool">Intelligent Project Controlling Tool</a> needed for running large collaborative research projects like <a href="http://www.iks-project.eu/">IKS</a>. Since the design we went with can be reused for other business analytics needs, I wanted to write a bit about it.</p>

<p>But first, here is how our system looks like:</p>

<p><img src="http://bergie.iki.fi/midcom-serveattachmentguid-1e0e47ad96fbfcee47a11e08d46e7126c9836c236c2/proggis-iks-projectplan-500.png" alt="Proggis displaying IKS project plan" title="" /></p>

<h2>Where does the data come from?</h2>

<p>There are many ways to gather business data. Often the information systems already contain the data needed. But it may also be hidden in a jungle of spreadsheets. Or maybe some data is simply not available, and has to be filled in manually.</p>

<p>Handling all these cases in one system is a tricky question. To solve it, we went with a two-layered strategy:</p>

<ul><li>All data used for analytics is stored as <a href="http://en.wikipedia.org/wiki/Linked_Data">Linked Data</a> in a CouchDB system</li>
<li>NoFlo workflows are used for gathering data from the diverse sources and convert it to the format needed</li>
</ul><p>In IKS's case, much of the data was available in a series of spreadsheets. With these, we built the necessary workflows for first converting the spreadsheets into XML with <a href="http://tika.apache.org/">Apache Tika</a>, and then extracting the information from them in a sensible subset of JSON-LD.</p>

<p>Because IKS is a collaborative project, information needs to be gathered from a diverse group of partner organizations. Some of them have systems that provide the needed APIs (like <a href="http://basecamphq.com/">Basecamp</a>, which <a href="http://nemein.com/en/">we</a> use), and we can just periodically import the data. But with many we decided on a simple data interchange approach: spreadsheets handled over email.</p>

<p>In this approach, user files a data request into the system. This gets picked up by NoFlo, which sends an email with the appropriate spreadsheet template to the partner. Then it starts waiting for a reply. When a reply arrives, it extracts the data from the attached spreadsheet and imports it to the system.</p>

<p>Our NoFlo processes are mostly initiated by the <a href="http://guide.couchdb.org/draft/notifications.html">CouchDB change notification API</a>. We keep them running persistently using <a href="http://blog.nodejitsu.com/keep-a-nodejs-server-up-with-forever">forever Node</a>, so whenever some operation needs to be run it happens nearly immediately.</p>

<h2>Ensuring data consistency</h2>

<p>With any automation, and especially with the email-based data interchange, things can go wrong. Because of this we tag all data that we receive with its origin, whether it was some automated operation or an imported spreadsheet. These origins are called <em>execution documents</em>. Users can browse all completed workflow executions and see what data came in from them. These can then be either accepted or rejected.</p>

<p>This way if some partner accidentally sends faulty data, or something else breaks, the incorrect information received can be easily removed. CouchDB's versioning capabilities help here.</p>

<h2>Analyzing the data</h2>

<p>CouchDB is built on top of the concept of map/reduce. Here you can modify and combine the data in lots of different ways using <a href="http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views">simple JavaScript functions</a>. In our case we elected to write all our CouchDB code in CoffeeScript for simplicity. For example, here is the reduce function in CoffeeScript that counts totals of time planned, time used, and time left per task or partner in a project:</p>

<pre><code>(keys, values, rereduce) -&gt;
    roundNumber = (rnum, rlength) -&gt;
        Math.round(parseFloat(rnum) * Math.pow(10, rlength)) / Math.pow(10, rlength)
    data =
        planned: 0.0
        spent: 0.0
        left: 0.0

    if rereduce
        for reducedData in values
            data.planned += reducedData.planned
            data.spent += reducedData.spent
        data.left = data.planned - data.spent
        return data

    for doc in values
        if doc['@type'] is 'effortallocation'
            data.planned += roundNumber doc.value, 1
        if doc['@type'] is 'effort'
            data.spent += roundNumber doc.value, 1
    data.left = roundNumber data.planned - data.spent, 1
    return data
</code></pre>

<p>If you figure out a new way to look at the data you have, simply write the needed map and reduce functions and save them into the database. CouchDB will then run them against existing data and produce numbers.</p>

<h2>Data visualizations</h2>

<p>Numbers are good, but to really see the information buried in them you need some visualizations. For this we decided to follow the <a href="http://couchapp.org/page/what-is-couchapp">CouchApp</a> idea where the user interface code is stored in the database together with the data itself. This way no application servers are needed, and you can take the whole system with you just by <a href="http://guide.couchdb.org/draft/replication.html">replicating the database</a>. Think of the possibility of doing some analysis on your company while flying to a meeting!</p>

<p>The visuals are in our case provided by <a href="http://thejit.org/">JavaScript InfoVis Toolkit</a>, a nice, MIT-licensed interactive graph library.</p>

<p>CouchDB views handle the number crunching, then CouchDB <a href="http://guide.couchdb.org/draft/transforming.html">list functions</a> process the numbers into the format needed for visualization. This leaves only a minimal amount of work for the client side.</p>

<p>For consistency <a href="https://github.com/IKS/Proggis">our application</a> has been built with <a href="https://github.com/andrzejsliwa/coffeeapp">CoffeeApp</a>, so all the database and user interface code is in <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a>.</p>

<h2>In a nutshell</h2>

<p>Any business analytics system dealing with moderate amounts of data can be built following this approach.</p>

<ul><li><a href="http://couchdb.apache.org/">Apache CouchDB</a> is the central data store</li>
<li>All data is stored as <a href="http://json-ld.org/">JSON-LD</a> entities</li>
<li><a href="https://github.com/bergie/noflo#readme">NoFlo</a> handles all data imports</li>
<li>Analytics based on the data are done with CouchDB map/reduce</li>
<li>Visualization happens with a CouchApp using <a href="http://thejit.org/">JavaScript InfoVis Toolkit</a></li>
</ul><p><img src="http://bergie.iki.fi/midcom-serveattachmentguid-1e0e47b247c04d2e47b11e08d46e7126c9836c236c2/proggis-architecture.png" alt="Simple architecture for a business analytics system" title="" /></p>

<p>This way you have a business analytics environment that is easy to extend with more data when it becomes available. New analysis can be done by writing reasonably simple map/reduce functions, and CouchDB's replication capabilities allow you to take the system and data with you.</p>

<p>Using JSON-LD for the data storage makes a lot of sense, as this way the relations between different pieces of information are easy to handle. And using URIs for data identifiers means you can easily mash up information coming from different sources together.</p>

<p>The two-layered approach of using NoFlo for data imports, and CouchDB for analysis also allows for clean separation of concerns. In our case, I did the workflow part of things, and <a href="https://github.com/szabyg">Szaby</a> built the visualizations.</p>
]]></content>
        <summary type="html"><![CDATA[

<p>The purpose of <a href="http://37signals.com/svn/posts/3002-the-three-secrets-of-business-analytics-no-rocket-science-here">business analytics</a> is to find data from the company's information systems that can be used to support decision making. What customers buy most? What do they do before a buying decision? What are the signs that a customer may be leaving?</p>

<p>For the last month we've been working in Salzburg to build such a system, the <a href="http://www.iks-project.eu/resources/intelligent-project-controlling-tool">Intelligent Project Controlling Tool</a> needed for running large collaborative research projects like <a href="http://www.iks-project.eu/">IKS</a>. Since the design we went with can be reused for other business analytics needs, I wanted to write a bit about it.</p>

<p>But first, here is how our system looks like:</p>

<p><img src="http://bergie.iki.fi/midcom-serveattachmentguid-1e0e47ad96fbfcee47a11e08d46e7126c9836c236c2/proggis-iks-projectplan-500.png" alt="Proggis displaying IKS project plan" title="" /></p>

<h2>Where does the data come from?</h2>

<p>There are many ways to gather business data. Often the information systems already contain the data needed. But it may also be hidden in a jungle of spreadsheets. Or maybe some data is simply not available, and has to be filled in manually.</p>

<p>Handling all these cases in one system is a tricky question. To solve it, we went with a two-layered strategy:</p>

<ul><li>All data used for analytics is stored as <a href="http://en.wikipedia.org/wiki/Linked_Data">Linked Data</a> in a CouchDB system</li>
<li>NoFlo workflows are used for gathering data from the diverse sources and convert it to the format needed</li>
</ul><p>In IKS's case, much of the data was available in a series of spreadsheets. With these, we built the necessary workflows for first converting the spreadsheets into XML with <a href="http://tika.apache.org/">Apache Tika</a>, and then extracting the information from them in a sensible subset of JSON-LD.</p>

<p>Because IKS is a collaborative project, information needs to be gathered from a diverse group of partner organizations. Some of them have systems that provide the needed APIs (like <a href="http://basecamphq.com/">Basecamp</a>, which <a href="http://nemein.com/en/">we</a> use), and we can just periodically import the data. But with many we decided on a simple data interchange approach: spreadsheets handled over email.</p>

<p>In this approach, user files a data request into the system. This gets picked up by NoFlo, which sends an email with the appropriate spreadsheet template to the partner. Then it starts waiting for a reply. When a reply arrives, it extracts the data from the attached spreadsheet and imports it to the system.</p>

<p>Our NoFlo processes are mostly initiated by the <a href="http://guide.couchdb.org/draft/notifications.html">CouchDB change notification API</a>. We keep them running persistently using <a href="http://blog.nodejitsu.com/keep-a-nodejs-server-up-with-forever">forever Node</a>, so whenever some operation needs to be run it happens nearly immediately.</p>

<h2>Ensuring data consistency</h2>

<p>With any automation, and especially with the email-based data interchange, things can go wrong. Because of this we tag all data that we receive with its origin, whether it was some automated operation or an imported spreadsheet. These origins are called <em>execution documents</em>. Users can browse all completed workflow executions and see what data came in from them. These can then be either accepted or rejected.</p>

<p>This way if some partner accidentally sends faulty data, or something else breaks, the incorrect information received can be easily removed. CouchDB's versioning capabilities help here.</p>

<h2>Analyzing the data</h2>

<p>CouchDB is built on top of the concept of map/reduce. Here you can modify and combine the data in lots of different ways using <a href="http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views">simple JavaScript functions</a>. In our case we elected to write all our CouchDB code in CoffeeScript for simplicity. For example, here is the reduce function in CoffeeScript that counts totals of time planned, time used, and time left per task or partner in a project:</p>

<pre><code>(keys, values, rereduce) -&gt;
    roundNumber = (rnum, rlength) -&gt;
        Math.round(parseFloat(rnum) * Math.pow(10, rlength)) / Math.pow(10, rlength)
    data =
        planned: 0.0
        spent: 0.0
        left: 0.0

    if rereduce
        for reducedData in values
            data.planned += reducedData.planned
            data.spent += reducedData.spent
        data.left = data.planned - data.spent
        return data

    for doc in values
        if doc['@type'] is 'effortallocation'
            data.planned += roundNumber doc.value, 1
        if doc['@type'] is 'effort'
            data.spent += roundNumber doc.value, 1
    data.left = roundNumber data.planned - data.spent, 1
    return data
</code></pre>

<p>If you figure out a new way to look at the data you have, simply write the needed map and reduce functions and save them into the database. CouchDB will then run them against existing data and produce numbers.</p>

<h2>Data visualizations</h2>

<p>Numbers are good, but to really see the information buried in them you need some visualizations. For this we decided to follow the <a href="http://couchapp.org/page/what-is-couchapp">CouchApp</a> idea where the user interface code is stored in the database together with the data itself. This way no application servers are needed, and you can take the whole system with you just by <a href="http://guide.couchdb.org/draft/replication.html">replicating the database</a>. Think of the possibility of doing some analysis on your company while flying to a meeting!</p>

<p>The visuals are in our case provided by <a href="http://thejit.org/">JavaScript InfoVis Toolkit</a>, a nice, MIT-licensed interactive graph library.</p>

<p>CouchDB views handle the number crunching, then CouchDB <a href="http://guide.couchdb.org/draft/transforming.html">list functions</a> process the numbers into the format needed for visualization. This leaves only a minimal amount of work for the client side.</p>

<p>For consistency <a href="https://github.com/IKS/Proggis">our application</a> has been built with <a href="https://github.com/andrzejsliwa/coffeeapp">CoffeeApp</a>, so all the database and user interface code is in <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a>.</p>

<h2>In a nutshell</h2>

<p>Any business analytics system dealing with moderate amounts of data can be built following this approach.</p>

<ul><li><a href="http://couchdb.apache.org/">Apache CouchDB</a> is the central data store</li>
<li>All data is stored as <a href="http://json-ld.org/">JSON-LD</a> entities</li>
<li><a href="https://github.com/bergie/noflo#readme">NoFlo</a> handles all data imports</li>
<li>Analytics based on the data are done with CouchDB map/reduce</li>
<li>Visualization happens with a CouchApp using <a href="http://thejit.org/">JavaScript InfoVis Toolkit</a></li>
</ul><p><img src="http://bergie.iki.fi/midcom-serveattachmentguid-1e0e47b247c04d2e47b11e08d46e7126c9836c236c2/proggis-architecture.png" alt="Simple architecture for a business analytics system" title="" /></p>

<p>This way you have a business analytics environment that is easy to extend with more data when it becomes available. New analysis can be done by writing reasonably simple map/reduce functions, and CouchDB's replication capabilities allow you to take the system and data with you.</p>

<p>Using JSON-LD for the data storage makes a lot of sense, as this way the relations between different pieces of information are easy to handle. And using URIs for data identifiers means you can easily mash up information coming from different sources together.</p>

<p>The two-layered approach of using NoFlo for data imports, and CouchDB for analysis also allows for clean separation of concerns. In our case, I did the workflow part of things, and <a href="https://github.com/szabyg">Szaby</a> built the visualizations.</p>
]]></summary>
    </entry>
    <entry>
        <title>VIE 2.0 is starting to emerge</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/vie_2-0_is_starting_to_emerge/"/>
        <published>2011-09-21T15:01:28+00:00</published>
        <updated>2011-09-21T15:01:28+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-f557c1ec053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p><a href="https://github.com/bergie/VIE#readme">VIE</a> is a JavaScript library that makes RDFa-annotated entities on web pages editable. We started the work towards the next major version of it, codenamed <a href="https://github.com/IKS/zart.js">Zart</a> (for Mozart) in a Salzburg IKS hackathon couple of weeks ago.</p>

<p><img src="https://github.com/bergie/VIE/raw/master/vie_logo_100.png" alt="VIE" title="" /></p>

<p>Yesterday I merged the Zart codebase into the <a href="https://github.com/bergie/VIE">VIE repository</a>. This blog post describes some of the improvements it brings.</p>

<h2>VIE now has an instance</h2>

<p>For VIE 1.x users the first visible change (and probably the only necessary API change) is that now VIE needs to be instantiated before being used. <a href="http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx">Singletons are evil</a>, and so we are not a singleton any longer.</p>

<p>So, for existing VIE code, you need to:</p>

<pre><code>var vie = new VIE();
// and then any traditional VIE calls, like:
var entities = vie.RDFaEntities.getInstances('div.article');
console.log("There are " + entities.length + " RDFa entities in your articles");
</code></pre>

<p>The VIE 1.0 API can be disabled by passing a setting when instantiating VIE:</p>

<pre><code>var vie = new VIE({classic: false});
</code></pre>

<h2>Services and VIE</h2>

<p>The other big change in VIE is that now the API has been built in a service-oriented manner. This means that for example reading and writing RDFa is just a service you can enable and disable at will.</p>

<p>The benefit here is that we can easily add support for other formats and capabilities without having to touch VIE internals. Thanks to the <a href="http://manu.sporny.org/2011/false-choice/">schema.org situation</a>, <a href="http://www.w3.org/TR/microdata/">Microdata</a> is getting more use, and so at some point we'll probably add a service for it.</p>

<p>Registering and accessing services is easy:</p>

<pre><code>// Instantiate VIE
var vie = new VIE();

// Pass the service instance and a name you want to use for it
vie.use(new vie.RdfaService, 'rdfa');

// Call a method from the service using the name
// this one would give us the RDF subject of the
// element matched by the jQuery selector
vie.service('rdfa').getElementSubject('div.article');
</code></pre>

<p>An immediate benefit here is that we can have two RDFa parsing implementations. If you have problems with our own custom jQuery-based RDFa parser, then you can use the more strict <a href="http://code.google.com/p/rdfquery/">rdfQuery</a> powered implementation instead:</p>

<pre><code>vie.use(new RdfaRdfQueryService, 'rdfa');
</code></pre>

<h2>Using deferreds</h2>

<p>For the new main VIE API we created a sort of a <a href="http://en.wikipedia.org/wiki/Domain-specific_language">Domain-Specific Language</a> for handling semantic entities. A core part of it is that now all operations utilize <a href="http://www.erichynds.com/jquery/using-deferreds-in-jquery/">jQuery's Deferred</a> objects. With them you can attach different callbacks to the results of your operation, and they will fire either when the operation completes, or immediately if the operation has already been run.</p>

<p>This gives a lot of flexibility in using the API, and allows us to provide same API for services that deal with the DOM, and services that talk to external APIs like <a href="http://incubator.apache.org/stanbol/">Stanbol</a>.</p>

<p>For example, parsing RDFa from a given DOM element (provided with a jQuery selector) happens like this:</p>

<pre><code>vie.load({
        element: 'div.article'
    }).
    from('rdfa').
    execute().
    done(function(entities) {
        console.log(entities);
    });
</code></pre>

<p>The chain here is: <em>operation</em> (in this case, load), <em>from service</em> (rdfa), <em>execute</em> operation, then when <em>done</em>, do <em>callback</em>.</p>

<p>With the RDFa service we register Backbone Views for the elements our entities came from, so just like with VIE 1.x, they will update automatically when you change the contents of your entities. But manual writing is also available in case you need it. Here is how it works:</p>

<pre><code>vie.save({
        element: 'div.article',
        entity: someBackboneModel
    }).
    to('rdfa').
    execute().
    done(function() {
        console.log("Saved!");
    });
</code></pre>

<p>In addition to <em>done</em>, which fires if the operation succeeds, you have <em>fail</em> for failed operations, and <em>then</em> which fires regardless of success or failure.</p>

<h2>Accessing external services</h2>

<p>The new VIE is not just about RDFa. In addition to working with the entities you have on a page, you can also access external repositories of semantic information, like <a href="http://dbpedia.org/About">DBpedia</a>.</p>

<p>For example, to find out everything that Wikipedia knows about Salzburg, you could run:</p>

<pre><code>vie.use(new vie.DBPediaService, 'dbpedia');
vie.load({
        entity: '&lt;http://dbpedia.org/resource/Salzburg&gt;'
    }).
    using('dbpedia').
    execute().
    done(function(entity) {
        console.log("This is what we know of Salzburg");
        console.log(entity);
    });
</code></pre>

<p>In browser usage these calls to external services are subject to cross-domain AJAX limitations. A way to work around those is to set up a proxy, and tell the DBpedia service to use that. To do this, pass the proxy URL to the service when instantiating:</p>

<pre><code>vie.use(new vie.DBPediaService({proxyUrl: 'http://localhost:8080'});
</code></pre>

<p>With this, all the factual information from Wikipedia will be at your disposal. The size of every city, the height of every mountain. Birthdates and places of birth for famous people. Your web app can do quite a bit with this information.</p>

<h3>Finding entities from text</h3>

<p><a href="http://incubator.apache.org/stanbol/">Apache Stanbol</a> is a semantic engine that can extract all kinds of entities from text documents. It can be used for auto-tagging and other things.</p>

<p>Here is how you can use it with VIE:</p>

<pre><code>vie.use(new vie.StanbolService, 'stanbol');
vie.analyze({
        element: 'div.article'
    }).
    using('stanbol').
    execute().
    done(function(entities) {
        console.log("We got the following enhancements for article content");
        console.log(entities);
    });
</code></pre>

<p>Stanbol can tell you what a piece of content talks about. People mentioned, places, concepts. It will also give you the language of the text.</p>

<h2>Moving forward</h2>

<p>The new version of VIE is still under heavy development. Most of the thngs work, but some details may still change. It is a good idea to start taking a look at it now, but before a beta release at least, <a href="https://github.com/bergie/VIE/tree/1.0.0">VIE 1.0</a> is the recommended tool to use.</p>

<p>If you already use VIE 1.0 for making your content editable, VIE 2.x will give you a lot of additional power. Enhancements, data queries, namespace handling, and much more.</p>

<p>Thanks to <a href="https://github.com/szabyg">Szaby</a> and <a href="https://github.com/neogermi">Sebastian</a> for helping to make this happen!</p>
]]></content>
        <summary type="html"><![CDATA[

<p><a href="https://github.com/bergie/VIE#readme">VIE</a> is a JavaScript library that makes RDFa-annotated entities on web pages editable. We started the work towards the next major version of it, codenamed <a href="https://github.com/IKS/zart.js">Zart</a> (for Mozart) in a Salzburg IKS hackathon couple of weeks ago.</p>

<p><img src="https://github.com/bergie/VIE/raw/master/vie_logo_100.png" alt="VIE" title="" /></p>

<p>Yesterday I merged the Zart codebase into the <a href="https://github.com/bergie/VIE">VIE repository</a>. This blog post describes some of the improvements it brings.</p>

<h2>VIE now has an instance</h2>

<p>For VIE 1.x users the first visible change (and probably the only necessary API change) is that now VIE needs to be instantiated before being used. <a href="http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx">Singletons are evil</a>, and so we are not a singleton any longer.</p>

<p>So, for existing VIE code, you need to:</p>

<pre><code>var vie = new VIE();
// and then any traditional VIE calls, like:
var entities = vie.RDFaEntities.getInstances('div.article');
console.log("There are " + entities.length + " RDFa entities in your articles");
</code></pre>

<p>The VIE 1.0 API can be disabled by passing a setting when instantiating VIE:</p>

<pre><code>var vie = new VIE({classic: false});
</code></pre>

<h2>Services and VIE</h2>

<p>The other big change in VIE is that now the API has been built in a service-oriented manner. This means that for example reading and writing RDFa is just a service you can enable and disable at will.</p>

<p>The benefit here is that we can easily add support for other formats and capabilities without having to touch VIE internals. Thanks to the <a href="http://manu.sporny.org/2011/false-choice/">schema.org situation</a>, <a href="http://www.w3.org/TR/microdata/">Microdata</a> is getting more use, and so at some point we'll probably add a service for it.</p>

<p>Registering and accessing services is easy:</p>

<pre><code>// Instantiate VIE
var vie = new VIE();

// Pass the service instance and a name you want to use for it
vie.use(new vie.RdfaService, 'rdfa');

// Call a method from the service using the name
// this one would give us the RDF subject of the
// element matched by the jQuery selector
vie.service('rdfa').getElementSubject('div.article');
</code></pre>

<p>An immediate benefit here is that we can have two RDFa parsing implementations. If you have problems with our own custom jQuery-based RDFa parser, then you can use the more strict <a href="http://code.google.com/p/rdfquery/">rdfQuery</a> powered implementation instead:</p>

<pre><code>vie.use(new RdfaRdfQueryService, 'rdfa');
</code></pre>

<h2>Using deferreds</h2>

<p>For the new main VIE API we created a sort of a <a href="http://en.wikipedia.org/wiki/Domain-specific_language">Domain-Specific Language</a> for handling semantic entities. A core part of it is that now all operations utilize <a href="http://www.erichynds.com/jquery/using-deferreds-in-jquery/">jQuery's Deferred</a> objects. With them you can attach different callbacks to the results of your operation, and they will fire either when the operation completes, or immediately if the operation has already been run.</p>

<p>This gives a lot of flexibility in using the API, and allows us to provide same API for services that deal with the DOM, and services that talk to external APIs like <a href="http://incubator.apache.org/stanbol/">Stanbol</a>.</p>

<p>For example, parsing RDFa from a given DOM element (provided with a jQuery selector) happens like this:</p>

<pre><code>vie.load({
        element: 'div.article'
    }).
    from('rdfa').
    execute().
    done(function(entities) {
        console.log(entities);
    });
</code></pre>

<p>The chain here is: <em>operation</em> (in this case, load), <em>from service</em> (rdfa), <em>execute</em> operation, then when <em>done</em>, do <em>callback</em>.</p>

<p>With the RDFa service we register Backbone Views for the elements our entities came from, so just like with VIE 1.x, they will update automatically when you change the contents of your entities. But manual writing is also available in case you need it. Here is how it works:</p>

<pre><code>vie.save({
        element: 'div.article',
        entity: someBackboneModel
    }).
    to('rdfa').
    execute().
    done(function() {
        console.log("Saved!");
    });
</code></pre>

<p>In addition to <em>done</em>, which fires if the operation succeeds, you have <em>fail</em> for failed operations, and <em>then</em> which fires regardless of success or failure.</p>

<h2>Accessing external services</h2>

<p>The new VIE is not just about RDFa. In addition to working with the entities you have on a page, you can also access external repositories of semantic information, like <a href="http://dbpedia.org/About">DBpedia</a>.</p>

<p>For example, to find out everything that Wikipedia knows about Salzburg, you could run:</p>

<pre><code>vie.use(new vie.DBPediaService, 'dbpedia');
vie.load({
        entity: '&lt;http://dbpedia.org/resource/Salzburg&gt;'
    }).
    using('dbpedia').
    execute().
    done(function(entity) {
        console.log("This is what we know of Salzburg");
        console.log(entity);
    });
</code></pre>

<p>In browser usage these calls to external services are subject to cross-domain AJAX limitations. A way to work around those is to set up a proxy, and tell the DBpedia service to use that. To do this, pass the proxy URL to the service when instantiating:</p>

<pre><code>vie.use(new vie.DBPediaService({proxyUrl: 'http://localhost:8080'});
</code></pre>

<p>With this, all the factual information from Wikipedia will be at your disposal. The size of every city, the height of every mountain. Birthdates and places of birth for famous people. Your web app can do quite a bit with this information.</p>

<h3>Finding entities from text</h3>

<p><a href="http://incubator.apache.org/stanbol/">Apache Stanbol</a> is a semantic engine that can extract all kinds of entities from text documents. It can be used for auto-tagging and other things.</p>

<p>Here is how you can use it with VIE:</p>

<pre><code>vie.use(new vie.StanbolService, 'stanbol');
vie.analyze({
        element: 'div.article'
    }).
    using('stanbol').
    execute().
    done(function(entities) {
        console.log("We got the following enhancements for article content");
        console.log(entities);
    });
</code></pre>

<p>Stanbol can tell you what a piece of content talks about. People mentioned, places, concepts. It will also give you the language of the text.</p>

<h2>Moving forward</h2>

<p>The new version of VIE is still under heavy development. Most of the thngs work, but some details may still change. It is a good idea to start taking a look at it now, but before a beta release at least, <a href="https://github.com/bergie/VIE/tree/1.0.0">VIE 1.0</a> is the recommended tool to use.</p>

<p>If you already use VIE 1.0 for making your content editable, VIE 2.x will give you a lot of additional power. Enhancements, data queries, namespace handling, and much more.</p>

<p>Thanks to <a href="https://github.com/szabyg">Szaby</a> and <a href="https://github.com/neogermi">Sebastian</a> for helping to make this happen!</p>
]]></summary>
    </entry>
    <entry>
        <title>Another django cms base</title>
        <link rel="alternate" type="text/html" href="http://g33kgnu3r.blogspot.com/2011/09/another-django-cms-base.html"/>
        <published>2011-09-13T10:35:00+00:00</published>
        <updated>2011-09-13T10:35:00+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-22c4e18c053111e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>avenpace0@0gmail.com (Uung Bhuwono)</name>
        </author>
        <category  term="feed:1f866c1c47c3ece3e467129251a9dca0" />
        <content type="html"><![CDATA[
Cooper-cms, a really simple cms built with django that probably  suitable for company site. It has testimonial, team, content and blog  (offcource :) ) modules. I know its not fancy as django-cms but it will  suit for some simple company site though 
https://bitbucket.org/avenpace/cooper-cms]]></content>
        <summary type="html"><![CDATA[
Cooper-cms, a really simple cms built with django that probably  suitable for company site. It has testimonial, team, content and blog  (offcource :) ) modules. I know its not fancy as django-cms but it will  suit for some simple company site though 
https://bitbucket.org/avenpace/cooper-cms]]></summary>
    </entry>
    <entry>
        <title>GObject Introspection is coming to Node.js</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/gobject_introspection_is_coming_to_node-js/"/>
        <published>2011-09-12T00:27:13+00:00</published>
        <updated>2011-09-12T00:27:13+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-f3636f6c053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p><a href="https://live.gnome.org/GObjectIntrospection">GObject Introspection</a> (GIR) is a way to create automatic bindings to <a href="http://developer.gnome.org/">GNOME libraries</a> for various different programming languages. I've written before about the <a href="http://bergie.iki.fi/blog/php_and_gobject_introspection/">benefits of bringing GIR to PHP</a>, and now it seems something similar is happening on <a href="http://nodejs.org/">Node.js</a>.</p>

<p><a href="https://github.com/creationix/node-gir">node-gir</a> has been written by <a href="https://github.com/creationix">Tim Caswell</a>, with help from <a href="https://github.com/swick">Sebastian Wick</a> and <a href="https://github.com/piotras">Piotr Pokora</a>.</p>

<p>I've been following the progress for a while, and today, during a flight from Helsinki to Salzburg, I was finally able to open a <a href="http://www.midgard-project.org/midgard2/">Midgard</a> repository connection with it. The API still is a bit weird, and lacks support for <a href="http://shinetech.com/thoughts/thought-articles/139-asynchronous-code-design-with-nodejs-">the asynchronous nature</a> of Node, but those will hopefully change soon. Quick example:</p>

<pre><code>var Midgard, gir, config, mgd;
gir = require("../gir");
gir.init();
Midgard = gir.load("Midgard");
Midgard.init();

// Use a local SQLite database file
config = new Midgard.Config();
config.__set_property__("dbdir", __dirname);
config.__set_property__("dbtype", "SQLite");
config.__set_property__("database", "midgard");

// Open connection to the database
mgd = new Midgard.Connection();
if (!mgd.__call__("open_config", config)) {
    console.error("Failed to open connection");
    process.exit();
}
</code></pre>

<p><a href="https://github.com/creationix/node-gir">node-gir is being developed on GitHub</a> if you want to lend a hand or try it out. To build it, run <code>npm install</code> and you should be able to run the <a href="https://github.com/swick/node-gir/tree/master/examples">code examples</a>.</p>

<p>Having GIR support for Node would make it a full-fledged GNOME environment, and mean that there would be proper GObject Introspection in all three major JavaScript runtimes - <a href="https://live.gnome.org/Gjs">SpiderMonkey</a>, <a href="https://live.gnome.org/Seed">JavaScriptCore</a> and <a href="https://github.com/creationix/node-gir">V8</a>. And this way GNOME JavaScript developers could also utilize the wealth of <a href="https://github.com/joyent/node/wiki/modules">existing Node.js modules</a>.</p>
]]></content>
        <summary type="html"><![CDATA[

<p><a href="https://live.gnome.org/GObjectIntrospection">GObject Introspection</a> (GIR) is a way to create automatic bindings to <a href="http://developer.gnome.org/">GNOME libraries</a> for various different programming languages. I've written before about the <a href="http://bergie.iki.fi/blog/php_and_gobject_introspection/">benefits of bringing GIR to PHP</a>, and now it seems something similar is happening on <a href="http://nodejs.org/">Node.js</a>.</p>

<p><a href="https://github.com/creationix/node-gir">node-gir</a> has been written by <a href="https://github.com/creationix">Tim Caswell</a>, with help from <a href="https://github.com/swick">Sebastian Wick</a> and <a href="https://github.com/piotras">Piotr Pokora</a>.</p>

<p>I've been following the progress for a while, and today, during a flight from Helsinki to Salzburg, I was finally able to open a <a href="http://www.midgard-project.org/midgard2/">Midgard</a> repository connection with it. The API still is a bit weird, and lacks support for <a href="http://shinetech.com/thoughts/thought-articles/139-asynchronous-code-design-with-nodejs-">the asynchronous nature</a> of Node, but those will hopefully change soon. Quick example:</p>

<pre><code>var Midgard, gir, config, mgd;
gir = require("../gir");
gir.init();
Midgard = gir.load("Midgard");
Midgard.init();

// Use a local SQLite database file
config = new Midgard.Config();
config.__set_property__("dbdir", __dirname);
config.__set_property__("dbtype", "SQLite");
config.__set_property__("database", "midgard");

// Open connection to the database
mgd = new Midgard.Connection();
if (!mgd.__call__("open_config", config)) {
    console.error("Failed to open connection");
    process.exit();
}
</code></pre>

<p><a href="https://github.com/creationix/node-gir">node-gir is being developed on GitHub</a> if you want to lend a hand or try it out. To build it, run <code>npm install</code> and you should be able to run the <a href="https://github.com/swick/node-gir/tree/master/examples">code examples</a>.</p>

<p>Having GIR support for Node would make it a full-fledged GNOME environment, and mean that there would be proper GObject Introspection in all three major JavaScript runtimes - <a href="https://live.gnome.org/Gjs">SpiderMonkey</a>, <a href="https://live.gnome.org/Seed">JavaScriptCore</a> and <a href="https://github.com/creationix/node-gir">V8</a>. And this way GNOME JavaScript developers could also utilize the wealth of <a href="https://github.com/joyent/node/wiki/modules">existing Node.js modules</a>.</p>
]]></summary>
    </entry>
    <entry>
        <title>Embrace and extend</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/embrace_and_extend/"/>
        <published>2011-09-11T23:14:02+00:00</published>
        <updated>2011-09-11T23:14:02+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-f1061580053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>I'm getting worried about Google. Long one of the champions of <a href="http://www.mozilla.org/about/manifesto.en.html">the open web</a> alongside Mozilla, the rise of <a href="http://www.facebook.com/">social networking silos</a> and the <a href="http://www.apple.com/iphone/apps-for-iphone/">app economy</a> seem to have scared them. And like any scared organism, they lash out.</p>

<p>Many of their plans to make web competitive against native development environments are good, there is indeed much to improve in the stack. But what I'm uneasy with is the unilateral way they go about it, preferring "big reveals" and post-facto standardization instead of <a href="http://www.wired.com/wired/archive/3.10/ietf.html">the open conversation</a> that built most of the Internet we have today. This is not the way <a href="http://bergie.iki.fi/blog/on_cross-project_collaboration/">to collaborate</a>.</p>

<p>Consider some of their recent efforts:</p>

<ul><li><a href="http://www.chromium.org/spdy/spdy-whitepaper">SPDY</a>, a protocol to replace HTTP which Web is built on. Currently only supported by Chrome, which uses it to talk to several Google services</li>
<li><a href="http://www.2ality.com/2011/09/google-dart.html">Dart</a>, their JavaScript-killer which recently surfaced through a <a href="http://news.ycombinator.com/item?id=2980267">leaked email</a></li>
<li><a href="http://manu.sporny.org/2011/false-choice/">Microdata and Schema.org</a> that seek to replace last ten years of semantic web development with a spec cooked up by couple of big vendors in secret</li>
</ul><p>These - together with <a href="http://en.wikipedia.org/wiki/Web_SQL_Database">WebSQL</a>, <a href="http://code.google.com/p/nativeclient/wiki/NativeClientInGoogleChrome">NaCl</a>, <a href="http://www.webmproject.org/">WebM</a> and <a href="http://code.google.com/speed/webp/">WebP</a> - mean that Google has active efforts to replace practically every layer of the web (except HTML itself) with something of their own design.</p>

<p>The way all of these were introduced bears strong reminders of how Microsoft tried to <a href="http://en.wikipedia.org/wiki/Embrace,_extend_and_extinguish">embrace, extend, and extinguish</a> the web in late 90s. That period brought horrors like ActiveX and the awful, unkillable IE6. Though, for the sake of fairness, it also brought us XmlHttpRequest which was the enabler of the AJAX revolution.</p>

<p>Google's new technologies may end up being beneficial for web developers, but they also threaten to fragment the platform. After all, as the competition in the <a href="http://bergie.iki.fi/blog/why_the_tablet_form_factor_is_winning/">"post-PC"</a> space heats up, the competitors are unlikely to embrace Google's extensions of the web stack. That would be a loss to all.</p>

<p><a href="http://brendaneich.com/">Brendan Eich</a>, the original author of JavaScript <a href="http://news.ycombinator.com/item?id=2982949">comments on Hacker News</a>:</p>

<blockquote>
  <p>So "Works best in Chrome" and even "Works only in Chrome" are new norms promulgated intentionally by Google. We see more of this fragmentation every day. As a user of Chrome and Firefox (and Safari), I find it painful to experience, never mind the political bad taste.</p>
  
  <p>Ok, counter-arguments. What's wrong with playing hardball to advance the web, you say? As my blog tries to explain, the standards process requires good social relations and philosophical balance among the participating competitors.</p>
  
  <p>Google's approach with Dart is thus pretty much all wrong and doomed to leave Dart in excellent yet non-standardized and non-interoperable implementation status. Dart is GBScript to NaCl/Pepper's ActiveG.</p>
</blockquote>

<p><em>Disclaimer: I've been a long-time fan of many of Google's services, and have visited some of their offices a few times. I like the company. Which is exactly why I'm so concerned about this unilateral approach at standards. I am also involved in some standards processes through the IKS Project.</em></p>
]]></content>
        <summary type="html"><![CDATA[

<p>I'm getting worried about Google. Long one of the champions of <a href="http://www.mozilla.org/about/manifesto.en.html">the open web</a> alongside Mozilla, the rise of <a href="http://www.facebook.com/">social networking silos</a> and the <a href="http://www.apple.com/iphone/apps-for-iphone/">app economy</a> seem to have scared them. And like any scared organism, they lash out.</p>

<p>Many of their plans to make web competitive against native development environments are good, there is indeed much to improve in the stack. But what I'm uneasy with is the unilateral way they go about it, preferring "big reveals" and post-facto standardization instead of <a href="http://www.wired.com/wired/archive/3.10/ietf.html">the open conversation</a> that built most of the Internet we have today. This is not the way <a href="http://bergie.iki.fi/blog/on_cross-project_collaboration/">to collaborate</a>.</p>

<p>Consider some of their recent efforts:</p>

<ul><li><a href="http://www.chromium.org/spdy/spdy-whitepaper">SPDY</a>, a protocol to replace HTTP which Web is built on. Currently only supported by Chrome, which uses it to talk to several Google services</li>
<li><a href="http://www.2ality.com/2011/09/google-dart.html">Dart</a>, their JavaScript-killer which recently surfaced through a <a href="http://news.ycombinator.com/item?id=2980267">leaked email</a></li>
<li><a href="http://manu.sporny.org/2011/false-choice/">Microdata and Schema.org</a> that seek to replace last ten years of semantic web development with a spec cooked up by couple of big vendors in secret</li>
</ul><p>These - together with <a href="http://en.wikipedia.org/wiki/Web_SQL_Database">WebSQL</a>, <a href="http://code.google.com/p/nativeclient/wiki/NativeClientInGoogleChrome">NaCl</a>, <a href="http://www.webmproject.org/">WebM</a> and <a href="http://code.google.com/speed/webp/">WebP</a> - mean that Google has active efforts to replace practically every layer of the web (except HTML itself) with something of their own design.</p>

<p>The way all of these were introduced bears strong reminders of how Microsoft tried to <a href="http://en.wikipedia.org/wiki/Embrace,_extend_and_extinguish">embrace, extend, and extinguish</a> the web in late 90s. That period brought horrors like ActiveX and the awful, unkillable IE6. Though, for the sake of fairness, it also brought us XmlHttpRequest which was the enabler of the AJAX revolution.</p>

<p>Google's new technologies may end up being beneficial for web developers, but they also threaten to fragment the platform. After all, as the competition in the <a href="http://bergie.iki.fi/blog/why_the_tablet_form_factor_is_winning/">"post-PC"</a> space heats up, the competitors are unlikely to embrace Google's extensions of the web stack. That would be a loss to all.</p>

<p><a href="http://brendaneich.com/">Brendan Eich</a>, the original author of JavaScript <a href="http://news.ycombinator.com/item?id=2982949">comments on Hacker News</a>:</p>

<blockquote>
  <p>So "Works best in Chrome" and even "Works only in Chrome" are new norms promulgated intentionally by Google. We see more of this fragmentation every day. As a user of Chrome and Firefox (and Safari), I find it painful to experience, never mind the political bad taste.</p>
  
  <p>Ok, counter-arguments. What's wrong with playing hardball to advance the web, you say? As my blog tries to explain, the standards process requires good social relations and philosophical balance among the participating competitors.</p>
  
  <p>Google's approach with Dart is thus pretty much all wrong and doomed to leave Dart in excellent yet non-standardized and non-interoperable implementation status. Dart is GBScript to NaCl/Pepper's ActiveG.</p>
</blockquote>

<p><em>Disclaimer: I've been a long-time fan of many of Google's services, and have visited some of their offices a few times. I like the company. Which is exactly why I'm so concerned about this unilateral approach at standards. I am also involved in some standards processes through the IKS Project.</em></p>
]]></summary>
    </entry>
    <entry>
        <title>Using LinkedIn for more business</title>
        <link rel="alternate" type="text/html" href="http://www.smallone.net/blog/using_linkedin_for_more_business/"/>
        <published>2011-09-08T09:57:00+00:00</published>
        <updated>2011-09-08T09:57:00+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-709341ba053111e1b43e8ffa2b7345c145c1</id>
        <author>
            <name>johan@bernhardsson.nu (Johan Bernhardsson)</name>
        </author>
        <category  term="feed:0e5d3b99667cce293d07bd863d81ca8f" />
        <content type="html"><![CDATA[
<div class="abstract">Using online forums can really generate business.</div>
<p>I have been quite lazy from time to time on social networks. Just being there was enough for me.</p>
<p>But is it really?</p>
<p>No one connects  with you just like that. You have to be commited to make something fo a tool. As an example. Just beacuse you install Word on your computer you wont get tons of documents. You still have to write them ...      <br /><br />So i decided some time ago to make somthing out of <a href="http://in.linkedin.com/profile/smallone" target="_blank" title="My profile">my profile</a>. Make it more interesting to people. People should want to connect with me when reading it.<br /><strong><br />Here are some small ways on how to get more out of your LinkedIn profile:</strong><br /><br /><strong>1. Connections</strong><br />If you connect with more people on LinkedIn you spread your message better. Even if its a person that wont buy your product or sell you something at the moment. The person will se your updates a<br />nd posts. This can lead to business in the future.<br /><strong><br />2. Groups</strong><br />You can get alot of connection in participating in groups. Groups that targets your business area. It can generate leads, give you new information and it also says some on what kind of person yo<br />u are and what you work with. (My own profile for example is mostly about systems administration and offshoring industry)<br /><br /><strong>3. Search engines</strong> <br />LinkedIn scores quite high on search engines. By keeping a good and updated profile with information on what you are doing will do good in promoting you and your company as a product.    <br /><br /><strong>4. Cross post content</strong><br />All your articles and updates you write should be cross posted across several networks. <a href="http://www.facebook.com/" target="_blank" title="Facebook">Facebook</a>, <a href="http://www.linkedin.com" target="_blank" title="LinkedIn">LinkedIn</a>, <a href="http://twitter.com" target="_blank" title="Twitter">Twitter</a> and more. That way your content is exposed to a broader audience and will make some points on all the search engines.<br /><strong><br />5. Building a good profile and what it can do for you.</strong><br />Your profile on LinkedIn is almost like your CV. It tells your visitors who you are and what you have accomplished workwise. It show your publications, your work history and recomendations from<br />others.<br /><br />In this way a good profile demonstrates knowledge and professionalism in a whole new way. It could generate more business for you by exposing you to wider audience. In the end it will make people more eager to connect with you and contact you for your services.<br /><strong><br />Final words.</strong><br />I know forums because it comes with my work some. But i have never really USED them i just have an account and log in from time to time.<br /><br />But now when i update them on a regular basis and really tend to them. It gives me new customers and a wider network. Securing a vital business for my company. It pays of in the end.</p>]]></content>
        <summary type="html"><![CDATA[
<div class="abstract">Using online forums can really generate business.</div>
<p>I have been quite lazy from time to time on social networks. Just being there was enough for me.</p>
<p>But is it really?</p>
<p>No one connects  with you just like that. You have to be commited to make something fo a tool. As an example. Just beacuse you install Word on your computer you wont get tons of documents. You still have to write them ...      <br /><br />So i decided some time ago to make somthing out of <a href="http://in.linkedin.com/profile/smallone" target="_blank" title="My profile">my profile</a>. Make it more interesting to people. People should want to connect with me when reading it.<br /><strong><br />Here are some small ways on how to get more out of your LinkedIn profile:</strong><br /><br /><strong>1. Connections</strong><br />If you connect with more people on LinkedIn you spread your message better. Even if its a person that wont buy your product or sell you something at the moment. The person will se your updates a<br />nd posts. This can lead to business in the future.<br /><strong><br />2. Groups</strong><br />You can get alot of connection in participating in groups. Groups that targets your business area. It can generate leads, give you new information and it also says some on what kind of person yo<br />u are and what you work with. (My own profile for example is mostly about systems administration and offshoring industry)<br /><br /><strong>3. Search engines</strong> <br />LinkedIn scores quite high on search engines. By keeping a good and updated profile with information on what you are doing will do good in promoting you and your company as a product.    <br /><br /><strong>4. Cross post content</strong><br />All your articles and updates you write should be cross posted across several networks. <a href="http://www.facebook.com/" target="_blank" title="Facebook">Facebook</a>, <a href="http://www.linkedin.com" target="_blank" title="LinkedIn">LinkedIn</a>, <a href="http://twitter.com" target="_blank" title="Twitter">Twitter</a> and more. That way your content is exposed to a broader audience and will make some points on all the search engines.<br /><strong><br />5. Building a good profile and what it can do for you.</strong><br />Your profile on LinkedIn is almost like your CV. It tells your visitors who you are and what you have accomplished workwise. It show your publications, your work history and recomendations from<br />others.<br /><br />In this way a good profile demonstrates knowledge and professionalism in a whole new way. It could generate more business for you by exposing you to wider audience. In the end it will make people more eager to connect with you and contact you for your services.<br /><strong><br />Final words.</strong><br />I know forums because it comes with my work some. But i have never really USED them i just have an account and log in from time to time.<br /><br />But now when i update them on a regular basis and really tend to them. It gives me new customers and a wider network. Securing a vital business for my company. It pays of in the end.</p>]]></summary>
    </entry>
    <entry>
        <title>Why the tablet form factor is winning</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/why_the_tablet_form_factor_is_winning/"/>
        <published>2011-09-05T15:30:31+00:00</published>
        <updated>2011-09-05T15:30:31+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-eed07af8053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>The press is writing a lot about a "post-PC ecosystem" these days, and while many dismiss tablets as simple toys, I think the world of computing is undergoing a major shift. Tablets may not be good for writing, but they are good, probably better than PCs for a lot of other things. And it turns out, people want to be doing these other things.</p>
<p>MG Siegler from TechCrunch has <a href="http://techcrunch.com/2011/09/02/post-pc-has-nothing-to-do-with-windows/">a great post on the subject</a>:</p>
<blockquote>
<p>...I’ve been trained over time to think that the traditional PC is the way to do these things whether it’s for work or play. That’s simply not true. The tablet form factor is so. much. better. when you don’t have to do an excessive amount of typing. And during downtime, when I use a computer like a more regular human being, I’ve found that’s often...</p>
<p>Computing is changing. That’s just about the most obvious statement ever. We’ve been seeing this for years with the rise of the smartphones. But <em>traditional</em> computing is changing as well. As in, people are abandoning PCs for these newer devices. And this will keep happening.</p>
</blockquote>
<p>My experience conforms with this. I rarely use my laptop outside of the work context of <em>writing code</em>, instead preferring to use the tablet with its great ergonomics, portability and long battery life. On some of my previous trips I noticed that already more than half of people sitting in airport lounges use a tablet instead of a laptop. Not bad for a product category that has existed in a mainstream manner for less than two years. <a href="http://bergie.iki.fi/blog/the_universal_communicator/">Nokia's internet tablets</a> blazed the trail years earlier, but were never marketed outside the geekdom.</p>
<p>Now, much of the attention in the tablet world has been focused on the couple of platforms that are winning in popularity, and therefore have most of the apps. But regardless of how well Apple and Google play their cards, <a href="http://www.asymco.com/2011/07/06/the-post-pc-era-will-be-a-multi-platform-era/">the post-PC world will be a multiplatform one</a>.</p>
<p>About a week after I got my webOS-powered TouchPad, HP went and <a href="http://www.wired.com/gadgetlab/2011/08/hp-webos-tablet-touchpad">killed the product</a>. Yet this hasn't made the device useless. As <a href="http://paulrouget.com/e/mobilewebapps/">Paul Rouget recently found out</a>, <em>as long as you have a good browser, your device will be relevant</em>.</p>
<blockquote>
<p>Some people can't or don't want to use Native Apps. Because their phones don't have Apps, or because there is just no good Apps for what they want to do, or because, well, because they don't need to...</p>
<p>While in the Western world we were looking at Apple bringing pretty Apps in an expensive device, in the Eastern world, Opera was bringing a working web browser to all the existing devices.</p>
</blockquote>
<p>This is the big opportunity for free software to remain relevant in an environment of highly-locked devices. Much of the web already runs on free components, and by using the web as <a href="http://bergie.iki.fi/blog/the_universal_runtime/">a universal runtime</a> we can bypass almost any platform restrictions. <a href="http://www.paulgraham.com/road.html">As Paul Graham wrote</a> back in 2001, <em>no one can break web applications without breaking browsing</em>.</p>
<p>The world of publishing is starting to understand this. Their revenue models can't take the heavy control that vendors like Apple imposes, and so <a href="https://read.amazon.com/about">Amazon's Kindle</a> is a web app, and <a href="http://apps.ft.com/ftwebapp/">so is Financial Times</a>. That<em> "Next year HTML5 will replace native apps" is the new "Next year will be the year of Linux on the desktop"</em> is <a href="https://twitter.com/jonlech/status/110598881049452545">already a Twitter joke</a>, but there is certainly some movement in this direction. And interestingly, the Linux desktop is actually <a href="http://blogs.gnome.org/xan/2011/08/31/web-application-mode-in-gnome-3-2/">becoming more web-savvy</a> and <a href="http://www.jonnor.com/2011/04/introducing-maliit-on-screen-keyboard-in-gnome-3/">touch-friendly</a>.</p>
<p>There are clearly sweet spots for something to be a web app, or for it to be a native application. Similarly, there are different situations where tablets will be the appropriate tool, and where PCs are. The tablet context will be more like this:</p>
<p><img src="http://bergie.iki.fi/static/1/1e0d7d53922345ed7d511e0af7669d1946e55d455d4_tablet-breakfast.jpg" border="0" alt="tablet-breakfast.jpg" title="tablet-breakfast.jpg" /></p>
<p>Than this:</p>
<p><img src="http://bergie.iki.fi/static/1/1e0d7d2eeae653ed7d211e0ad084b49cc799d7c9d7c_ipad-workstation.jpg" border="0" alt="ipad-workstation.jpg" title="ipad-workstation.jpg" /></p>
<p>The heavy lifting is a better fit for a system designed for that. As Steve Jobs said, <a href="http://lirneasia.net/2010/06/the-pc-is-a-truck-steve-jobs/">the PC will be the truck</a>.</p>]]></content>
        <summary type="html"><![CDATA[

<p>The press is writing a lot about a "post-PC ecosystem" these days, and while many dismiss tablets as simple toys, I think the world of computing is undergoing a major shift. Tablets may not be good for writing, but they are good, probably better than PCs for a lot of other things. And it turns out, people want to be doing these other things.</p>
<p>MG Siegler from TechCrunch has <a href="http://techcrunch.com/2011/09/02/post-pc-has-nothing-to-do-with-windows/">a great post on the subject</a>:</p>
<blockquote>
<p>...I’ve been trained over time to think that the traditional PC is the way to do these things whether it’s for work or play. That’s simply not true. The tablet form factor is so. much. better. when you don’t have to do an excessive amount of typing. And during downtime, when I use a computer like a more regular human being, I’ve found that’s often...</p>
<p>Computing is changing. That’s just about the most obvious statement ever. We’ve been seeing this for years with the rise of the smartphones. But <em>traditional</em> computing is changing as well. As in, people are abandoning PCs for these newer devices. And this will keep happening.</p>
</blockquote>
<p>My experience conforms with this. I rarely use my laptop outside of the work context of <em>writing code</em>, instead preferring to use the tablet with its great ergonomics, portability and long battery life. On some of my previous trips I noticed that already more than half of people sitting in airport lounges use a tablet instead of a laptop. Not bad for a product category that has existed in a mainstream manner for less than two years. <a href="http://bergie.iki.fi/blog/the_universal_communicator/">Nokia's internet tablets</a> blazed the trail years earlier, but were never marketed outside the geekdom.</p>
<p>Now, much of the attention in the tablet world has been focused on the couple of platforms that are winning in popularity, and therefore have most of the apps. But regardless of how well Apple and Google play their cards, <a href="http://www.asymco.com/2011/07/06/the-post-pc-era-will-be-a-multi-platform-era/">the post-PC world will be a multiplatform one</a>.</p>
<p>About a week after I got my webOS-powered TouchPad, HP went and <a href="http://www.wired.com/gadgetlab/2011/08/hp-webos-tablet-touchpad">killed the product</a>. Yet this hasn't made the device useless. As <a href="http://paulrouget.com/e/mobilewebapps/">Paul Rouget recently found out</a>, <em>as long as you have a good browser, your device will be relevant</em>.</p>
<blockquote>
<p>Some people can't or don't want to use Native Apps. Because their phones don't have Apps, or because there is just no good Apps for what they want to do, or because, well, because they don't need to...</p>
<p>While in the Western world we were looking at Apple bringing pretty Apps in an expensive device, in the Eastern world, Opera was bringing a working web browser to all the existing devices.</p>
</blockquote>
<p>This is the big opportunity for free software to remain relevant in an environment of highly-locked devices. Much of the web already runs on free components, and by using the web as <a href="http://bergie.iki.fi/blog/the_universal_runtime/">a universal runtime</a> we can bypass almost any platform restrictions. <a href="http://www.paulgraham.com/road.html">As Paul Graham wrote</a> back in 2001, <em>no one can break web applications without breaking browsing</em>.</p>
<p>The world of publishing is starting to understand this. Their revenue models can't take the heavy control that vendors like Apple imposes, and so <a href="https://read.amazon.com/about">Amazon's Kindle</a> is a web app, and <a href="http://apps.ft.com/ftwebapp/">so is Financial Times</a>. That<em> "Next year HTML5 will replace native apps" is the new "Next year will be the year of Linux on the desktop"</em> is <a href="https://twitter.com/jonlech/status/110598881049452545">already a Twitter joke</a>, but there is certainly some movement in this direction. And interestingly, the Linux desktop is actually <a href="http://blogs.gnome.org/xan/2011/08/31/web-application-mode-in-gnome-3-2/">becoming more web-savvy</a> and <a href="http://www.jonnor.com/2011/04/introducing-maliit-on-screen-keyboard-in-gnome-3/">touch-friendly</a>.</p>
<p>There are clearly sweet spots for something to be a web app, or for it to be a native application. Similarly, there are different situations where tablets will be the appropriate tool, and where PCs are. The tablet context will be more like this:</p>
<p><img src="http://bergie.iki.fi/static/1/1e0d7d53922345ed7d511e0af7669d1946e55d455d4_tablet-breakfast.jpg" border="0" alt="tablet-breakfast.jpg" title="tablet-breakfast.jpg" /></p>
<p>Than this:</p>
<p><img src="http://bergie.iki.fi/static/1/1e0d7d2eeae653ed7d211e0ad084b49cc799d7c9d7c_ipad-workstation.jpg" border="0" alt="ipad-workstation.jpg" title="ipad-workstation.jpg" /></p>
<p>The heavy lifting is a better fit for a system designed for that. As Steve Jobs said, <a href="http://lirneasia.net/2010/06/the-pc-is-a-truck-steve-jobs/">the PC will be the truck</a>.</p>]]></summary>
    </entry>
    <entry>
        <title>Nemein and Infigo merge to create a digital agency focused on web and mobile</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/nemein_and_infigo_merge/"/>
        <published>2011-09-02T11:15:37+00:00</published>
        <updated>2011-09-02T11:15:37+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-ec1cf548053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>Yesterday the contracts were signed to acquire <a href="http://infigo.fi/en/">Infigo</a> as part of <a href="http://nemein.com/en/">Nemein</a>. Infigo, is a consulting company focused on mobile development and web using open source tools. You'll probably at least know their CTO, <a href="http://bergie.iki.fi/blog/on_usb_fingers_and_world_news/">Jerry of the USB finger fame</a>.</p>
<p>Even in the <a href="http://bergie.iki.fi/blog/ten_years_of_nemein/">ten years of history</a> of our company this is quite a significant move - it allows us to combine Nemein's traditional expertise on content management with Infigo's mobile offerings. As smartphones and tablets are becoming popular, more and more services we build will have a mobile element, which is now easier with lots of in-house expertise.</p>
<p>This also means more focus on the interplay between the <a href="http://www.midgard-project.org/">Midgard</a> content repository, <a href="https://github.com/bergie/noflo">NoFlo</a> workflows, <a href="http://nodejs.org/">Node.js</a> and <a href="http://symfony.com/">Symfony</a> web services, and mobile applications built in <a href="http://qt.nokia.com/">Qt</a>.</p>
<p><img src="http://bergie.iki.fi/static/1/1e0d55317b0f154d55311e0a7e177ab46dbbff1bff1_nemein-infigo.jpg" border="0" alt="nemein-infigo.jpg" title="nemein-infigo.jpg" /></p>
<p><a href="http://infigo.fi/en/page/company/team">Petri Rajahalme</a> (with me in the photo) will be the CEO of the merged company, and I will focus on leading the R&amp;D efforts.</p>]]></content>
        <summary type="html"><![CDATA[

<p>Yesterday the contracts were signed to acquire <a href="http://infigo.fi/en/">Infigo</a> as part of <a href="http://nemein.com/en/">Nemein</a>. Infigo, is a consulting company focused on mobile development and web using open source tools. You'll probably at least know their CTO, <a href="http://bergie.iki.fi/blog/on_usb_fingers_and_world_news/">Jerry of the USB finger fame</a>.</p>
<p>Even in the <a href="http://bergie.iki.fi/blog/ten_years_of_nemein/">ten years of history</a> of our company this is quite a significant move - it allows us to combine Nemein's traditional expertise on content management with Infigo's mobile offerings. As smartphones and tablets are becoming popular, more and more services we build will have a mobile element, which is now easier with lots of in-house expertise.</p>
<p>This also means more focus on the interplay between the <a href="http://www.midgard-project.org/">Midgard</a> content repository, <a href="https://github.com/bergie/noflo">NoFlo</a> workflows, <a href="http://nodejs.org/">Node.js</a> and <a href="http://symfony.com/">Symfony</a> web services, and mobile applications built in <a href="http://qt.nokia.com/">Qt</a>.</p>
<p><img src="http://bergie.iki.fi/static/1/1e0d55317b0f154d55311e0a7e177ab46dbbff1bff1_nemein-infigo.jpg" border="0" alt="nemein-infigo.jpg" title="nemein-infigo.jpg" /></p>
<p><a href="http://infigo.fi/en/page/company/team">Petri Rajahalme</a> (with me in the photo) will be the CEO of the merged company, and I will focus on leading the R&amp;D efforts.</p>]]></summary>
    </entry>
    <entry>
        <title>python-oauth2 hack</title>
        <link rel="alternate" type="text/html" href="http://g33kgnu3r.blogspot.com/2011/08/python-oauth2-hack.html"/>
        <published>2011-08-21T13:13:00+00:00</published>
        <updated>2011-08-21T13:13:00+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-20402d36053111e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>avenpace0@0gmail.com (Uung Bhuwono)</name>
        </author>
        <category  term="feed:1f866c1c47c3ece3e467129251a9dca0" />
        <content type="html"><![CDATA[
When you are using python-oauth2 from simplegeo on your Google App Engine instance, you'll get some exception that cause by "ImportError: No module named httplib2"
Yes, apparently httplib2 are not supported by GAE and instead they oblige you to use google.appengine.api.urlfetch.fetch instead
So I hack python-oauth2 to use google.appengine.api.urlfetch.fetch
You can found my python-oauth2 fork on ]]></content>
        <summary type="html"><![CDATA[
When you are using python-oauth2 from simplegeo on your Google App Engine instance, you'll get some exception that cause by "ImportError: No module named httplib2"
Yes, apparently httplib2 are not supported by GAE and instead they oblige you to use google.appengine.api.urlfetch.fetch instead
So I hack python-oauth2 to use google.appengine.api.urlfetch.fetch
You can found my python-oauth2 fork on ]]></summary>
    </entry>
    <entry>
        <title>Flow-based programming for PHP</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/flow-based_programming_for_php/"/>
        <published>2011-08-18T13:07:34+00:00</published>
        <updated>2011-08-18T13:07:34+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-ea2b9690053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>You may have seen my earlier <a href="http://bergie.iki.fi/blog/desktop_summit_flow-based_programming/">post about NoFlo</a>, the <a href="http://en.wikipedia.org/wiki/Flow-based_programming">flow-based programming</a> tool I've written for Node.js. It allows you to do quite cool stuff, like <a href="http://universalruntime.tumblr.com/post/8998693776/node-js-powered-web-server-written-with-the-noflo">a visually controlled web server</a>:</p>

<p><img src="http://27.media.tumblr.com/tumblr_lq12x0Sf481qies3uo1_500.png" alt="NoFlo-powered web server" title="" /></p>

<p>Yesterday Igor Wiedler published <a href="https://github.com/igorw/Evenement">Evenement</a>, a PHP port of the EventEmitter class from Node.js. As <a href="https://github.com/bergie/noflo">NoFlo</a> builds quite heavily on EventEmitter, I decided to see how far the PHP port could be taken.</p>

<p>As result, there is now <a href="https://github.com/bergie/phpflo">PhpFlo</a>, a flow-based programming environment for PHP.</p>

<p>Example of how to define and run a flow (you can also use <a href="https://github.com/bergie/phpflo/blob/master/examples/linecount/count.json">a JSON format</a> for this):</p>

<pre><code>// Add nodes to the graph
$graph = new PhpFlo\Graph("linecount");
$graph-&gt;addNode("Read File", "ReadFile");
$graph-&gt;addNode("Split by Lines", "SplitStr");
$graph-&gt;addNode("Count Lines", "Counter");
$graph-&gt;addNode("Display", "Output");

// Add connections between nodes
$graph-&gt;addEdge("Read File", "out", "Split by Lines", "in");
$graph-&gt;addEdge("Read File", "error", "Display", "in");
$graph-&gt;addEdge("Split by Lines", "out", "Count Lines", "in");
$graph-&gt;addEdge("Count Lines", "count", "Display", "in");

// Kick-start the process by sending filename to Read File
$graph-&gt;addInitial($fileName, "Read File", "source");

// Make the graph "live"
$network = PhpFlo\Network::create($graph);
</code></pre>

<p>The flow consists of processes, or instances simple "black box" components that have their own defined input and output ports. Program logic is defined by making connections between them. Here is a simple component that reads the contents of a file:</p>

<pre><code>namespace PhpFlo\Component;
use PhpFlo\Component;
use PhpFlo\Port;
class ReadFile extends Component
{
    public function __construct()
    {
        $this-&gt;inPorts['source'] = new Port();
        $this-&gt;outPorts['out'] = new Port();
        $this-&gt;outPorts['error'] = new Port();

        $this-&gt;inPorts['source']-&gt;on('data', array($this, 'readFile'));
    }

    public function readFile($data)
    {
        if (!file_exists($data)) {
            $this-&gt;outPorts['error']-&gt;send("File {$data} doesn't exist");
            return;
        }

        $this-&gt;outPorts['out']-&gt;send(file_get_contents($data));
        $this-&gt;outPorts['out']-&gt;disconnect();
    }
}
</code></pre>

<p>I hope people find this system useful. If you're interested in FBP, then <a href="http://www.jpaulmorrison.com/fbp/#More">J. Paul Morrison's book</a> is a good place to start.</p>

<p>And if you're in <a href="http://froscon.de/">FrOSCon</a>, feel free to come and chat with me :-)</p>
]]></content>
        <summary type="html"><![CDATA[

<p>You may have seen my earlier <a href="http://bergie.iki.fi/blog/desktop_summit_flow-based_programming/">post about NoFlo</a>, the <a href="http://en.wikipedia.org/wiki/Flow-based_programming">flow-based programming</a> tool I've written for Node.js. It allows you to do quite cool stuff, like <a href="http://universalruntime.tumblr.com/post/8998693776/node-js-powered-web-server-written-with-the-noflo">a visually controlled web server</a>:</p>

<p><img src="http://27.media.tumblr.com/tumblr_lq12x0Sf481qies3uo1_500.png" alt="NoFlo-powered web server" title="" /></p>

<p>Yesterday Igor Wiedler published <a href="https://github.com/igorw/Evenement">Evenement</a>, a PHP port of the EventEmitter class from Node.js. As <a href="https://github.com/bergie/noflo">NoFlo</a> builds quite heavily on EventEmitter, I decided to see how far the PHP port could be taken.</p>

<p>As result, there is now <a href="https://github.com/bergie/phpflo">PhpFlo</a>, a flow-based programming environment for PHP.</p>

<p>Example of how to define and run a flow (you can also use <a href="https://github.com/bergie/phpflo/blob/master/examples/linecount/count.json">a JSON format</a> for this):</p>

<pre><code>// Add nodes to the graph
$graph = new PhpFlo\Graph("linecount");
$graph-&gt;addNode("Read File", "ReadFile");
$graph-&gt;addNode("Split by Lines", "SplitStr");
$graph-&gt;addNode("Count Lines", "Counter");
$graph-&gt;addNode("Display", "Output");

// Add connections between nodes
$graph-&gt;addEdge("Read File", "out", "Split by Lines", "in");
$graph-&gt;addEdge("Read File", "error", "Display", "in");
$graph-&gt;addEdge("Split by Lines", "out", "Count Lines", "in");
$graph-&gt;addEdge("Count Lines", "count", "Display", "in");

// Kick-start the process by sending filename to Read File
$graph-&gt;addInitial($fileName, "Read File", "source");

// Make the graph "live"
$network = PhpFlo\Network::create($graph);
</code></pre>

<p>The flow consists of processes, or instances simple "black box" components that have their own defined input and output ports. Program logic is defined by making connections between them. Here is a simple component that reads the contents of a file:</p>

<pre><code>namespace PhpFlo\Component;
use PhpFlo\Component;
use PhpFlo\Port;
class ReadFile extends Component
{
    public function __construct()
    {
        $this-&gt;inPorts['source'] = new Port();
        $this-&gt;outPorts['out'] = new Port();
        $this-&gt;outPorts['error'] = new Port();

        $this-&gt;inPorts['source']-&gt;on('data', array($this, 'readFile'));
    }

    public function readFile($data)
    {
        if (!file_exists($data)) {
            $this-&gt;outPorts['error']-&gt;send("File {$data} doesn't exist");
            return;
        }

        $this-&gt;outPorts['out']-&gt;send(file_get_contents($data));
        $this-&gt;outPorts['out']-&gt;disconnect();
    }
}
</code></pre>

<p>I hope people find this system useful. If you're interested in FBP, then <a href="http://www.jpaulmorrison.com/fbp/#More">J. Paul Morrison's book</a> is a good place to start.</p>

<p>And if you're in <a href="http://froscon.de/">FrOSCon</a>, feel free to come and chat with me :-)</p>
]]></summary>
    </entry>
    <entry>
        <title>Symfony2 for Midgard Developers</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/symfony2_for_midgard_developers/"/>
        <published>2011-08-16T17:18:49+00:00</published>
        <updated>2011-08-16T17:18:49+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-e7c9b2b0053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p><a href="http://nemein.com/en/">We</a> hosted a full-day <a href="http://symfony.com/">Symfony2</a> workshop for some of the Finnish Midgard developer community today. As I've written before, Midgard is now <a href="http://bergie.iki.fi/blog/midgard_in_the_symfony2_world/">transitioning to Symfony2</a> as our PHP web framework of choice, and this workshop was organized to support that.</p> 
 
<div style="width:425px" id="__ss_8866106"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/bergie/symfony2-for-midgard-developers" title="Symfony2 for Midgard Developers" target="_blank">Symfony2 for Midgard Developers</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/8866106" 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/bergie" target="_blank">Henri Bergius</a> </div> </div>
 
<p>Subjects discussed included:</p> 
 
<ul><li>Symfony2 as a central PHP ecosystem</li> 
<li>Basic ideas behind Symfony2</li> 
<li>Introduction to PHP namespaces</li> 
<li>Installation with Symfony Standard Edition</li> 
<li>Running Symfony2 with AppServer-in-PHP</li> 
<li>Creating a new Bundle</li> 
<li>Templating in Symfony2</li> 
<li>Routing in Symfony2</li> 
<li>Using the Midgard content repository with Symfony2</li> 
<li>Running MidCOM components inside Symfony2</li> 
</ul><p>You can also find the <a href="https://live.gnome.org/Pinpoint">Pinpoint</a> sources for the tutorial <a href="https://github.com/bergie/Symfony2ForMidgardians">from GitHub</a>. I'll try to keep them updated for future use.</p>]]></content>
        <summary type="html"><![CDATA[

<p><a href="http://nemein.com/en/">We</a> hosted a full-day <a href="http://symfony.com/">Symfony2</a> workshop for some of the Finnish Midgard developer community today. As I've written before, Midgard is now <a href="http://bergie.iki.fi/blog/midgard_in_the_symfony2_world/">transitioning to Symfony2</a> as our PHP web framework of choice, and this workshop was organized to support that.</p> 
 
<div style="width:425px" id="__ss_8866106"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/bergie/symfony2-for-midgard-developers" title="Symfony2 for Midgard Developers" target="_blank">Symfony2 for Midgard Developers</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/8866106" 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/bergie" target="_blank">Henri Bergius</a> </div> </div>
 
<p>Subjects discussed included:</p> 
 
<ul><li>Symfony2 as a central PHP ecosystem</li> 
<li>Basic ideas behind Symfony2</li> 
<li>Introduction to PHP namespaces</li> 
<li>Installation with Symfony Standard Edition</li> 
<li>Running Symfony2 with AppServer-in-PHP</li> 
<li>Creating a new Bundle</li> 
<li>Templating in Symfony2</li> 
<li>Routing in Symfony2</li> 
<li>Using the Midgard content repository with Symfony2</li> 
<li>Running MidCOM components inside Symfony2</li> 
</ul><p>You can also find the <a href="https://live.gnome.org/Pinpoint">Pinpoint</a> sources for the tutorial <a href="https://github.com/bergie/Symfony2ForMidgardians">from GitHub</a>. I'll try to keep them updated for future use.</p>]]></summary>
    </entry>
    <entry>
        <title>Some notes from Desktop Summit 2011</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/some_notes_from_desktop_summit_2011/"/>
        <published>2011-08-11T16:18:35+00:00</published>
        <updated>2011-08-11T16:18:35+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-e5982472053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>As usual, <a href="https://desktopsummit.org/">Desktop Summit 2011</a> has been a lot of fun. I've been to most of the GUADEC and aKademy free desktop events in the past few years, but this was the first time I didn't give a talk. Even that way, it was definitely worth spending a week in Berlin.</p>

<p>While much of the corporate involvement around the desktops has evaporated through some recent events, this seems to have given the developers lots more creative freedom. I've seen many very promising concepts from both communities.</p>

<p>Here are some things that happened during the week:</p>

<ul><li>The <em><a href="http://lists.midgard-project.org/pipermail/dev/2011-August/003045.html">roadmap for Midgard</a></em> to become closer to the JCR specification solidified, including a reasonably good plan on backwards compatibility</li>
<li>We published the first version of <a href="https://github.com/midgardproject/GICR">GICR</a>, generic <em>Content Repository interfaces for GObject</em>. Midgard will probably be the first project to implement them, but we hope others will follow. It'd be a great fit for <a href="https://live.gnome.org/Design/Apps/Documents">GNOME Documents</a>, among other things</li>
<li>The project to replace our own PHP frameworks with <em><a href="http://symfony.com/">Symfony2</a></em> continued by implementing the <a href="https://github.com/bergie/MidgardMidcomCompatBundle">MidCOM compatibility layer</a> that will allow Midgard1 web applications to be run in the new environment</li>
<li>My work on the <em><a href="https://github.com/bergie/noflo">NoFlo</a> flow-based programming tool</em> got some positive attention and interest. Still lot of stuff to do</li>
<li>We at <a href="http://nemein.com/">Nemein</a> co-sponsored the <em><a href="https://live.gnome.org/Hackfests/Introspection2011">GObject Introspection hackfest</a></em>. <a href="https://live.gnome.org/GObjectIntrospection/">GIR</a> is important for bringing GNOME libraries to new environments like scripting languages and the web</li>
<li><em>Lots of ice cream</em> got eaten. I think it will be fair if I stay out of next year's deathmatch and focus on coaching ;-)</li>
</ul><p>Tomorrow back to Helsinki for a week, then onwards to <a href="http://froscon.de/">FrOSCon</a> and Salzburg...</p>
]]></content>
        <summary type="html"><![CDATA[

<p>As usual, <a href="https://desktopsummit.org/">Desktop Summit 2011</a> has been a lot of fun. I've been to most of the GUADEC and aKademy free desktop events in the past few years, but this was the first time I didn't give a talk. Even that way, it was definitely worth spending a week in Berlin.</p>

<p>While much of the corporate involvement around the desktops has evaporated through some recent events, this seems to have given the developers lots more creative freedom. I've seen many very promising concepts from both communities.</p>

<p>Here are some things that happened during the week:</p>

<ul><li>The <em><a href="http://lists.midgard-project.org/pipermail/dev/2011-August/003045.html">roadmap for Midgard</a></em> to become closer to the JCR specification solidified, including a reasonably good plan on backwards compatibility</li>
<li>We published the first version of <a href="https://github.com/midgardproject/GICR">GICR</a>, generic <em>Content Repository interfaces for GObject</em>. Midgard will probably be the first project to implement them, but we hope others will follow. It'd be a great fit for <a href="https://live.gnome.org/Design/Apps/Documents">GNOME Documents</a>, among other things</li>
<li>The project to replace our own PHP frameworks with <em><a href="http://symfony.com/">Symfony2</a></em> continued by implementing the <a href="https://github.com/bergie/MidgardMidcomCompatBundle">MidCOM compatibility layer</a> that will allow Midgard1 web applications to be run in the new environment</li>
<li>My work on the <em><a href="https://github.com/bergie/noflo">NoFlo</a> flow-based programming tool</em> got some positive attention and interest. Still lot of stuff to do</li>
<li>We at <a href="http://nemein.com/">Nemein</a> co-sponsored the <em><a href="https://live.gnome.org/Hackfests/Introspection2011">GObject Introspection hackfest</a></em>. <a href="https://live.gnome.org/GObjectIntrospection/">GIR</a> is important for bringing GNOME libraries to new environments like scripting languages and the web</li>
<li><em>Lots of ice cream</em> got eaten. I think it will be fair if I stay out of next year's deathmatch and focus on coaching ;-)</li>
</ul><p>Tomorrow back to Helsinki for a week, then onwards to <a href="http://froscon.de/">FrOSCon</a> and Salzburg...</p>
]]></summary>
    </entry>
    <entry>
        <title>django realtime currency rate</title>
        <link rel="alternate" type="text/html" href="http://g33kgnu3r.blogspot.com/2011/08/django-realtime-currency-rate.html"/>
        <published>2011-08-09T23:33:00+00:00</published>
        <updated>2011-08-09T23:33:00+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-1c1a1c44053111e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>avenpace0@0gmail.com (Uung Bhuwono)</name>
        </author>
        <category  term="feed:1f866c1c47c3ece3e467129251a9dca0" />
        <content type="html"><![CDATA[
Its been a really long time since I post something here 
For some dumb reason, I forgot my blogger login/password :hammer: 
Anyway, since I'm now heavily work with django stuff 
Here are some django related projects that hopefully can benefit anyone who need it 

* django-currency_rate, simple django app that can give you realtime currency rate base on  http://themoneyconverter.com. Owh its even ]]></content>
        <summary type="html"><![CDATA[
Its been a really long time since I post something here 
For some dumb reason, I forgot my blogger login/password :hammer: 
Anyway, since I'm now heavily work with django stuff 
Here are some django related projects that hopefully can benefit anyone who need it 

* django-currency_rate, simple django app that can give you realtime currency rate base on  http://themoneyconverter.com. Owh its even ]]></summary>
    </entry>
    <entry>
        <title>Desktop Summit, and some thoughts on Flow-Based Programming</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/desktop_summit_flow-based_programming/"/>
        <published>2011-08-06T15:09:59+00:00</published>
        <updated>2011-08-06T15:09:59+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-e39ec39c053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>Like many, I'm currently in Berlin for <a href="https://desktopsummit.org/">Desktop Summit</a>, the combined conference of the GNOME and KDE communities. It is a lot of fun to see all the familiar faces, and talk about the different projects going on!</p>
<p><img src="https://www.desktopsummit.org/sites/www.desktopsummit.org/files/DS2011banner.png" border="0" alt="DS2011banner.png" /></p>
<p>Now, one of the things I've talked about with people is <a href="https://github.com/bergie/noflo">NoFlo</a>, my new tool that brings <em>Flow-Based Programming</em> to <a href="http://nodejs.org/">Node.js</a>. What is that? <a href="http://en.wikipedia.org/wiki/Flow-based_programming">Wikipedia explains</a>:</p>
<blockquote>Flow-based programming (FBP) is a programming paradigm that defines applications as networks of "black box" processes, which exchange data across predefined connections by message passing, where the connections are specified externally to the processes. These black box processes can be reconnected endlessly to form different applications without having to be changed internally. FBP is thus naturally component-oriented.</blockquote>
<p>Basically the idea here is to simplify managing the control flow of software: what data goes where, what happens then, etc. with the goal of making software more understandable. With NoFlo you can go and peek under the hood of a running piece of software, see where data is going to, and even rewire some connections if you want to.</p>
<p>The project is still in reasonably early stages, but it is already used in at least one real-life deployment. Here are some sneak peeks:</p>
<p><img src="http://bergie.iki.fi/static/1/1e0c03da3d93d7ec03d11e0ad7493d9595d183c183c_noflo-shell-small.png" border="0" alt="noflo-shell-small.png" title="noflo-shell-small.png" />:</p>
<p><img src="http://bergie.iki.fi/static/1/1e0c03dc1eb3d1cc03d11e0853e692a724efbc6fbc6_noflo-gui-small.png" border="0" alt="noflo-gui-small.png" title="noflo-gui-small.png" /></p>
<p>If you're interested, follow the progress on <a href="https://github.com/bergie/noflo">my GitHub repo</a>, or subscribe to the <a href="http://groups.google.com/group/flow-based-programming">Flow-Based Programming mailing list</a>.</p>
<p>In the spirit of Desktop Summit, it would be interesting to talk how these workflows would fit into the concept of a free software desktop.</p>]]></content>
        <summary type="html"><![CDATA[

<p>Like many, I'm currently in Berlin for <a href="https://desktopsummit.org/">Desktop Summit</a>, the combined conference of the GNOME and KDE communities. It is a lot of fun to see all the familiar faces, and talk about the different projects going on!</p>
<p><img src="https://www.desktopsummit.org/sites/www.desktopsummit.org/files/DS2011banner.png" border="0" alt="DS2011banner.png" /></p>
<p>Now, one of the things I've talked about with people is <a href="https://github.com/bergie/noflo">NoFlo</a>, my new tool that brings <em>Flow-Based Programming</em> to <a href="http://nodejs.org/">Node.js</a>. What is that? <a href="http://en.wikipedia.org/wiki/Flow-based_programming">Wikipedia explains</a>:</p>
<blockquote>Flow-based programming (FBP) is a programming paradigm that defines applications as networks of "black box" processes, which exchange data across predefined connections by message passing, where the connections are specified externally to the processes. These black box processes can be reconnected endlessly to form different applications without having to be changed internally. FBP is thus naturally component-oriented.</blockquote>
<p>Basically the idea here is to simplify managing the control flow of software: what data goes where, what happens then, etc. with the goal of making software more understandable. With NoFlo you can go and peek under the hood of a running piece of software, see where data is going to, and even rewire some connections if you want to.</p>
<p>The project is still in reasonably early stages, but it is already used in at least one real-life deployment. Here are some sneak peeks:</p>
<p><img src="http://bergie.iki.fi/static/1/1e0c03da3d93d7ec03d11e0ad7493d9595d183c183c_noflo-shell-small.png" border="0" alt="noflo-shell-small.png" title="noflo-shell-small.png" />:</p>
<p><img src="http://bergie.iki.fi/static/1/1e0c03dc1eb3d1cc03d11e0853e692a724efbc6fbc6_noflo-gui-small.png" border="0" alt="noflo-gui-small.png" title="noflo-gui-small.png" /></p>
<p>If you're interested, follow the progress on <a href="https://github.com/bergie/noflo">my GitHub repo</a>, or subscribe to the <a href="http://groups.google.com/group/flow-based-programming">Flow-Based Programming mailing list</a>.</p>
<p>In the spirit of Desktop Summit, it would be interesting to talk how these workflows would fit into the concept of a free software desktop.</p>]]></summary>
    </entry>
    <entry>
        <title>Testing a clients varnish vs googles page speed service</title>
        <link rel="alternate" type="text/html" href="http://www.smallone.net/blog/testing_a_clients_varnish_vs_googles_page_speed_service/"/>
        <published>2011-07-29T11:28:24+00:00</published>
        <updated>2011-07-29T11:28:24+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-2eeb0496053111e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>johan@bernhardsson.nu (Johan Bernhardsson)</name>
        </author>
        <category  term="feed:0e5d3b99667cce293d07bd863d81ca8f" />
        <content type="html"><![CDATA[
<div class="abstract">Google just launched a page speed service along with a testing tool. And i decided to test one of the larger installations I have done with varnish.</div>
<p>The test results was quite interesting. My clients Varnish+nginx+php-fpm cluster was actually faster than googles service in 3 out of four tests.</p>
<p>The grid with the results below says it all.</p>
<p> </p>
<table class="batchResults" style="width:568px;height:281px;" border="1" cellspacing="0" cellpadding="15"><tbody><tr><th class="empty"><br /></th><th>Varnish nginx+php-fpm</th><th>Googles page speed service<br /></th><th>Difference</th>
</tr><tr><td class="right"><strong>Page Load Time</strong></td>
<td>2.720s</td>
<td>3.157s</td>
<td class="bad"><strong>+0.437s (16.1%)</strong></td>
</tr><tr><td class="right"><strong>Start Render Time</strong></td>
<td>0.897s</td>
<td>0.706s</td>
<td class="good">-0.191s (21.3%)</td>
</tr><tr><td class="right"><strong>Repeat View Page Load Time</strong></td>
<td>1.381s</td>
<td>2.264s</td>
<td class="bad"><strong>+0.883s (63.9%)</strong></td>
</tr><tr><td class="right"><strong>Repeat View Start Render Time</strong></td>
<td>0.272s</td>
<td>0.392s</td>
<td class="bad"><strong>+0.120s (44.1%)</strong></td>
</tr></tbody></table><p> </p>
<p><img src="http://www.smallone.net/midcom-serveattachmentguid-1e0b9d90314602cb9d911e0876cd536e90aa379a379/pagespeed.jpg" border="0" alt="pagespeed.jpg" title="pagespeed.jpg" /></p>
<p>This is just one of the installations I have done. Results vary depending on what type of content you store. My clients content is a mix of static and frequently updated content.</p>
<p>A perfect example on a properly optimized website.</p>]]></content>
        <summary type="html"><![CDATA[
<div class="abstract">Google just launched a page speed service along with a testing tool. And i decided to test one of the larger installations I have done with varnish.</div>
<p>The test results was quite interesting. My clients Varnish+nginx+php-fpm cluster was actually faster than googles service in 3 out of four tests.</p>
<p>The grid with the results below says it all.</p>
<p> </p>
<table class="batchResults" style="width:568px;height:281px;" border="1" cellspacing="0" cellpadding="15"><tbody><tr><th class="empty"><br /></th><th>Varnish nginx+php-fpm</th><th>Googles page speed service<br /></th><th>Difference</th>
</tr><tr><td class="right"><strong>Page Load Time</strong></td>
<td>2.720s</td>
<td>3.157s</td>
<td class="bad"><strong>+0.437s (16.1%)</strong></td>
</tr><tr><td class="right"><strong>Start Render Time</strong></td>
<td>0.897s</td>
<td>0.706s</td>
<td class="good">-0.191s (21.3%)</td>
</tr><tr><td class="right"><strong>Repeat View Page Load Time</strong></td>
<td>1.381s</td>
<td>2.264s</td>
<td class="bad"><strong>+0.883s (63.9%)</strong></td>
</tr><tr><td class="right"><strong>Repeat View Start Render Time</strong></td>
<td>0.272s</td>
<td>0.392s</td>
<td class="bad"><strong>+0.120s (44.1%)</strong></td>
</tr></tbody></table><p> </p>
<p><img src="http://www.smallone.net/midcom-serveattachmentguid-1e0b9d90314602cb9d911e0876cd536e90aa379a379/pagespeed.jpg" border="0" alt="pagespeed.jpg" title="pagespeed.jpg" /></p>
<p>This is just one of the installations I have done. Results vary depending on what type of content you store. My clients content is a mix of static and frequently updated content.</p>
<p>A perfect example on a properly optimized website.</p>]]></summary>
    </entry>
    <entry>
        <title>Midgard in the Symfony2 world</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/midgard_in_the_symfony2_world/"/>
        <published>2011-07-28T19:04:08+00:00</published>
        <updated>2011-07-28T19:04:08+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-e14a8f90053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>So, <a href="http://symfony.com/blog/symfony-2-0">Symfony2 was released</a> today. Now, you may remember me complaining about the <a href="http://bergie.iki.fi/blog/php-finally_getting_an_ecosystem/">fragmentation in the PHP community</a>, as well as <a href="http://bergie.iki.fi/blog/my_secret_agenda_for_php_content_management_systems/">suggesting various technologies</a> that have the power to bring the community together. But what I haven't talked about is convergence in the area of PHP frameworks.</p>

<p>Frameworks are generally problematic concerning <a href="http://bergie.iki.fi/blog/on_cross-project_collaboration/">cross-project collaboration</a>, as most of the code written against a particular framework tends to run only on that framework. If things are <a href="http://bergie.iki.fi/blog/decoupling_content_management/">properly decoupled</a>, and most of the logic is in generic libraries, this doesn't matter so much. But still, having a common framework most of the code is written for helps, as can be seen <a href="http://rubyonrails.org/">in the Ruby community</a>.</p>

<p>So, to advance this goal, we in the <a href="http://www.midgard-project.org/">Midgard Community</a> have <a href="http://lists.midgard-project.org/pipermail/dev/2011-July/003022.html">made a decision</a> to start aligning our PHP code <a href="http://lists.midgard-project.org/pipermail/dev/2011-July/003016.html">to Symfony2</a>. The <a href="http://symfony.com/blog/symfony-2-0">ideas behind SF2</a> are quite compatible with our views:</p>

<blockquote>
  <p><em>Symfony2 embraces standards</em>: First, Symfony2 is willingly centered around the HTTP specification (just have a look at the built-in HTTP reverse proxy). Then, we are embracing the PHP standards: PHPUnit, namespaces, PSR-0 autoloader, ... That makes Symfony2 easily interoperable with many other great PHP libraries.</p>
  
  <p><em>Symfony2 is decoupled</em>: Beside being a full-stack framework, Symfony2 is also a set of decoupled and cohesive components; Symfony2 is made of 21 components that can be used as standalone libraries: they have their own Git repositories, and they are all available as PEAR packages.</p>
</blockquote>

<p>For us this alignment means making sure code written for MidCOM and Midgard MVC, our two PHP frameworks runs properly under Symfony2, and filling various functionality gaps that exist between our frameworks and SF2.</p>

<p>I believe this to be a great opportunity for both communities. Especially for Midgard users this brings a great promise of future functionality coupled with full backwards compatibility.</p>

<p>Here are some very early results of this collaboration:</p>

<ul><li>Symfony2 can now be <em>run on AppServer-in-PHP</em> with our <a href="https://github.com/bergie/MidgardAppServerBundle">AppServerBundle</a>. Great performance and deployment benefits can be had by adopting AiP, so having a simple way to run SF2 with it is useful</li>
<li>There is a <a href="https://github.com/bergie/MidgardConnectionBundle">ConnectionBundle</a> which is responsible for initializing and <em>connecting to a <a href="http://www.midgard-project.org/midgard2/">Midgard2 content repository</a></em></li>
<li><em>Midgard MVC components can now be run as part of a Symfony2</em> application with the <a href="https://github.com/bergie/MidgardMvcCompatBundle">MvcCompatBundle</a>. Lots of work there still remains, but it is a good start</li>
</ul><p>Here you can see a screen from a simple AiP-powered SF2 application, running the <a href="https://github.com/bergie/org_midgardproject_news">org_midgardproject_news</a> component displaying content from the Midgard2 repository rendered via <a href="http://phptal.org/">TAL</a>:</p>

<p><img src="http://static.qaiku.com/e2b/919/62b/e2b91962b92e11e0a362916cb7aa58f358f3.jpg" alt="Midgard says Hello World" title="" /></p>

<p>After the Midgard MVC compatibility work is done we will also focus on ensuring full MidCOM applications run on Symfony2. There is already some precedent for this sort of compatibility work, as you can also run <a href="https://github.com/beberlei/WhitewashingZFMvcCompatBundle">Zend Framework applications under Symfony2</a>.</p>

<p>Congratulations to the Symfony2 community for a great release! I look forward to a lot more collaboration in the future.</p>
]]></content>
        <summary type="html"><![CDATA[

<p>So, <a href="http://symfony.com/blog/symfony-2-0">Symfony2 was released</a> today. Now, you may remember me complaining about the <a href="http://bergie.iki.fi/blog/php-finally_getting_an_ecosystem/">fragmentation in the PHP community</a>, as well as <a href="http://bergie.iki.fi/blog/my_secret_agenda_for_php_content_management_systems/">suggesting various technologies</a> that have the power to bring the community together. But what I haven't talked about is convergence in the area of PHP frameworks.</p>

<p>Frameworks are generally problematic concerning <a href="http://bergie.iki.fi/blog/on_cross-project_collaboration/">cross-project collaboration</a>, as most of the code written against a particular framework tends to run only on that framework. If things are <a href="http://bergie.iki.fi/blog/decoupling_content_management/">properly decoupled</a>, and most of the logic is in generic libraries, this doesn't matter so much. But still, having a common framework most of the code is written for helps, as can be seen <a href="http://rubyonrails.org/">in the Ruby community</a>.</p>

<p>So, to advance this goal, we in the <a href="http://www.midgard-project.org/">Midgard Community</a> have <a href="http://lists.midgard-project.org/pipermail/dev/2011-July/003022.html">made a decision</a> to start aligning our PHP code <a href="http://lists.midgard-project.org/pipermail/dev/2011-July/003016.html">to Symfony2</a>. The <a href="http://symfony.com/blog/symfony-2-0">ideas behind SF2</a> are quite compatible with our views:</p>

<blockquote>
  <p><em>Symfony2 embraces standards</em>: First, Symfony2 is willingly centered around the HTTP specification (just have a look at the built-in HTTP reverse proxy). Then, we are embracing the PHP standards: PHPUnit, namespaces, PSR-0 autoloader, ... That makes Symfony2 easily interoperable with many other great PHP libraries.</p>
  
  <p><em>Symfony2 is decoupled</em>: Beside being a full-stack framework, Symfony2 is also a set of decoupled and cohesive components; Symfony2 is made of 21 components that can be used as standalone libraries: they have their own Git repositories, and they are all available as PEAR packages.</p>
</blockquote>

<p>For us this alignment means making sure code written for MidCOM and Midgard MVC, our two PHP frameworks runs properly under Symfony2, and filling various functionality gaps that exist between our frameworks and SF2.</p>

<p>I believe this to be a great opportunity for both communities. Especially for Midgard users this brings a great promise of future functionality coupled with full backwards compatibility.</p>

<p>Here are some very early results of this collaboration:</p>

<ul><li>Symfony2 can now be <em>run on AppServer-in-PHP</em> with our <a href="https://github.com/bergie/MidgardAppServerBundle">AppServerBundle</a>. Great performance and deployment benefits can be had by adopting AiP, so having a simple way to run SF2 with it is useful</li>
<li>There is a <a href="https://github.com/bergie/MidgardConnectionBundle">ConnectionBundle</a> which is responsible for initializing and <em>connecting to a <a href="http://www.midgard-project.org/midgard2/">Midgard2 content repository</a></em></li>
<li><em>Midgard MVC components can now be run as part of a Symfony2</em> application with the <a href="https://github.com/bergie/MidgardMvcCompatBundle">MvcCompatBundle</a>. Lots of work there still remains, but it is a good start</li>
</ul><p>Here you can see a screen from a simple AiP-powered SF2 application, running the <a href="https://github.com/bergie/org_midgardproject_news">org_midgardproject_news</a> component displaying content from the Midgard2 repository rendered via <a href="http://phptal.org/">TAL</a>:</p>

<p><img src="http://static.qaiku.com/e2b/919/62b/e2b91962b92e11e0a362916cb7aa58f358f3.jpg" alt="Midgard says Hello World" title="" /></p>

<p>After the Midgard MVC compatibility work is done we will also focus on ensuring full MidCOM applications run on Symfony2. There is already some precedent for this sort of compatibility work, as you can also run <a href="https://github.com/beberlei/WhitewashingZFMvcCompatBundle">Zend Framework applications under Symfony2</a>.</p>

<p>Congratulations to the Symfony2 community for a great release! I look forward to a lot more collaboration in the future.</p>
]]></summary>
    </entry>
    <entry>
        <title>PHP and GObject Introspection</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/php_and_gobject_introspection/"/>
        <published>2011-07-26T12:15:01+00:00</published>
        <updated>2011-07-26T12:15:01+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-df393bd4053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p><a href="https://live.gnome.org/GObjectIntrospection">GObject Introspection</a> is one of the hidden jewels of the <a href="http://developer.gnome.org/platform-overview/stable/">GNOME stack</a>: you write a library in C or <a href="http://en.wikipedia.org/wiki/Vala_%28programming_language%29">Vala</a>, and it becomes automatically available to <a href="https://live.gnome.org/GObjectIntrospection/Users">a wide variety</a> of languages and runtimes, including <a href="https://live.gnome.org/PyGObject">Python</a>, <a href="https://live.gnome.org/Gjs">JavaScript</a>, <a href="https://live.gnome.org/JGIR">Java</a> and <a href="http://blogs.kde.org/node/4444">Qt</a>.</p>

<p>Now I would like to bring GObject Introspection to PHP. Why?</p>

<p>For many years we in the <a href="http://www.midgard-project.org/">Midgard</a> community have been using GNOME infrastructure on the web server side, by building our persistence layer on top of GObjects, and providing <a href="http://teroheikkinen.iki.fi/blog/midgard_workshop_at_fscons/">D-Bus notifications</a> when content changes. So far this has been done with our own <a href="https://github.com/midgardproject/midgard-php5">custom PHP extension</a>.</p>

<p>I believe a common PHP extension providing GObject Introspection support would make more sense, as it wouldn't just benefit our own community, but also support efforts like <a href="http://gtk.php.net/">php-gtk</a>.</p>

<p><a href="http://github.com/indeyets">Alexey Zakhlestin</a> already <a href="https://github.com/indeyets/gobject-for-php">started a project</a> for this a while back, but unfortunately has been unable to finish it. Because of this, <a href="http://nemein.com/en/">we</a> would be willing to sponsor anybody interested in making the <a href="https://github.com/indeyets/gobject-for-php">gobject-for-php</a> extension work.</p>

<p>Benefits for the GNOME community:</p>

<ul><li>New supported development language and a large community of potential contributors</li>
<li>The possibility of making the GNOME stack relevant in web space. Just think of Telepathy or GStreamer in a web app</li>
</ul><p>Benefits for the PHP community:</p>

<ul><li>Access to the rich collection of GNOME libraries, many which may be useful when building web applications</li>
<li>Being able to use your PHP skills to build GNOME applications and bring them to interesting environments like <a href="http://www.ubuntu.com/ubuntu">Ubuntu</a> and <a href="http://cordiahd.org/">Cordia</a></li>
</ul><p>Benefits for the Midgard community:</p>

<ul><li>No need to maintain our own custom PHP extension</li>
<li>A more generic GObject Introspection extension has better chances of being included into Linux distributions and being available on hosting providers</li>
</ul><p>Let <a href="http://nemein.com/en/people/bergie/">me</a> know if you are interested. We're coming to the <a href="https://desktopsummit.org/">Desktop Summit</a> with <a href="http://blogs.nemein.com/people/piotras/">Piotras</a>, so for example that is a great opportunity to talk more about this.</p>
]]></content>
        <summary type="html"><![CDATA[

<p><a href="https://live.gnome.org/GObjectIntrospection">GObject Introspection</a> is one of the hidden jewels of the <a href="http://developer.gnome.org/platform-overview/stable/">GNOME stack</a>: you write a library in C or <a href="http://en.wikipedia.org/wiki/Vala_%28programming_language%29">Vala</a>, and it becomes automatically available to <a href="https://live.gnome.org/GObjectIntrospection/Users">a wide variety</a> of languages and runtimes, including <a href="https://live.gnome.org/PyGObject">Python</a>, <a href="https://live.gnome.org/Gjs">JavaScript</a>, <a href="https://live.gnome.org/JGIR">Java</a> and <a href="http://blogs.kde.org/node/4444">Qt</a>.</p>

<p>Now I would like to bring GObject Introspection to PHP. Why?</p>

<p>For many years we in the <a href="http://www.midgard-project.org/">Midgard</a> community have been using GNOME infrastructure on the web server side, by building our persistence layer on top of GObjects, and providing <a href="http://teroheikkinen.iki.fi/blog/midgard_workshop_at_fscons/">D-Bus notifications</a> when content changes. So far this has been done with our own <a href="https://github.com/midgardproject/midgard-php5">custom PHP extension</a>.</p>

<p>I believe a common PHP extension providing GObject Introspection support would make more sense, as it wouldn't just benefit our own community, but also support efforts like <a href="http://gtk.php.net/">php-gtk</a>.</p>

<p><a href="http://github.com/indeyets">Alexey Zakhlestin</a> already <a href="https://github.com/indeyets/gobject-for-php">started a project</a> for this a while back, but unfortunately has been unable to finish it. Because of this, <a href="http://nemein.com/en/">we</a> would be willing to sponsor anybody interested in making the <a href="https://github.com/indeyets/gobject-for-php">gobject-for-php</a> extension work.</p>

<p>Benefits for the GNOME community:</p>

<ul><li>New supported development language and a large community of potential contributors</li>
<li>The possibility of making the GNOME stack relevant in web space. Just think of Telepathy or GStreamer in a web app</li>
</ul><p>Benefits for the PHP community:</p>

<ul><li>Access to the rich collection of GNOME libraries, many which may be useful when building web applications</li>
<li>Being able to use your PHP skills to build GNOME applications and bring them to interesting environments like <a href="http://www.ubuntu.com/ubuntu">Ubuntu</a> and <a href="http://cordiahd.org/">Cordia</a></li>
</ul><p>Benefits for the Midgard community:</p>

<ul><li>No need to maintain our own custom PHP extension</li>
<li>A more generic GObject Introspection extension has better chances of being included into Linux distributions and being available on hosting providers</li>
</ul><p>Let <a href="http://nemein.com/en/people/bergie/">me</a> know if you are interested. We're coming to the <a href="https://desktopsummit.org/">Desktop Summit</a> with <a href="http://blogs.nemein.com/people/piotras/">Piotras</a>, so for example that is a great opportunity to talk more about this.</p>
]]></summary>
    </entry>
    <entry>
        <title>My secret agenda for PHP Content Management Systems</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/my_secret_agenda_for_php_content_management_systems/"/>
        <published>2011-07-08T16:25:27+00:00</published>
        <updated>2011-07-08T16:25:27+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-dd164c0c053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>As I've written before, I'm concerned about the state of the PHP ecosystem. There are lots of good applications written in the language, but there is very little code sharing between different projects, mainly because of framework incompatibilities, but also because of quite a strong <a href="http://en.wikipedia.org/wiki/Not_Invented_Here">NIH</a> culture.</p>

<p>But there are also bright points. I've recently seen lots of exchange of ideas, and even potential code sharing between some communities including Symfony2, Midgard, TYPO3 and eZ Publish. Much of the vision in these systems is similar, as are many of the engineering principles. When everybody uses reasonable object-oriented design, namespaces, and test-driven development, it is much easier to share.</p>

<p>If I had to list three areas where there is most potential for collaboration, these would be:</p>

<h2>Content model on the browser: VIE and RDFa</h2>

<p>The age of communicating with your web audience via <em>forms</em> is almost over, and it is time to evolve. HTML5 includes support for the <a href="http://blog.whatwg.org/the-road-to-html-5-contenteditable">contentEditable</a> attribute which allows rich editing interaction straight on the pages, and there are cool editors supporting that, including <a href="http://aloha-editor.org/">Aloha Editor</a> and <a href="https://github.com/jejacks0n/mercury#readme">Mercury</a>.</p>

<p>To do proper front-end editing, your CMS and the JavaScript environment have to agree on the content model. Fortunately there is a great solution for this: just annotate your content with some RDFa.</p>

<p>Having RDFa on a page allows the browser to understand the content. What is a collection of blog posts for instance, and what is the title of a blog post. With this, my VIE library will provide you with a nice in-browser content management API based on <a href="http://documentcloud.github.com/backbone/">Backbone.js</a>. Getting there is easy:</p>

<ol><li>Annotate your pages with RDFa</li>
<li>Include <a href="https://github.com/bergie/VIE">vie.js</a> to the pages</li>
<li>Implement <a href="http://documentcloud.github.com/backbone/#Sync">Backbone.sync</a></li>
</ol><p>This allows a great deal of <a href="http://bergie.iki.fi/blog/decoupling_content_management/">decoupling in the CMS stack</a>. Suddenly the server side just has to worry about content management and page generation, and newer in-browser technologies can be used for actual content authoring.</p>

<p>Using RDFa annotations in your content comes also with another benefit: suddenly your pages themselves are an API into your content model. And search engines can understand and present your content better.</p>

<p>If you want to learn more about this, <a href="http://bergie.iki.fi/blog/midgard_create_and_vie_in_the_aloha_editor_conference/">watch my talk</a> from the Aloha Editor Dev Con.</p>

<h2>Content persistence and retrieval: PHPCR</h2>

<p>Historically, all CMSs have implemented persistence in their own way. There have been systems using relational databases like MySQL, systems providing their own content repository APIs like Midgard, and also some systems just using XML and the file system. This has reduced integration and code re-use possibilities between systems. In the Java world, a solution exists for this: the <a href="http://en.wikipedia.org/wiki/Content_repository_API_for_Java">Java Content Repository</a> standard (JCR).</p>

<p>Now JCR has been ported to PHP. <a href="http://phpcr.github.com/">PHPCR</a> provides a standard interface for all content management needs, and has multiple back-ends available. Depending on your deployment needs, you could store your content into a relational database, into Apache Jackrabbit, or into for example MongoDB.</p>

<p>PHPCR is great in that you can start small: just model your content with a simple, filesystem-like tree of nodes and properties. Then when you need it, a wealth of functionality is available. Versioning? Query builders? Access control? It is all there for you to use. And, depending on the PHPCR back-end, you'll have the ability to scale up to insane amounts of content.</p>

<p>While I've advocated <a href="http://bergie.iki.fi/blog/why_you_should_use_a_content_repository_for_your_application/">using content repositories</a> for years now, this is the first time PHP has a true standardized, vendor-neutral API for it. And PHPCR is even being integrated <a href="http://java.net/jira/browse/JSR_333-28">into the JCR specification</a>, eventually making it an official standard.</p>

<p><img src="http://farm7.static.flickr.com/6053/5915517564_ba20056559.jpg" alt="PHPCR discussion in Sursee, Switzerland" title="" /></p>

<p>Adoption is also picking up. Yesterday I was in a meeting where we had developers from TYPO3, Symfony2, Doctrine and Midgard discussing issues and solutions in the content repository space. I just hope the other projects also pick this specification up.</p>

<h2>Improving performance: AppServer-in-PHP</h2>

<p>Of the three, this is probably the most controversial idea. Traditionally PHP is run as a scripting environment on a regular web server, like Apache or Nginx. In such setup, when the server receives a request, it passes it on to the PHP environment. The PHP environment loads all the code needed to fulfill the request, runs it, sends the response back, and unloads everything loaded.</p>

<p>This is fine when PHP is being used in the way Rasmus originally intended, as a simple display layer. But nowadays most of <a href="http://www.sitepoint.com/rasmus-lerdorf-php-frameworks-think-again/">PHP runs on a big framework</a>, whether it is MVC or something custom like Drupal. And loading and then discarding a whole framework for each request is simply insane.</p>

<p>With <a href="http://github.com/indeyets/appserver-in-php">AppServer-in-PHP</a> (AiP), you have an environment where even a big framework can perform. AiP provides you with a full server environment for PHP, <em>written in PHP</em>. In this setup, your framework is loaded when the server boots up, and then each request just runs the request processing part of it.</p>

<p>During the <a href="http://www.aloha-editor.org/wiki/Aloha_Editor_Dev_Con_SanFrancisco_11">San Francisco Aloha Dev Con</a> we ported TYPO3 to run on AiP, and the performance results where staggering. A simpler request with not much I/O would run 3-4 times faster than the same code on regular PHP setup, and an I/O -intensive request would still be <em>twice as fast</em>. AiP can't do much about I/O performance, but at least the cost of having a framework is greatly reduced.</p>

<p>In short, AppServer-in-PHP is something any developer running web services with a PHP framework should consider. It is also a great way for framework developers to see if they have request isolation problems in their design.</p>

<p><em>This post has been written in the <a href="http://t3dd11.typo3.org/">TYPO3 Developer Days 2011</a> event where I was invited to discuss these ideas, and also help run the RDFa part of the <a href="http://www.slideshare.net/jocrau/semantic-typo3">TYPO3 Goes Semantic</a> workshop.</em></p>
]]></content>
        <summary type="html"><![CDATA[

<p>As I've written before, I'm concerned about the state of the PHP ecosystem. There are lots of good applications written in the language, but there is very little code sharing between different projects, mainly because of framework incompatibilities, but also because of quite a strong <a href="http://en.wikipedia.org/wiki/Not_Invented_Here">NIH</a> culture.</p>

<p>But there are also bright points. I've recently seen lots of exchange of ideas, and even potential code sharing between some communities including Symfony2, Midgard, TYPO3 and eZ Publish. Much of the vision in these systems is similar, as are many of the engineering principles. When everybody uses reasonable object-oriented design, namespaces, and test-driven development, it is much easier to share.</p>

<p>If I had to list three areas where there is most potential for collaboration, these would be:</p>

<h2>Content model on the browser: VIE and RDFa</h2>

<p>The age of communicating with your web audience via <em>forms</em> is almost over, and it is time to evolve. HTML5 includes support for the <a href="http://blog.whatwg.org/the-road-to-html-5-contenteditable">contentEditable</a> attribute which allows rich editing interaction straight on the pages, and there are cool editors supporting that, including <a href="http://aloha-editor.org/">Aloha Editor</a> and <a href="https://github.com/jejacks0n/mercury#readme">Mercury</a>.</p>

<p>To do proper front-end editing, your CMS and the JavaScript environment have to agree on the content model. Fortunately there is a great solution for this: just annotate your content with some RDFa.</p>

<p>Having RDFa on a page allows the browser to understand the content. What is a collection of blog posts for instance, and what is the title of a blog post. With this, my VIE library will provide you with a nice in-browser content management API based on <a href="http://documentcloud.github.com/backbone/">Backbone.js</a>. Getting there is easy:</p>

<ol><li>Annotate your pages with RDFa</li>
<li>Include <a href="https://github.com/bergie/VIE">vie.js</a> to the pages</li>
<li>Implement <a href="http://documentcloud.github.com/backbone/#Sync">Backbone.sync</a></li>
</ol><p>This allows a great deal of <a href="http://bergie.iki.fi/blog/decoupling_content_management/">decoupling in the CMS stack</a>. Suddenly the server side just has to worry about content management and page generation, and newer in-browser technologies can be used for actual content authoring.</p>

<p>Using RDFa annotations in your content comes also with another benefit: suddenly your pages themselves are an API into your content model. And search engines can understand and present your content better.</p>

<p>If you want to learn more about this, <a href="http://bergie.iki.fi/blog/midgard_create_and_vie_in_the_aloha_editor_conference/">watch my talk</a> from the Aloha Editor Dev Con.</p>

<h2>Content persistence and retrieval: PHPCR</h2>

<p>Historically, all CMSs have implemented persistence in their own way. There have been systems using relational databases like MySQL, systems providing their own content repository APIs like Midgard, and also some systems just using XML and the file system. This has reduced integration and code re-use possibilities between systems. In the Java world, a solution exists for this: the <a href="http://en.wikipedia.org/wiki/Content_repository_API_for_Java">Java Content Repository</a> standard (JCR).</p>

<p>Now JCR has been ported to PHP. <a href="http://phpcr.github.com/">PHPCR</a> provides a standard interface for all content management needs, and has multiple back-ends available. Depending on your deployment needs, you could store your content into a relational database, into Apache Jackrabbit, or into for example MongoDB.</p>

<p>PHPCR is great in that you can start small: just model your content with a simple, filesystem-like tree of nodes and properties. Then when you need it, a wealth of functionality is available. Versioning? Query builders? Access control? It is all there for you to use. And, depending on the PHPCR back-end, you'll have the ability to scale up to insane amounts of content.</p>

<p>While I've advocated <a href="http://bergie.iki.fi/blog/why_you_should_use_a_content_repository_for_your_application/">using content repositories</a> for years now, this is the first time PHP has a true standardized, vendor-neutral API for it. And PHPCR is even being integrated <a href="http://java.net/jira/browse/JSR_333-28">into the JCR specification</a>, eventually making it an official standard.</p>

<p><img src="http://farm7.static.flickr.com/6053/5915517564_ba20056559.jpg" alt="PHPCR discussion in Sursee, Switzerland" title="" /></p>

<p>Adoption is also picking up. Yesterday I was in a meeting where we had developers from TYPO3, Symfony2, Doctrine and Midgard discussing issues and solutions in the content repository space. I just hope the other projects also pick this specification up.</p>

<h2>Improving performance: AppServer-in-PHP</h2>

<p>Of the three, this is probably the most controversial idea. Traditionally PHP is run as a scripting environment on a regular web server, like Apache or Nginx. In such setup, when the server receives a request, it passes it on to the PHP environment. The PHP environment loads all the code needed to fulfill the request, runs it, sends the response back, and unloads everything loaded.</p>

<p>This is fine when PHP is being used in the way Rasmus originally intended, as a simple display layer. But nowadays most of <a href="http://www.sitepoint.com/rasmus-lerdorf-php-frameworks-think-again/">PHP runs on a big framework</a>, whether it is MVC or something custom like Drupal. And loading and then discarding a whole framework for each request is simply insane.</p>

<p>With <a href="http://github.com/indeyets/appserver-in-php">AppServer-in-PHP</a> (AiP), you have an environment where even a big framework can perform. AiP provides you with a full server environment for PHP, <em>written in PHP</em>. In this setup, your framework is loaded when the server boots up, and then each request just runs the request processing part of it.</p>

<p>During the <a href="http://www.aloha-editor.org/wiki/Aloha_Editor_Dev_Con_SanFrancisco_11">San Francisco Aloha Dev Con</a> we ported TYPO3 to run on AiP, and the performance results where staggering. A simpler request with not much I/O would run 3-4 times faster than the same code on regular PHP setup, and an I/O -intensive request would still be <em>twice as fast</em>. AiP can't do much about I/O performance, but at least the cost of having a framework is greatly reduced.</p>

<p>In short, AppServer-in-PHP is something any developer running web services with a PHP framework should consider. It is also a great way for framework developers to see if they have request isolation problems in their design.</p>

<p><em>This post has been written in the <a href="http://t3dd11.typo3.org/">TYPO3 Developer Days 2011</a> event where I was invited to discuss these ideas, and also help run the RDFa part of the <a href="http://www.slideshare.net/jocrau/semantic-typo3">TYPO3 Goes Semantic</a> workshop.</em></p>
]]></summary>
    </entry>
    <entry>
        <title>Some good things in Google+</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/some_good_things_in_google/"/>
        <published>2011-07-01T22:38:26+00:00</published>
        <updated>2011-07-01T22:38:26+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-dabad342053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>So, <a href="http://plus.google.com">Google Plus</a> launched, the first truly viable Facebook competitor. The timing is quite interesting, given Google's recent failures with the Buzz microblogging platform, and the impending <a href="http://mashable.com/2011/06/13/facebook-ipo-100-billion/">Facebook IPO</a>. After a bit of time with Plus, here are some thoughts:</p>
<ul><li>Google already knows everything I do, so sharing stuff there feels less risky</li>
<li>The UI is pretty and a lot less bloated than Facebook's</li>
<li>Messages and comments can be edited, saving from unnecessary typos and having to post quick clarifications separately</li>
<li>Circles are a great way to organize your contacts, and I like the fact that they avoid the loaded <em>friend</em> term</li>
<li>You can export all your data, so you have a way out if you need one</li>
<li>Group videochats are also a promising concept</li>
</ul><div>But of course there are some downsides:</div>
<p>
</p><ul><li>Facebook already has a crazy critical mass. We'll see whether the non-geeks convert to Plus or not</li>
<li>There is no integration to third-party services like Flickr, and there is no API</li>
<li>Content is not language tagged and filtered, like on <a href="http://qaiku.com/">Qaiku</a>. Google could probably do even better here, doing automatic language recognition and translation</li>
</ul><div>We'll see how this plays out. In general, Google is a more friendly player than Facebook, but if they have both search and social, they'll basically own the web.</div>
<div><br /></div>
<div>Righ now Facebook is the social service with the users, alongside the more news-oriented Twitter. But Google's advantage may be how this now integrates with all their other services. If you register to Plus, the black "sandbar" that appears everywhere including search results will do its best to pull you back.</div>
<div><br /></div>
<div>And they may do something interesting with the masses of Android devices out there, most with Google accounts already enabled.</div>
]]></content>
        <summary type="html"><![CDATA[

<p>So, <a href="http://plus.google.com">Google Plus</a> launched, the first truly viable Facebook competitor. The timing is quite interesting, given Google's recent failures with the Buzz microblogging platform, and the impending <a href="http://mashable.com/2011/06/13/facebook-ipo-100-billion/">Facebook IPO</a>. After a bit of time with Plus, here are some thoughts:</p>
<ul><li>Google already knows everything I do, so sharing stuff there feels less risky</li>
<li>The UI is pretty and a lot less bloated than Facebook's</li>
<li>Messages and comments can be edited, saving from unnecessary typos and having to post quick clarifications separately</li>
<li>Circles are a great way to organize your contacts, and I like the fact that they avoid the loaded <em>friend</em> term</li>
<li>You can export all your data, so you have a way out if you need one</li>
<li>Group videochats are also a promising concept</li>
</ul><div>But of course there are some downsides:</div>
<p>
</p><ul><li>Facebook already has a crazy critical mass. We'll see whether the non-geeks convert to Plus or not</li>
<li>There is no integration to third-party services like Flickr, and there is no API</li>
<li>Content is not language tagged and filtered, like on <a href="http://qaiku.com/">Qaiku</a>. Google could probably do even better here, doing automatic language recognition and translation</li>
</ul><div>We'll see how this plays out. In general, Google is a more friendly player than Facebook, but if they have both search and social, they'll basically own the web.</div>
<div><br /></div>
<div>Righ now Facebook is the social service with the users, alongside the more news-oriented Twitter. But Google's advantage may be how this now integrates with all their other services. If you register to Plus, the black "sandbar" that appears everywhere including search results will do its best to pull you back.</div>
<div><br /></div>
<div>And they may do something interesting with the masses of Android devices out there, most with Google accounts already enabled.</div>
]]></summary>
    </entry>
    <entry>
        <title>Preliminary test results for varnish on midgard-project.org</title>
        <link rel="alternate" type="text/html" href="http://www.smallone.net/blog/preliminary_test_results_for_varnish_on_midgard-project-org/"/>
        <published>2011-06-11T17:09:02+00:00</published>
        <updated>2011-06-11T17:09:02+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-2c136cfe053111e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>johan@bernhardsson.nu (Johan Bernhardsson)</name>
        </author>
        <category  term="feed:0e5d3b99667cce293d07bd863d81ca8f" />
        <content type="html"><![CDATA[
<div class="abstract">This is the preliminary results on running varnish on a larger site than my blog ...</div>
<p>Scaling up some and running <a href="http://varnish-cache.org">Varnish</a> on the main site for the <a href="http://www.midgard-project.org/" target="_blank">midgard project</a> website show just how much better you can make a website perform.</p>
<p>The data ...</p>
<p>siege -b on <a href="http://www.midgard-project.org/documentation/">http://www.midgard-project.org/documentation/</a></p>
<p>Without <a href="http://varnish-cache.org" target="_blank">Varnish</a>:</p>
<p>Transactions:                     817 hits<br />Availability:                 100.00 %<br />Elapsed time:                   9.69 secs<br />Data transferred:               3.75 MB<br />Response time:                  0.18 secs<br />Transaction rate:              84.31 trans/sec<br />Throughput:                     0.39 MB/sec<br />Concurrency:                   14.81<br />Successful transactions:         817<br />Failed transactions:               0<br />Longest transaction:            1.36<br />Shortest transaction:           0.01</p>
<p> </p>
<p>With <a href="http://varnish-cache.org" target="_blank">Varnish</a>:</p>
<p>Transactions:                    2951 hits<br />Availability:                 100.00 %<br />Elapsed time:                  10.69 secs<br />Data transferred:              58.38 MB<br />Response time:                  0.05 secs<br />Transaction rate:             276.05 trans/sec<br />Throughput:                     5.46 MB/sec<br />Concurrency:                   13.50<br />Successful transactions:        2951<br />Failed transactions:               0<br />Longest transaction:            0.43<br />Shortest transaction:           0.00</p>
<p> </p>
<p>I guess that says it all. I will try to add some more logic to <a href="http://varnish-cache.org" target="_blank">Varnish</a> so that it doesnt cache logged in users.  After that we can launch it  :)</p>
<p> </p>]]></content>
        <summary type="html"><![CDATA[
<div class="abstract">This is the preliminary results on running varnish on a larger site than my blog ...</div>
<p>Scaling up some and running <a href="http://varnish-cache.org">Varnish</a> on the main site for the <a href="http://www.midgard-project.org/" target="_blank">midgard project</a> website show just how much better you can make a website perform.</p>
<p>The data ...</p>
<p>siege -b on <a href="http://www.midgard-project.org/documentation/">http://www.midgard-project.org/documentation/</a></p>
<p>Without <a href="http://varnish-cache.org" target="_blank">Varnish</a>:</p>
<p>Transactions:                     817 hits<br />Availability:                 100.00 %<br />Elapsed time:                   9.69 secs<br />Data transferred:               3.75 MB<br />Response time:                  0.18 secs<br />Transaction rate:              84.31 trans/sec<br />Throughput:                     0.39 MB/sec<br />Concurrency:                   14.81<br />Successful transactions:         817<br />Failed transactions:               0<br />Longest transaction:            1.36<br />Shortest transaction:           0.01</p>
<p> </p>
<p>With <a href="http://varnish-cache.org" target="_blank">Varnish</a>:</p>
<p>Transactions:                    2951 hits<br />Availability:                 100.00 %<br />Elapsed time:                  10.69 secs<br />Data transferred:              58.38 MB<br />Response time:                  0.05 secs<br />Transaction rate:             276.05 trans/sec<br />Throughput:                     5.46 MB/sec<br />Concurrency:                   13.50<br />Successful transactions:        2951<br />Failed transactions:               0<br />Longest transaction:            0.43<br />Shortest transaction:           0.00</p>
<p> </p>
<p>I guess that says it all. I will try to add some more logic to <a href="http://varnish-cache.org" target="_blank">Varnish</a> so that it doesnt cache logged in users.  After that we can launch it  :)</p>
<p> </p>]]></summary>
    </entry>
    <entry>
        <title>Midgard Create and VIE in the Aloha Editor conference</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/midgard_create_and_vie_in_the_aloha_editor_conference/"/>
        <published>2011-06-07T00:53:46+00:00</published>
        <updated>2011-06-07T00:53:46+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-d8187e78053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>The <a href="http://www.aloha-editor.org/wiki/index.php/Aloha_Editor_Dev_Con_SanFrancisco_11">Aloha Editor Developer Conference</a> is happening this week in <a href="http://wiki.hackerdojo.com/w/page/25437/FrontPage">Hacker Dojo</a>, Mountain View. While some <a href="http://arstechnica.com/apple/news/2011/06/liveblog-wwdc-2011-keynote-on-june-6.ars">other events</a> may steal a bit of focus from this one, there seems to be a good amount of energy here. The event opened with <a href="https://twitter.com/draftkraft">Haymo Meran's</a> keynote on the state and roadmap of <a href="http://aloha-editor.org/">Aloha Editor</a>. As part of this there was an interesting observation:</p>
<blockquote>Aloha Editor has an impressive rate of adoption: Drupal, TYPO3, WordPress, Midgard and others are now in the process of integrating the editor. If all of these work out, Aloha Editor can reach an approximately <em>66% of the CMS market</em>.</blockquote>
<p>And since most of them will do this with my <a href="https://github.com/bergie/VIE">VIE library</a>, this is also great news for <a href="http://bergie.iki.fi/blog/decoupling_content_management/">Decoupled Content Management</a>, <a href="http://en.wikipedia.org/wiki/RDFa">RDFa</a> and the goals of the <a href="http://www.iks-project.eu/">IKS project</a>.</p>
<p><img src="http://bergie.iki.fi/static/1/1e090a166ba8dce90a111e0aec3d9657ffc1c7b1c7b_bergie-alohadevcon.jpg" border="0" alt="bergie-alohadevcon.jpg" title="bergie-alohadevcon.jpg" /></p>
<p>I also gave a talk on how we <a href="http://bergie.iki.fi/blog/introducing_the_midgard_create_user_interface/">use Aloha Editor and VIE in Midgard Create</a>. Both <a href="http://www.slideshare.net/bergie/midgard-create-and-vie">slides</a> and <a href="http://bambuser.com/channel/alohaeditor/broadcast/1719639">video</a> are available.</p>
<p>
<object id="bplayer" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="480" height="411"><embed name="bplayer" src="http://static.bambuser.com/r/player.swf?vid=1719639" type="application/x-shockwave-flash" width="480" height="411" allowfullscreen="true" allowscriptaccess="always" wmode="opaque"></embed><param name="movie" value="http://static.bambuser.com/r/player.swf?vid=1719639"></param><param name="allowfullscreen" value="true"></param><param name="allowscriptaccess" value="always"></param><param name="wmode" value="opaque"></param></object>
</p>
<p>Later this week there will be also an interesting BoF in SemTech about <a href="http://www.w3.org/2001/sw/wiki/SemTech2011BOF">Structured Data in HTML</a> that I will try to attend. After that it is time to fly home...</p>
<p><em>Photo by <a href="http://www.flickr.com/photos/nils-dehl/sets/72157626900822236/">Nils Dehl</a>.</em></p>]]></content>
        <summary type="html"><![CDATA[

<p>The <a href="http://www.aloha-editor.org/wiki/index.php/Aloha_Editor_Dev_Con_SanFrancisco_11">Aloha Editor Developer Conference</a> is happening this week in <a href="http://wiki.hackerdojo.com/w/page/25437/FrontPage">Hacker Dojo</a>, Mountain View. While some <a href="http://arstechnica.com/apple/news/2011/06/liveblog-wwdc-2011-keynote-on-june-6.ars">other events</a> may steal a bit of focus from this one, there seems to be a good amount of energy here. The event opened with <a href="https://twitter.com/draftkraft">Haymo Meran's</a> keynote on the state and roadmap of <a href="http://aloha-editor.org/">Aloha Editor</a>. As part of this there was an interesting observation:</p>
<blockquote>Aloha Editor has an impressive rate of adoption: Drupal, TYPO3, WordPress, Midgard and others are now in the process of integrating the editor. If all of these work out, Aloha Editor can reach an approximately <em>66% of the CMS market</em>.</blockquote>
<p>And since most of them will do this with my <a href="https://github.com/bergie/VIE">VIE library</a>, this is also great news for <a href="http://bergie.iki.fi/blog/decoupling_content_management/">Decoupled Content Management</a>, <a href="http://en.wikipedia.org/wiki/RDFa">RDFa</a> and the goals of the <a href="http://www.iks-project.eu/">IKS project</a>.</p>
<p><img src="http://bergie.iki.fi/static/1/1e090a166ba8dce90a111e0aec3d9657ffc1c7b1c7b_bergie-alohadevcon.jpg" border="0" alt="bergie-alohadevcon.jpg" title="bergie-alohadevcon.jpg" /></p>
<p>I also gave a talk on how we <a href="http://bergie.iki.fi/blog/introducing_the_midgard_create_user_interface/">use Aloha Editor and VIE in Midgard Create</a>. Both <a href="http://www.slideshare.net/bergie/midgard-create-and-vie">slides</a> and <a href="http://bambuser.com/channel/alohaeditor/broadcast/1719639">video</a> are available.</p>
<p>
<object id="bplayer" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="480" height="411"><embed name="bplayer" src="http://static.bambuser.com/r/player.swf?vid=1719639" type="application/x-shockwave-flash" width="480" height="411" allowfullscreen="true" allowscriptaccess="always" wmode="opaque"></embed><param name="movie" value="http://static.bambuser.com/r/player.swf?vid=1719639"></param><param name="allowfullscreen" value="true"></param><param name="allowscriptaccess" value="always"></param><param name="wmode" value="opaque"></param></object>
</p>
<p>Later this week there will be also an interesting BoF in SemTech about <a href="http://www.w3.org/2001/sw/wiki/SemTech2011BOF">Structured Data in HTML</a> that I will try to attend. After that it is time to fly home...</p>
<p><em>Photo by <a href="http://www.flickr.com/photos/nils-dehl/sets/72157626900822236/">Nils Dehl</a>.</em></p>]]></summary>
    </entry>
    <entry>
        <title>Understanding MeeGo</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/understanding_meego/"/>
        <published>2011-06-05T03:58:17+00:00</published>
        <updated>2011-06-05T03:58:17+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-d5f2e64c053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p><em>Disclaimer: I'm a software developer with a background in Nokia's Maemo mobile Linux ecosystem. I've built both software and community services for it. As a Maemo enthusiast, I've also been following MeeGo with interest, and am helping to build some of the project infrastructure there as well. But I do not speak with the authority of the MeeGo project, and what is written below is my personal view into what MeeGo is.</em></p>

<p>After the recent <a href="http://sf2011.meego.com/">San Francisco MeeGo Conference</a> there has been surprisingly much negative reporting about MeeGo, mostly centered at <a href="http://www.latestnewsin.com/meegos-state-of-development-was-an-oh-shit-moment-for-nokia/">Nokia's MeeGo story</a>. While Nokia's strategy changes are unfortunate, much of the reporting around it appears to come from misunderstanding what MeeGo is about.</p>

<p>Many see MeeGo just as <em>Android without Java</em>, but it is much more, as I'll explain here.</p>

<h2>Industrial Linux</h2>

<p>MeeGo is much more than just handsets or tablets. It is an attempt at creating a standardized industrial Linux distribution that can be used anywhere from in-vehicle infotainment devices to TVs to, indeed, handsets.</p>

<p>It is a true open and collaborative environment, managed by <a href="http://www.linuxfoundation.org/">Linux Foundation</a>. The <a href="https://meego.com/about/governance">governance model</a> is there to ensure that MeeGo stays a vendor-neutral platform that anybody can build their products on top.</p>

<p>Many device segments have very long development, and especially usage times. For this MeeGo has a predictable release schedule of a major release every six months, and <a href="https://meego.com/about/roadmaps">a roadmap</a> kept by the Technical Steering Group.</p>

<p>If MeeGo succeeds in this, you will be using it in your TV, in your car stereo, and at the back of an airline seat. But in most of these situations you won't be able to know that it is MeeGo. It is simply there to make building products faster and cheaper for the manufacturer.</p>

<h2>Openness</h2>

<p>As I argued in my earlier piece <a href="http://bergie.iki.fi/blog/open_source-free_software-what_we_need_is_open_projects/">Open Source? Free Software? What we need is Open Projects</a>, being an open platform is much more than just the licensing terms of the code. There needs to be transparency into the development process, a clear procedure on how to participate and much more. And of course licensing has to be such that the participants can actually use the results in whatever they're doing.</p>

<p>For this, most of <a href="https://meego.com/about/licensing-policy">MeeGo is licensed</a> under permissive terms, like the GNU LGPL and BSD-style licenses.</p>

<p>But indeed, the other aspects of openness are more important. With MeeGo you can see every commit happening on Gitorious, and you can see the bugs and features being worked out in a public Bugzilla.</p>

<p>MeeGo as a project is still quite young, and many participants are still learning how to work in the open. This has lead to <a href="http://lwn.net/Articles/444567/">some issues in project transparency</a>. But hopefully those are now getting resolved.</p>

<h2>User Experience</h2>

<p>MeeGo allows anyone to build their own user experience on top of the platform. Actually, this is expected of any serious manufacturer. Sure, there are some reference UXs available, including Tablet, Handset and Netbook, but none of these are quite product-ready, and are not necessarily even intended to be.</p>

<p>Because of this it is quite funny to see reviews of the reference UXs. They're not the ones most devices will run, though obviously some manufacturers or community members are going to use them anyway. A full MeeGo product will look and feel like something completely different.</p>

<p>This is not like Android manufacturers adding their own skins. With MeeGo anybody has the full freedom to build a complete user experience that suits their device, branding and other goals. The whole platform has been built to allow this sort of differentiation, without a risk of fragmenting the ecosystem. I'll explain the fragmentation question soon.</p>

<p>Actually, the freedom of defining your own user interface is big enough that both Android and WebOS could theoretically be rebased on top of MeeGo to be just different MeeGo UXs. Obviously they would need to allow running MeeGo-compliant Qt applications in addition to ones written for them directly, but that is minor detail. WebOS already ships Qt, so it isn't even that far from this. Similarly, KDE or GNOME could run as MeeGo UXs.</p>

<h2>Compliance</h2>

<p>At the core of MeeGo there is <a href="http://wiki.meego.com/Quality/Compliance">a set of compliance rules</a>. Being Open Source, anybody can take MeeGo, modify it, and run it on their devices. But only if their implementation passes MeeGo compliance it can be called MeeGo.</p>

<p><em>Device Compliance</em> is a set of rules that ensures any MeeGo-compliant software can run on a particular device. <em>Application Compliance</em> similarly ensures an app can be installed and run on any MeeGo-compliant device.</p>

<p>Both of these sets of compliance rules have automated tests that anybody can run. So, between non-compliant MeeGo-related software there may be fragmentation, but anything branded MeeGo (and therefore compliant) must be fully compatible.</p>

<h2>App Stores and business models</h2>

<p>MeeGo is an open source project, not a company. This means it comes without strings attached, compliance rules aside. There are no limitations on the business model of a MeeGo device manufacturer, no mandatory online services or app stores to enable, and no royalty payments.</p>

<p>With this, each vendor can decide what they want to enable their users to do with the device. An embedded device might have no concept of installable applications, a tablet might come with the vendor's own app store.</p>

<p>For those who do not want to go through trouble of building their own developer ecosystems and app stores, there are some generic solutions available in the MeeGo sphere:</p>

<p>Intel's <a href="http://www.appup.com/applications/index">AppUp</a> is a "white label" app store. This means that a device manufacturer, or even retailer or operator can get an instance of AppUp with their own branding and a revenue sharing deal with Intel. Developers submit software only once and it will be available on all the different branded AppUps.</p>

<p>On the more open side, there is also the upcoming <a href="http://wiki.meego.com/MeeGo_Apps">MeeGo Community Apps</a>, a fully community driven "store" of free software written for MeeGo. It comes with its own, OCS-compatible client application, a web frontend, and clear set of <a href="http://bergie.iki.fi/blog/application_quality_assurance_in_linux_distributions/">crowdsourced app quality assurance</a> processes. The similarly handled Maemo Downloads has served over 80 million downloads for the Nokia N900, so the user and developer interest is clearly there.</p>

<h2>The future of MeeGo</h2>

<p>At this early stage of the project it is hard to make predictions, but there are many things MeeGo gets right. I think it has a bright future ahead of it, especially in more specialized devices. There the shared infrastructure and clear development schedule give manufacturers substantial advantages in both development time and cost.</p>

<p>Product development times in the embedded sector are quite long, and it may well take years before we'll see MeeGo in a airline multimedia system. But if the project shows the necessary durability and longevity, this will eventually happen. Now many of those systems run on customized Linux distributions that their manufacturers have to spend quite a bit of money to maintain. MeeGo removes that problem, and allows easier collaboration through the compliance rules.</p>

<p>As for consumer devices like tablets and handsets, that area mostly requires there to be a vendor that wants to properly differentiate itself from the grey masses of the Android ecosystem. MeeGo provides all the necessary tools on both systems side and user interface development to make that happen.</p>

<p>Currently there are many different ideas floating around on how to build user experiences on connected devices. There is the "wall of apps" approach of iPhone, there are the fully cloud-connected WebOS and Android approaches, and now Microsoft is also starting to enter the game with their own ideas.</p>

<p>I don't think the "post-PC" world is yet complete. What MeeGo gives is a fast way to build products differentiating from that crowd. It just needs companies who are willing to go for it.</p>

<p>The next couple of years will be quite interesting.</p>
]]></content>
        <summary type="html"><![CDATA[

<p><em>Disclaimer: I'm a software developer with a background in Nokia's Maemo mobile Linux ecosystem. I've built both software and community services for it. As a Maemo enthusiast, I've also been following MeeGo with interest, and am helping to build some of the project infrastructure there as well. But I do not speak with the authority of the MeeGo project, and what is written below is my personal view into what MeeGo is.</em></p>

<p>After the recent <a href="http://sf2011.meego.com/">San Francisco MeeGo Conference</a> there has been surprisingly much negative reporting about MeeGo, mostly centered at <a href="http://www.latestnewsin.com/meegos-state-of-development-was-an-oh-shit-moment-for-nokia/">Nokia's MeeGo story</a>. While Nokia's strategy changes are unfortunate, much of the reporting around it appears to come from misunderstanding what MeeGo is about.</p>

<p>Many see MeeGo just as <em>Android without Java</em>, but it is much more, as I'll explain here.</p>

<h2>Industrial Linux</h2>

<p>MeeGo is much more than just handsets or tablets. It is an attempt at creating a standardized industrial Linux distribution that can be used anywhere from in-vehicle infotainment devices to TVs to, indeed, handsets.</p>

<p>It is a true open and collaborative environment, managed by <a href="http://www.linuxfoundation.org/">Linux Foundation</a>. The <a href="https://meego.com/about/governance">governance model</a> is there to ensure that MeeGo stays a vendor-neutral platform that anybody can build their products on top.</p>

<p>Many device segments have very long development, and especially usage times. For this MeeGo has a predictable release schedule of a major release every six months, and <a href="https://meego.com/about/roadmaps">a roadmap</a> kept by the Technical Steering Group.</p>

<p>If MeeGo succeeds in this, you will be using it in your TV, in your car stereo, and at the back of an airline seat. But in most of these situations you won't be able to know that it is MeeGo. It is simply there to make building products faster and cheaper for the manufacturer.</p>

<h2>Openness</h2>

<p>As I argued in my earlier piece <a href="http://bergie.iki.fi/blog/open_source-free_software-what_we_need_is_open_projects/">Open Source? Free Software? What we need is Open Projects</a>, being an open platform is much more than just the licensing terms of the code. There needs to be transparency into the development process, a clear procedure on how to participate and much more. And of course licensing has to be such that the participants can actually use the results in whatever they're doing.</p>

<p>For this, most of <a href="https://meego.com/about/licensing-policy">MeeGo is licensed</a> under permissive terms, like the GNU LGPL and BSD-style licenses.</p>

<p>But indeed, the other aspects of openness are more important. With MeeGo you can see every commit happening on Gitorious, and you can see the bugs and features being worked out in a public Bugzilla.</p>

<p>MeeGo as a project is still quite young, and many participants are still learning how to work in the open. This has lead to <a href="http://lwn.net/Articles/444567/">some issues in project transparency</a>. But hopefully those are now getting resolved.</p>

<h2>User Experience</h2>

<p>MeeGo allows anyone to build their own user experience on top of the platform. Actually, this is expected of any serious manufacturer. Sure, there are some reference UXs available, including Tablet, Handset and Netbook, but none of these are quite product-ready, and are not necessarily even intended to be.</p>

<p>Because of this it is quite funny to see reviews of the reference UXs. They're not the ones most devices will run, though obviously some manufacturers or community members are going to use them anyway. A full MeeGo product will look and feel like something completely different.</p>

<p>This is not like Android manufacturers adding their own skins. With MeeGo anybody has the full freedom to build a complete user experience that suits their device, branding and other goals. The whole platform has been built to allow this sort of differentiation, without a risk of fragmenting the ecosystem. I'll explain the fragmentation question soon.</p>

<p>Actually, the freedom of defining your own user interface is big enough that both Android and WebOS could theoretically be rebased on top of MeeGo to be just different MeeGo UXs. Obviously they would need to allow running MeeGo-compliant Qt applications in addition to ones written for them directly, but that is minor detail. WebOS already ships Qt, so it isn't even that far from this. Similarly, KDE or GNOME could run as MeeGo UXs.</p>

<h2>Compliance</h2>

<p>At the core of MeeGo there is <a href="http://wiki.meego.com/Quality/Compliance">a set of compliance rules</a>. Being Open Source, anybody can take MeeGo, modify it, and run it on their devices. But only if their implementation passes MeeGo compliance it can be called MeeGo.</p>

<p><em>Device Compliance</em> is a set of rules that ensures any MeeGo-compliant software can run on a particular device. <em>Application Compliance</em> similarly ensures an app can be installed and run on any MeeGo-compliant device.</p>

<p>Both of these sets of compliance rules have automated tests that anybody can run. So, between non-compliant MeeGo-related software there may be fragmentation, but anything branded MeeGo (and therefore compliant) must be fully compatible.</p>

<h2>App Stores and business models</h2>

<p>MeeGo is an open source project, not a company. This means it comes without strings attached, compliance rules aside. There are no limitations on the business model of a MeeGo device manufacturer, no mandatory online services or app stores to enable, and no royalty payments.</p>

<p>With this, each vendor can decide what they want to enable their users to do with the device. An embedded device might have no concept of installable applications, a tablet might come with the vendor's own app store.</p>

<p>For those who do not want to go through trouble of building their own developer ecosystems and app stores, there are some generic solutions available in the MeeGo sphere:</p>

<p>Intel's <a href="http://www.appup.com/applications/index">AppUp</a> is a "white label" app store. This means that a device manufacturer, or even retailer or operator can get an instance of AppUp with their own branding and a revenue sharing deal with Intel. Developers submit software only once and it will be available on all the different branded AppUps.</p>

<p>On the more open side, there is also the upcoming <a href="http://wiki.meego.com/MeeGo_Apps">MeeGo Community Apps</a>, a fully community driven "store" of free software written for MeeGo. It comes with its own, OCS-compatible client application, a web frontend, and clear set of <a href="http://bergie.iki.fi/blog/application_quality_assurance_in_linux_distributions/">crowdsourced app quality assurance</a> processes. The similarly handled Maemo Downloads has served over 80 million downloads for the Nokia N900, so the user and developer interest is clearly there.</p>

<h2>The future of MeeGo</h2>

<p>At this early stage of the project it is hard to make predictions, but there are many things MeeGo gets right. I think it has a bright future ahead of it, especially in more specialized devices. There the shared infrastructure and clear development schedule give manufacturers substantial advantages in both development time and cost.</p>

<p>Product development times in the embedded sector are quite long, and it may well take years before we'll see MeeGo in a airline multimedia system. But if the project shows the necessary durability and longevity, this will eventually happen. Now many of those systems run on customized Linux distributions that their manufacturers have to spend quite a bit of money to maintain. MeeGo removes that problem, and allows easier collaboration through the compliance rules.</p>

<p>As for consumer devices like tablets and handsets, that area mostly requires there to be a vendor that wants to properly differentiate itself from the grey masses of the Android ecosystem. MeeGo provides all the necessary tools on both systems side and user interface development to make that happen.</p>

<p>Currently there are many different ideas floating around on how to build user experiences on connected devices. There is the "wall of apps" approach of iPhone, there are the fully cloud-connected WebOS and Android approaches, and now Microsoft is also starting to enter the game with their own ideas.</p>

<p>I don't think the "post-PC" world is yet complete. What MeeGo gives is a fast way to build products differentiating from that crowd. It just needs companies who are willing to go for it.</p>

<p>The next couple of years will be quite interesting.</p>
]]></summary>
    </entry>
    <entry>
        <title>Speeding up midcom/midgard with Varnish</title>
        <link rel="alternate" type="text/html" href="http://www.smallone.net/blog/speeding_up_midcom-midgard_with_varnish/"/>
        <published>2011-06-04T12:18:42+00:00</published>
        <updated>2011-06-04T12:18:42+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-289aaf92053111e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>johan@bernhardsson.nu (Johan Bernhardsson)</name>
        </author>
        <category  term="feed:0e5d3b99667cce293d07bd863d81ca8f" />
        <content type="html"><![CDATA[
<div class="abstract">Speeding up websites is a part of my work. So here a small thing on what varnish can do for midcom based websites.</div>
<p>I have done this on websites running <a href="http://tomcat.apache.org/" target="_blank">Tomcat</a>, <a href="http://wordpress.org/" target="_blank">Wordpress</a>, <a href="http://drupal.org/" target="_blank">Drupal</a> on both large installations and smaller ones. And decided to put a sample on how it affects <a href="http://www.midhard-project.org" target="_blank">Midcom/Midgard</a>.</p>
<p>I did some preliminary tests on how it would work on this blog using one of my testservers for <a href="http://www.varnish-cache.org/" target="_blank">Varnish</a>. Some small and simple rules made the website almost 3 times as fast. And this <a href="http://www.varnish-cache.org/" target="_blank">Varnish</a> installation is not that optimized.</p>
<p>One of the things todo is to cache images .. we do that in vcl_fetch in the vcl code.</p>
<pre> if (req.url ~ "\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|flv|swf|html|htm)$") {
    if (beresp.status == 200) {
      remove beresp.http.Cache-Control;
      remove beresp.http.Set-Cookie;
      remove beresp.http.expires;
      set beresp.http.magicmarker = "1";
      set beresp.http.Cache-Control = "max-age=604800";
      set beresp.ttl = 1d;
      set beresp.cacheable = true;
    }
  }</pre>
<p> </p>
<p>Im using an unconfigured <a href="http://www.joedog.org/index/siege-home" target="_blank">Siege</a> on /blog for about 20 seconds.</p>
<p>Before <a href="http://www.varnish-cache.org/" target="_blank">Varnish</a>:</p>
<pre>Lifting the server siege...      done.
Transactions:		          53 hits
Availability:		      100.00 %
Elapsed time:		       20.28 secs
Data transferred:	        1.53 MB
Response time:		        4.43 secs
Transaction rate:	        2.61 trans/sec
Throughput:		        0.08 MB/sec
Concurrency:		       11.58
Successful transactions:          53
Failed transactions:	           0
Longest transaction:	       12.66
Shortest transaction:	        0.72
</pre>
<p>After <a href="http://www.varnish-cache.org/" target="_blank">Varnish</a>:</p>
<pre>Lifting the server siege...      done.
Transactions:		         170 hits
Availability:		      100.00 %
Elapsed time:		       20.11 secs
Data transferred:	        4.88 MB
Response time:		        1.21 secs
Transaction rate:	        8.45 trans/sec
Throughput:		        0.24 MB/sec
Concurrency:		       10.19
Successful transactions:         170
Failed transactions:	           0
Longest transaction:	        5.58
Shortest transaction:	        0.52
</pre>
<div>Some insights on what small and simple performance tasks can do for your website. To speed things up more we can use <a href="http://www.varnish-cache.org" target="_blank">Varnish</a> to fron several midgard enabled backends to spread the load.</div>]]></content>
        <summary type="html"><![CDATA[
<div class="abstract">Speeding up websites is a part of my work. So here a small thing on what varnish can do for midcom based websites.</div>
<p>I have done this on websites running <a href="http://tomcat.apache.org/" target="_blank">Tomcat</a>, <a href="http://wordpress.org/" target="_blank">Wordpress</a>, <a href="http://drupal.org/" target="_blank">Drupal</a> on both large installations and smaller ones. And decided to put a sample on how it affects <a href="http://www.midhard-project.org" target="_blank">Midcom/Midgard</a>.</p>
<p>I did some preliminary tests on how it would work on this blog using one of my testservers for <a href="http://www.varnish-cache.org/" target="_blank">Varnish</a>. Some small and simple rules made the website almost 3 times as fast. And this <a href="http://www.varnish-cache.org/" target="_blank">Varnish</a> installation is not that optimized.</p>
<p>One of the things todo is to cache images .. we do that in vcl_fetch in the vcl code.</p>
<pre> if (req.url ~ "\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|flv|swf|html|htm)$") {
    if (beresp.status == 200) {
      remove beresp.http.Cache-Control;
      remove beresp.http.Set-Cookie;
      remove beresp.http.expires;
      set beresp.http.magicmarker = "1";
      set beresp.http.Cache-Control = "max-age=604800";
      set beresp.ttl = 1d;
      set beresp.cacheable = true;
    }
  }</pre>
<p> </p>
<p>Im using an unconfigured <a href="http://www.joedog.org/index/siege-home" target="_blank">Siege</a> on /blog for about 20 seconds.</p>
<p>Before <a href="http://www.varnish-cache.org/" target="_blank">Varnish</a>:</p>
<pre>Lifting the server siege...      done.
Transactions:		          53 hits
Availability:		      100.00 %
Elapsed time:		       20.28 secs
Data transferred:	        1.53 MB
Response time:		        4.43 secs
Transaction rate:	        2.61 trans/sec
Throughput:		        0.08 MB/sec
Concurrency:		       11.58
Successful transactions:          53
Failed transactions:	           0
Longest transaction:	       12.66
Shortest transaction:	        0.72
</pre>
<p>After <a href="http://www.varnish-cache.org/" target="_blank">Varnish</a>:</p>
<pre>Lifting the server siege...      done.
Transactions:		         170 hits
Availability:		      100.00 %
Elapsed time:		       20.11 secs
Data transferred:	        4.88 MB
Response time:		        1.21 secs
Transaction rate:	        8.45 trans/sec
Throughput:		        0.24 MB/sec
Concurrency:		       10.19
Successful transactions:         170
Failed transactions:	           0
Longest transaction:	        5.58
Shortest transaction:	        0.52
</pre>
<div>Some insights on what small and simple performance tasks can do for your website. To speed things up more we can use <a href="http://www.varnish-cache.org" target="_blank">Varnish</a> to fron several midgard enabled backends to spread the load.</div>]]></summary>
    </entry>
    <entry>
        <title>Want to do something similar to PostRank?</title>
        <link rel="alternate" type="text/html" href="http://bergie.iki.fi/blog/want_to_do_something_similar_to_postrank/"/>
        <published>2011-06-04T08:29:33+00:00</published>
        <updated>2011-06-04T08:29:33+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-d299f8c8053011e1ac714b279f5ac7ccc7cc</id>
        <author>
            <name>henri.bergius@iki.fi (Henri Bergius)</name>
        </author>
        <category  term="feed:e1ac443192c214d3dd05c950b16e0929" />
        <content type="html"><![CDATA[

<p>So, <a href="http://blog.postrank.com/2011/06/postrank-has-been-acquired-by-google/">Google acquired PostRank</a>, the service calculating impact of blog posts and other items in social media.</p>
<p>If you want something similar but without the Google tie-in, then a good option is my <a href="https://github.com/nemein/com_meego_planet">social impact calculator</a> which is fully free software written in PHP. It was originally <a href="http://bergie.iki.fi/blog/calculating_news_item_relevance/">written in 2007</a>, but the newer version has been cleaned of Midgard dependencies and updated to reflect the current popular social networking services. Usage example from <a href="http://bergie.iki.fi/blog/calculate_the_impact_of_your_posts/">my earlier post</a>:</p>
<p><span style="color:#333333;font-family:'Lucida Grande', Verdana, Arial, sans-serif;font-size:13px;">
</span></p><pre>require('calculate.php');

$url = 'http://bergie.iki.fi/blog/introducing_the_midgard_create_user_interface/';

// Get the raw count for only one source
echo com_meego_planet_calculate::hackernews($url); // 145
echo com_meego_planet_calculate::facebook($url); // 1

// Get weighted total score for all sources
echo com_meego_planet_calculate::all($url); // 130.8</pre>
]]></content>
        <summary type="html"><![CDATA[

<p>So, <a href="http://blog.postrank.com/2011/06/postrank-has-been-acquired-by-google/">Google acquired PostRank</a>, the service calculating impact of blog posts and other items in social media.</p>
<p>If you want something similar but without the Google tie-in, then a good option is my <a href="https://github.com/nemein/com_meego_planet">social impact calculator</a> which is fully free software written in PHP. It was originally <a href="http://bergie.iki.fi/blog/calculating_news_item_relevance/">written in 2007</a>, but the newer version has been cleaned of Midgard dependencies and updated to reflect the current popular social networking services. Usage example from <a href="http://bergie.iki.fi/blog/calculate_the_impact_of_your_posts/">my earlier post</a>:</p>
<p><span style="color:#333333;font-family:'Lucida Grande', Verdana, Arial, sans-serif;font-size:13px;">
</span></p><pre>require('calculate.php');

$url = 'http://bergie.iki.fi/blog/introducing_the_midgard_create_user_interface/';

// Get the raw count for only one source
echo com_meego_planet_calculate::hackernews($url); // 145
echo com_meego_planet_calculate::facebook($url); // 1

// Get weighted total score for all sources
echo com_meego_planet_calculate::all($url); // 130.8</pre>
]]></summary>
    </entry>
    <entry>
        <title>One year has passed…</title>
        <link rel="alternate" type="text/html" href="http://jemiweb.wordpress.com/2011/04/02/one-year-has-passed/"/>
        <published>2011-04-01T22:21:03+00:00</published>
        <updated>2011-04-01T22:21:03+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-fdc0f4b4642411e093f36f5ad15a66f966f9</id>
        <author>
            <name>jemi@iki.fi (Edvard Immonen)</name>
        </author>
        <category  term="feed:8a14b25060334d992b2c32782632632e" />
        <content type="html"><![CDATA[
&#8230;and there are many things going on. I&#8217;d been working on different VRM projects from taxi services through health2.0 and now we are building groundbreaking stuff within the Vendor Relationship Marketing area. Stay tunes on us &#8211; we are coming out from the stealth mode in may&#8230;perhaps here: http://www.multi-mania.be/2011/conference/ Stay tuned fore more&#8230;and I&#8217;d really [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jemiweb.wordpress.com&amp;blog=2426414&amp;post=95&amp;subd=jemiweb&amp;ref=&amp;feed=1" width="1" height="1" />]]></content>
        <summary type="html"><![CDATA[
&#8230;and there are many things going on. I&#8217;d been working on different VRM projects from taxi services through health2.0 and now we are building groundbreaking stuff within the Vendor Relationship Marketing area. Stay tunes on us &#8211; we are coming out from the stealth mode in may&#8230;perhaps here: http://www.multi-mania.be/2011/conference/ Stay tuned fore more&#8230;and I&#8217;d really [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jemiweb.wordpress.com&amp;blog=2426414&amp;post=95&amp;subd=jemiweb&amp;ref=&amp;feed=1" width="1" height="1" />]]></summary>
    </entry>
    <entry>
        <title>using Python with GObject Introspection</title>
        <link rel="alternate" type="text/html" href="http://blog.milkfarmsoft.com/2011/03/pygi/"/>
        <published>2011-03-17T21:32:23+00:00</published>
        <updated>2011-03-17T21:32:23+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-9d1fbb8853ab11e09b1a5900587acd03cd03</id>
        <author>
            <name>indeyets@gmail.com (Alexey Zakhlestine)</name>
        </author>
        <category  term="feed:e21651cb75a5ec45a4dc685512c73dd2" />
        <content type="html"><![CDATA[
<p>I was recently working on <a href="https://github.com/midgardproject/midgard-daemon">one small tool</a> for <a href="http://www.midgard-project.org/" title="Midgard Project">Midgard Project</a>, and had to deal with a new framework: <a href="http://live.gnome.org/PyGI" title="PyGI - GNOME Live!">PyGI</a>. Strictly speaking, it&#8217;s not &#8220;totally new&#8221;, but it is: a) new for me b) just starts to get attention from application developers.</p>
<p>PyGI is a project, which implements dynamic bindings to GObject based libraries for Python using <a href="http://live.gnome.org/GObjectIntrospection" title="GObjectIntrospection - GNOME Live!">GObject Introspection</a>. Initially, it was a separate project, these days it is merged into main <a href="http://live.gnome.org/PyGObject" title="PyGObject - GNOME Live!">PyGObect</a>. If you read my previous posts, this is kinda what we want to implement for PHP in <a href="http://blog.milkfarmsoft.com/2011/02/gobject-for-php-new-bindings-project/" title="GObject for PHP (new bindings project) &laquo; Alexey Zakhlestins blog">GObject for PHP</a> project, but for Python.</p>
<p>For the project, I used Python 3. This choice led to the requirement of installing latest versions of software, but the good news is, that coming <a href="https://wiki.ubuntu.com/NattyNarwhal">Ubuntu Natty</a> has a good initial set of software. So, I had to install:</p>
<ul>
<li>Python 3.1 (3.2 should work too)</li>
<li><a href="http://ftp.gnome.org/pub/GNOME/sources/gobject-introspection/0.10/" title="ftp.gnome.org">GObject Introspection 0.10.x</a></li>
<li><a href="http://ftp.gnome.org/pub/GNOME/sources/pygobject/2.28/" title="ftp.gnome.org">PyGObject 2.28.0</a> (2.27.x-dev series are ok too)</li>
<li>If you plan to work with ØMQ, as I did, be sure to grab <a href="http://www.zeromq.org/bindings:python" title="Python binding - zeromq">PyZMQ</a> 2.1 series (easy_install will probably work)</li>
</ul>
<p>The main library, I worked with — <a href="https://github.com/midgardproject/midgard-core/tree/ratatoskr">libmidgard2</a> — supports GObject introspection, so I didn&#8217;t need to install anything python-related to make it work.</p>
<p>Ok. Here are some hints on coding using PyGI.</p>
<pre><code class="python">
    # to use introspection-friendly library use import statement similar to this
    from gi.repository import Midgard

    # global functions are available directly in imported package
    Midgard.init()

    # constructors are ALWAYS called with "named" parameters
    config = Midgard.Config(dbtype = "SQLite", database = "testdb")

    # library errors are thrown as exceptions
    import gobject
    try:
        do_something()
    except gobject.GError as e:
        print(e.message)

    # want to know name of objects GType?
    print(obj.__class__.__gtype__.name)

    # want to get list of non-object properties of some GObject?
    property_names = [pspec.name for pspec in obj.props if not pspec.value_type.is_classed()]

    # need to get names of all classes, which inherit from your GObject's class?
    # (note: Midgard.Object is the class to be replaced by your class)
    child_names = [gtype.name for gtype in Midgard.Object.__gtype__.children]

</code></pre>
]]></content>
        <summary type="html"><![CDATA[
<p>I was recently working on <a href="https://github.com/midgardproject/midgard-daemon">one small tool</a> for <a href="http://www.midgard-project.org/" title="Midgard Project">Midgard Project</a>, and had to deal with a new framework: <a href="http://live.gnome.org/PyGI" title="PyGI - GNOME Live!">PyGI</a>. Strictly speaking, it&#8217;s not &#8220;totally new&#8221;, but it is: a) new for me b) just starts to get attention from application developers.</p>
<p>PyGI is a project, which implements dynamic bindings to GObject based libraries for Python using <a href="http://live.gnome.org/GObjectIntrospection" title="GObjectIntrospection - GNOME Live!">GObject Introspection</a>. Initially, it was a separate project, these days it is merged into main <a href="http://live.gnome.org/PyGObject" title="PyGObject - GNOME Live!">PyGObect</a>. If you read my previous posts, this is kinda what we want to implement for PHP in <a href="http://blog.milkfarmsoft.com/2011/02/gobject-for-php-new-bindings-project/" title="GObject for PHP (new bindings project) &laquo; Alexey Zakhlestins blog">GObject for PHP</a> project, but for Python.</p>
<p>For the project, I used Python 3. This choice led to the requirement of installing latest versions of software, but the good news is, that coming <a href="https://wiki.ubuntu.com/NattyNarwhal">Ubuntu Natty</a> has a good initial set of software. So, I had to install:</p>
<ul>
<li>Python 3.1 (3.2 should work too)</li>
<li><a href="http://ftp.gnome.org/pub/GNOME/sources/gobject-introspection/0.10/" title="ftp.gnome.org">GObject Introspection 0.10.x</a></li>
<li><a href="http://ftp.gnome.org/pub/GNOME/sources/pygobject/2.28/" title="ftp.gnome.org">PyGObject 2.28.0</a> (2.27.x-dev series are ok too)</li>
<li>If you plan to work with ØMQ, as I did, be sure to grab <a href="http://www.zeromq.org/bindings:python" title="Python binding - zeromq">PyZMQ</a> 2.1 series (easy_install will probably work)</li>
</ul>
<p>The main library, I worked with — <a href="https://github.com/midgardproject/midgard-core/tree/ratatoskr">libmidgard2</a> — supports GObject introspection, so I didn&#8217;t need to install anything python-related to make it work.</p>
<p>Ok. Here are some hints on coding using PyGI.</p>
<pre><code class="python">
    # to use introspection-friendly library use import statement similar to this
    from gi.repository import Midgard

    # global functions are available directly in imported package
    Midgard.init()

    # constructors are ALWAYS called with "named" parameters
    config = Midgard.Config(dbtype = "SQLite", database = "testdb")

    # library errors are thrown as exceptions
    import gobject
    try:
        do_something()
    except gobject.GError as e:
        print(e.message)

    # want to know name of objects GType?
    print(obj.__class__.__gtype__.name)

    # want to get list of non-object properties of some GObject?
    property_names = [pspec.name for pspec in obj.props if not pspec.value_type.is_classed()]

    # need to get names of all classes, which inherit from your GObject's class?
    # (note: Midgard.Object is the class to be replaced by your class)
    child_names = [gtype.name for gtype in Midgard.Object.__gtype__.children]

</code></pre>
]]></summary>
    </entry>
    <entry>
        <title>On feature-branches and pull-requests</title>
        <link rel="alternate" type="text/html" href="http://blog.milkfarmsoft.com/2011/03/on-feature-branches/"/>
        <published>2011-03-17T13:22:18+00:00</published>
        <updated>2011-03-17T13:22:18+00:00</updated>
        <id>http://www.midgard-project.org/midcom-permalink-9adc8b5853ab11e09b1a5900587acd03cd03</id>
        <author>
            <name>indeyets@gmail.com (Alexey Zakhlestine)</name>
        </author>
        <category  term="feed:e21651cb75a5ec45a4dc685512c73dd2" />
        <content type="html"><![CDATA[
<p>Everyone and their mother uses <a href="http://git-scm.com/" title="Git - Fast Version Control System">Git</a> + <a href="https://github.com/">GitHub</a> combo these days. A lot of open-source projects accept patches using github&#8217;s <a href="http://help.github.com/pull-requests/" title="Help.GitHub - Sending pull requests">pull requests</a>, because… well, because it is the easiest way to review and accept patches.</p>
<p><img src="http://blog.milkfarmsoft.com/wp-content/uploads/2011/03/Screen-shot-2011-03-17-at-16.19.51.png" alt="" title="commits" width="377" height="299" /></p>
<p>But, novice Git users don&#8217;t know how to do this optimally, and &#8220;naive&#8221; approach leads to complexities. Git is a distributed version control system, which means that everyone can &#8220;commit&#8221; to their copies of repositories. Syncing these commits with upstream is a bit more difficult and leads to commit-conflicts sometimes. So, here&#8217;s aforementioned &#8220;naive&#8221; approach:</p>
<ol style="padding-left: 30px">
<li>Fork upstream github repository</li>
<li>Clone forked repository to local machine</li>
<li>Make changes</li>
<li>Commit</li>
<li>Push</li>
<li>Send Pull Request</li>
</ol>
<p>It will work, but, there&#8217;s one non-obvious thing: pull request, probably, won&#8217;t be merged immediately and there are high chances, that there will be some commits commits pushed to official repository before our commit is merged. As the result, we have a conflict between upstream repository and our forked repository. So, at this point, if we plan to use our forked repository again, we have to &#8220;merge&#8221; upstream changes. It&#8217;s not end of the world, and git, if we&#8217;re lucky enough, will do this merge automatically as part of &#8220;<code>git pull upstream</code>&#8220;, but it won&#8217;t be &#8220;fast-forward&#8221; merge and github&#8217;s &#8220;<a href="https://github.com/blog/39-say-hello-to-the-network-graph-visualizer">Network</a>&#8221; diagram (or branches diagram in your favourite git GUI) won&#8217;t be nice and clean anymore.</p>
<p>There&#8217;s better approach, and it&#8217;s name is &#8220;<strong>Feature Branches</strong>&#8220;. It&#8217;s quite simple. Once you have cloned forked repository (i.e. after steps 1-2), use &#8220;<code>git checkout -b new_branch_name</code>&#8221; command (it&#8217;s nice, if &#8220;new_branch_name&#8221; summarises changes you&#8217;re going to implement). This command creates new branch, starting from current &#8220;master&#8221; and makes it active. Make changes and commit them: &#8220;master&#8221; branch is left intact and all the things you changed sit nicely in this new branch. Now, push these changes with &#8220;<code>git push origin new_branch_name</code>&#8221; command. This will send your new branch to github. Now, open this branch on github and send Pull Request from your &#8220;new_branch_name&#8221; to upstream&#8217;s &#8220;master&#8221;, as usually.</p>
<p>Use &#8220;<code>git checkout master</code>&#8221; to return to the &#8220;master&#8221; branch, and, whenever upstream merges your changes, and you pull those, they will appear here automatically, without a single &#8220;merge&#8221; effort from you. As a bonus, you get beautiful tree of branches without complex knots.</p>
]]></content>
        <summary type="html"><![CDATA[
<p>Everyone and their mother uses <a href="http://git-scm.com/" title="Git - Fast Version Control System">Git</a> + <a href="https://github.com/">GitHub</a> combo these days. A lot of open-source projects accept patches using github&#8217;s <a href="http://help.github.com/pull-requests/" title="Help.GitHub - Sending pull requests">pull requests</a>, because… well, because it is the easiest way to review and accept patches.</p>
<p><img src="http://blog.milkfarmsoft.com/wp-content/uploads/2011/03/Screen-shot-2011-03-17-at-16.19.51.png" alt="" title="commits" width="377" height="299" /></p>
<p>But, novice Git users don&#8217;t know how to do this optimally, and &#8220;naive&#8221; approach leads to complexities. Git is a distributed version control system, which means that everyone can &#8220;commit&#8221; to their copies of repositories. Syncing these commits with upstream is a bit more difficult and leads to commit-conflicts sometimes. So, here&#8217;s aforementioned &#8220;naive&#8221; approach:</p>
<ol style="padding-left: 30px">
<li>Fork upstream github repository</li>
<li>Clone forked repository to local machine</li>
<li>Make changes</li>
<li>Commit</li>
<li>Push</li>
<li>Send Pull Request</li>
</ol>
<p>It will work, but, there&#8217;s one non-obvious thing: pull request, probably, won&#8217;t be merged immediately and there are high chances, that there will be some commits commits pushed to official repository before our commit is merged. As the result, we have a conflict between upstream repository and our forked repository. So, at this point, if we plan to use our forked repository again, we have to &#8220;merge&#8221; upstream changes. It&#8217;s not end of the world, and git, if we&#8217;re lucky enough, will do this merge automatically as part of &#8220;<code>git pull upstream</code>&#8220;, but it won&#8217;t be &#8220;fast-forward&#8221; merge and github&#8217;s &#8220;<a href="https://github.com/blog/39-say-hello-to-the-network-graph-visualizer">Network</a>&#8221; diagram (or branches diagram in your favourite git GUI) won&#8217;t be nice and clean anymore.</p>
<p>There&#8217;s better approach, and it&#8217;s name is &#8220;<strong>Feature Branches</strong>&#8220;. It&#8217;s quite simple. Once you have cloned forked repository (i.e. after steps 1-2), use &#8220;<code>git checkout -b new_branch_name</code>&#8221; command (it&#8217;s nice, if &#8220;new_branch_name&#8221; summarises changes you&#8217;re going to implement). This command creates new branch, starting from current &#8220;master&#8221; and makes it active. Make changes and commit them: &#8220;master&#8221; branch is left intact and all the things you changed sit nicely in this new branch. Now, push these changes with &#8220;<code>git push origin new_branch_name</code>&#8221; command. This will send your new branch to github. Now, open this branch on github and send Pull Request from your &#8220;new_branch_name&#8221; to upstream&#8217;s &#8220;master&#8221;, as usually.</p>
<p>Use &#8220;<code>git checkout master</code>&#8221; to return to the &#8220;master&#8221; branch, and, whenever upstream merges your changes, and you pull those, they will appear here automatically, without a single &#8220;merge&#8221; effort from you. As a bonus, you get beautiful tree of branches without complex knots.</p>
]]></summary>
    </entry>
</feed>

