<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>Frederik Dietz</title>
 <link href="http://fdietz.github.com/atom.xml" rel="self"/>
 <link href="http://fdietz.github.com/"/>
 <updated>2019-04-07T17:23:08+02:00</updated>
 <id>http://fdietz.github.com/</id>
 <author>
   <name>Frederik Dietz</name>
   <email>fdietz@gmail.com</email>
 </author>

 
 <entry>
   <title>Vue.js Component Composition with Scoped Slots</title>
   <link href="http://fdietz.github.com/2018/09/13/vue-js-component-composition-with-scoped-slots.html"/>
   <updated>2018-09-13T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2018/09/13/vue-js-component-composition-with-scoped-slots</id>
   <content type="html">&lt;p&gt;In the &lt;a href=&quot;/2018/09/05/vue-js-component-composition-with-slots.html&quot;&gt;previous post&lt;/a&gt; we looked into slots and named slots to compose our components and content in a very flexible way.
There’s one catch though we have not discussed. The content we pass to our slot is in the context of the parent component and not the child component. This sounds quite abstract, let’s build an example component and investigate the problem further!&lt;/p&gt;

&lt;h2 id=&quot;list-of-items-example&quot;&gt;List of Items Example&lt;/h2&gt;

&lt;p&gt;Probably the most canonical example for this kind of scenario is a todo list which renders for each todo a checkbox with name.&lt;/p&gt;

&lt;figure&gt;
  &lt;img width=&quot;50%&quot; alt=&quot;Example 1&quot; src=&quot;/assets/list-3d2c4519af74f6f3b242312c1d042df4548d6e4bca35a91bf2d938476bb93839.png&quot; /&gt;
  &lt;figcaption&gt;Example 1&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div id=&amp;quot;demo&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;list&amp;quot;&amp;gt;
    &amp;lt;div v-for=&amp;quot;item in listItems&amp;quot; key=&amp;quot;item.id&amp;quot; class=&amp;quot;list-item&amp;quot;&amp;gt;
      &amp;lt;input type=&amp;quot;checkbox&amp;quot; v-model=&amp;quot;item.completed&amp;quot; class=&amp;quot;list-item__checkbox&amp;quot; /&amp;gt;
      {{item.name}}
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;new Vue({ 
  el: &amp;#39;#demo&amp;#39;,
  data: {
    listItems: [
      {id: 1, name: &amp;quot;item 1&amp;quot;, completed: false},
      {id: 2, name: &amp;quot;item 2&amp;quot;, completed: false},
      {id: 3, name: &amp;quot;item 3&amp;quot;, completed: false}
    ]
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;In the next step we refactor this code into a reusable list component and our goal is to leave it up to the client of the component to decide what and how to render the list item.&lt;/p&gt;

&lt;h2 id=&quot;refactor-to-reusable-list-component&quot;&gt;Refactor to Reusable List component&lt;/h2&gt;

&lt;p&gt;Let’s start with the implementation of the List component:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;Vue.component(&amp;quot;List&amp;quot;, {
  template: &amp;quot;#template-list&amp;quot;,
  props: {
    items: {
      type: Array, 
      default: []
    }
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;template id=&amp;quot;template-list&amp;quot;&amp;gt;  
  &amp;lt;div class=&amp;quot;list&amp;quot;&amp;gt;
    &amp;lt;div v-for=&amp;quot;item in items&amp;quot; class=&amp;quot;list-item&amp;quot;&amp;gt;
      &amp;lt;slot&amp;gt;&amp;lt;/slot&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Following our previous examples we use the default slot to render a list item.&lt;/p&gt;

&lt;p&gt;And now make use of our new component:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div id=&amp;quot;demo&amp;quot;&amp;gt;
  &amp;lt;List :items=&amp;quot;listItems&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;list-item&amp;quot;&amp;gt;
      &amp;lt;input type=&amp;quot;checkbox&amp;quot; v-model=&amp;quot;item.completed&amp;quot; class=&amp;quot;list-item__checkbox&amp;quot; /&amp;gt;
      &amp;lt;div class=&amp;quot;list-item__title&amp;quot;&amp;gt;{{item.name}}&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/List&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;But, when trying this example we run into a Javascript error message:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;ReferenceError: item is not defined&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;It seems we cannot access &lt;code&gt;item&lt;/code&gt; from our slot content. In fact the content we passed runs in the context of the parent and not the child component &lt;code&gt;List&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s verify this by printing the total number of items in our &lt;code&gt;List&lt;/code&gt; component using the &lt;code&gt;listItems&lt;/code&gt; data defined in our Vue instance.&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div id=&amp;quot;demo&amp;quot;&amp;gt;
  &amp;lt;List :items=&amp;quot;listItems&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;list-item&amp;quot;&amp;gt;
      {{listItems}}
    &amp;lt;/div&amp;gt;
  &amp;lt;/List&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;That works because we run in the context of the parent component which is in this example the Vue instance. But, how can we pass the &lt;code&gt;item&lt;/code&gt; data from our child &lt;code&gt;&amp;lt;List&amp;gt;&lt;/code&gt; to our slot? This is where “scoped slots” come to the rescue!&lt;/p&gt;

&lt;p&gt;Our component must pass along &lt;code&gt;item&lt;/code&gt; as a prop to the slot itself:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;template id=&amp;quot;template-list&amp;quot;&amp;gt;  
  &amp;lt;div class=&amp;quot;list&amp;quot;&amp;gt;
    &amp;lt;div v-for=&amp;quot;item in items&amp;quot; class=&amp;quot;list-item&amp;quot;&amp;gt;
      &amp;lt;slot :item=&amp;quot;item&amp;quot;&amp;gt;&amp;lt;/slot&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note, that it is important to pass this with a binding &lt;code&gt;:item&lt;/code&gt; instead of only &lt;code&gt;item&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;Okay let’s try this again:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div id=&amp;quot;demo&amp;quot;&amp;gt;
  &amp;lt;List :items=&amp;quot;listItems&amp;quot;&amp;gt;
    &amp;lt;div slot-scope=&amp;quot;slotProps&amp;quot; class=&amp;quot;list-item&amp;quot;&amp;gt;
      &amp;lt;input type=&amp;quot;checkbox&amp;quot; v-model=&amp;quot;slotProps.item.completed&amp;quot; class=&amp;quot;list-item__checkbox&amp;quot; /&amp;gt;
      &amp;lt;div class=&amp;quot;list-item__title&amp;quot;&amp;gt;{{slotProps.item.name}}&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/List&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This time we use the &lt;code&gt;slot-scope&lt;/code&gt; attribute and assign the name &lt;code&gt;slotProps&lt;/code&gt; to it. Inside this scoped slot we can access all props passed along via this &lt;code&gt;slotProps&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;In Vue.js 2.5.0+, scope is no longer limited to the &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; element, but can instead be used on any element or component in the slot.&lt;/p&gt;

&lt;h2 id=&quot;extending-the-rendering-of-the-list-item&quot;&gt;Extending the rendering of the list item&lt;/h2&gt;

&lt;p&gt;Now that we know how to pass data along we are free to extend the list item with some new functionality without changing the List component. It would be awesome if we could remove a todo item!&lt;/p&gt;

&lt;p&gt;First of all we define the Vue app with a method to remove a todo item:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;new Vue({ 
  el: &amp;#39;#demo&amp;#39;,
  data: {
    listItems: [
      {id: 1, name: &amp;quot;item 1&amp;quot;, completed: false},
      {id: 2, name: &amp;quot;item 2&amp;quot;, completed: false},
      {id: 3, name: &amp;quot;item 3&amp;quot;, completed: false}
    ]
  },
  methods: {
    remove(item) {
      this.listItems.splice(this.listItems.indexOf(item), 1);
    }
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We use the Javascript &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice&quot;&gt;splice&lt;/a&gt; function to remove the item using it’s index from &lt;code&gt;listItems&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, we use this method when rendering the list item:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;template slot-scope=&amp;quot;slotProps&amp;quot; class=&amp;quot;list-item&amp;quot;&amp;gt;
  &amp;lt;input type=&amp;quot;checkbox&amp;quot; v-model=&amp;quot;slotProps.item.completed&amp;quot; class=&amp;quot;list-item__checkbox&amp;quot; /&amp;gt;
  &amp;lt;div class=&amp;quot;list-item__title&amp;quot;&amp;gt;{{slotProps.item.name}}&amp;lt;/div&amp;gt;
  &amp;lt;button @click=&amp;quot;remove(slotProps.item)&amp;quot; class=&amp;quot;list-item__remove&amp;quot;&amp;gt;×&amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We add a button with a &lt;code&gt;click&lt;/code&gt; event which calls our previously defined &lt;code&gt;remove&lt;/code&gt; function. That’s it!&lt;/p&gt;

&lt;h2 id=&quot;using-destructuring-for-the-slot-scope&quot;&gt;Using Destructuring for the &lt;code&gt;slot-scope&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;We can further simplify this template by using a modern Javascript trick on the &lt;code&gt;slot-scope&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;Here’s an example of using Javascript “destructuring” to access an attribute of an object:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const item = slotProps.item;
// same as 
const { item } = slotProps;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Instead of using the value &lt;code&gt;slotProps&lt;/code&gt; we can now access the &lt;code&gt;item&lt;/code&gt; directly.&lt;/p&gt;

&lt;p&gt;Let’s use this in our template:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;template slot-scope=&amp;quot;{item}&amp;quot; class=&amp;quot;list-item&amp;quot;&amp;gt;
  &amp;lt;input type=&amp;quot;checkbox&amp;quot; v-model=&amp;quot;item.completed&amp;quot; class=&amp;quot;list-item__checkbox&amp;quot; /&amp;gt;
  &amp;lt;div class=&amp;quot;list-item__title&amp;quot;&amp;gt;{{item.name}}&amp;lt;/div&amp;gt;
  &amp;lt;button @click=&amp;quot;remove(item)&amp;quot; class=&amp;quot;list-item__remove&amp;quot;&amp;gt;×&amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is easier to read because we can directly use the &lt;code&gt;item&lt;/code&gt; variable instead of always going via &lt;code&gt;slotProps.item&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;In this chapter we used scoped slots to allow the parent to access data from the child. This gives us lots of new possibilities which weren’t possible before. This feature is especially useful in scenarios where you want to leave the rendering of the slot content to the user of the component. In our case the list component is very reusable by decoupling the rendering of the list items.&lt;/p&gt;

&lt;p&gt;You can find the complete examples on &lt;a href=&quot;https://github.com/fdietz/vue_components_book_examples/tree/master/chapter-4&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you like this post also check out my new course &lt;a href=&quot;/vue-component-patterns-course.html&quot;&gt;Vue.js Component Patterns Course&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Stay tuned for my upcoming post about headless components!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Vue.js Component Composition with Slots</title>
   <link href="http://fdietz.github.com/2018/09/05/vue-js-component-composition-with-slots.html"/>
   <updated>2018-09-05T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2018/09/05/vue-js-component-composition-with-slots</id>
   <content type="html">&lt;p&gt;In the &lt;a href=&quot;/2018/08/23/introduction-to-vue-js-components.html&quot;&gt;previous post&lt;/a&gt; we introduced the Vue.js component model and saw how to pass data to 
child components via &lt;code&gt;props&lt;/code&gt; and how components can emit events up their parents.&lt;/p&gt;

&lt;p&gt;In this chapter we focus on slots which give your components even more flexibility by injecting content into child components.&lt;/p&gt;

&lt;p&gt;For this chapter we use a modal dialog as an example.&lt;/p&gt;

&lt;figure&gt;
  &lt;img width=&quot;50%&quot; alt=&quot;Modal Dialog with close button&quot; src=&quot;/assets/modal-11bb5aed7e98c91617f0b4e758ca0cdc22115a9fa5280a78f397aa0059abf2ee.png&quot; /&gt;
  &lt;figcaption&gt;Modal Dialog with close button&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;slots-as-content-placeholders&quot;&gt;Slots as Content Placeholders&lt;/h2&gt;

&lt;p&gt;We start with the smallest possible modal dialog implementation where the rendering of the modal is done using a &lt;code&gt;v-if&lt;/code&gt; directive with the &lt;code&gt;showModal&lt;/code&gt; variable.&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;new Vue({
  el: &amp;quot;#demo&amp;quot;,
  data: {
    showModal: false
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;showModal&lt;/code&gt; value is set to &lt;code&gt;true&lt;/code&gt; on button click:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div id=&amp;quot;demo&amp;quot;&amp;gt;
  &amp;lt;modal v-if=&amp;quot;showModal&amp;quot; @close=&amp;quot;showModal = false&amp;quot;&amp;gt;
    &amp;lt;h2&amp;gt;Modal Header&amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;This is a paragraph inside the modal.&amp;lt;/p&amp;gt;
  &amp;lt;/modal&amp;gt;
  &amp;lt;button @click=&amp;quot;showModal = true&amp;quot;&amp;gt;Show Modal&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Our &lt;code&gt;modal&lt;/code&gt; component children consist of some example HTML heading and paragraph we’d like to show inside the modal dialog.&lt;/p&gt;

&lt;p&gt;Additionally, we listen to the &lt;code&gt;@close&lt;/code&gt; event in case the user closes the modal dialog by pressing the close button.&lt;/p&gt;

&lt;p&gt;Let’s have a look at the component:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;template id=&amp;quot;template-modal&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;modal-background&amp;quot; @click.self=&amp;quot;$emit(&amp;#39;close&amp;#39;)&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;modal-container&amp;quot;&amp;gt;
      &amp;lt;div class=&amp;quot;modal-body&amp;quot;&amp;gt;
        &amp;lt;slot&amp;gt;&amp;lt;/slot&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;modal-footer&amp;quot;&amp;gt;
        &amp;lt;button @click=&amp;quot;$emit(&amp;#39;close&amp;#39;)&amp;quot;&amp;gt;Close&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;modal-body&lt;/code&gt; contains a &lt;code&gt;slot&lt;/code&gt; component which acts as a placeholder for our content we passed along above. It will not be visible in the browser DOM and will be replaced with our content.&lt;/p&gt;

&lt;figure&gt;
  &lt;img width=&quot;75%&quot; alt=&quot;Screenshot of Chrome Devtools Elements Tab&quot; src=&quot;/assets/modal_dom-b6fc4f23cfa1828bca7b4724babb08041ba3cdf4ec05473f81a3263d584102bc.png&quot; /&gt;
  &lt;figcaption&gt;Screenshot of Chrome Devtools Elements Tab&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The &lt;code&gt;modal-background&lt;/code&gt; class used to render a darkened overlay underneath the modal dialog. Additionally, it emits a &lt;code&gt;click&lt;/code&gt; event to close the dialog. The &lt;code&gt;self&lt;/code&gt; &lt;a href=&quot;https://vuejs.org/v2/guide/events.html#Event-Modifiers&quot;&gt;event modifier&lt;/a&gt; is used to make sure the event is only emitted when clicking the background and not when clicking the modal dialog itself.&lt;/p&gt;

&lt;h2 id=&quot;named-slots&quot;&gt;Named Slots&lt;/h2&gt;

&lt;p&gt;In our previous example we used the “default slot” to pass along all content to our modal component. In the next example we improve the modal dialog component further by using “named slots” which enables users of the component to inject content in multiple places.&lt;/p&gt;

&lt;p&gt;In order to become more flexible, we introduce named slots for the header, body and footer. Here is the definition of our markup:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;template id=&amp;quot;template-modal&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;modal-background&amp;quot; @click.self=&amp;quot;$emit(&amp;#39;close&amp;#39;)&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;modal-container&amp;quot;&amp;gt;
      &amp;lt;div class=&amp;quot;modal-header&amp;quot;&amp;gt;
        &amp;lt;slot name=&amp;quot;header&amp;quot;&amp;gt;&amp;lt;/slot&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;modal-body&amp;quot;&amp;gt;
        &amp;lt;slot name=&amp;quot;body&amp;quot;&amp;gt;&amp;lt;/slot&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;modal-footer&amp;quot;&amp;gt;
        &amp;lt;slot name=&amp;quot;footer&amp;quot;&amp;gt;
          &amp;lt;button @click=&amp;quot;$emit(&amp;#39;close&amp;#39;)&amp;quot;&amp;gt;Close&amp;lt;/button&amp;gt;
        &amp;lt;/slot&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note the usage of the &lt;code&gt;name&lt;/code&gt; attribute for each slot and how each &lt;code&gt;slot&lt;/code&gt; is wrapped in another &lt;code&gt;div&lt;/code&gt; element. The component has complete control of the styling by using specific CSS classes &lt;code&gt;modal-header&lt;/code&gt;, &lt;code&gt;modal-body&lt;/code&gt; and &lt;code&gt;modal-footer&lt;/code&gt;. And the user of the component can focus on the content only.&lt;/p&gt;

&lt;p&gt;The usage of these named slots is quite similar to the default slot:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;modal v-if=&amp;quot;showModal&amp;quot; @close=&amp;quot;showModal = false&amp;quot;&amp;gt;
  &amp;lt;h2 slot=&amp;quot;header&amp;quot;&amp;gt;Modal Header&amp;lt;/h2&amp;gt;
  &amp;lt;div slot=&amp;quot;body&amp;quot;&amp;gt;Modal Body&amp;lt;/div&amp;gt;
&amp;lt;/modal&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We can use whatever HTML element we want for our content and use the &lt;code&gt;slot&lt;/code&gt; attribute to select the appropriate slot we want to use. This not only includes HTML elements but also other Vue.js components.&lt;/p&gt;

&lt;p&gt;Note, that the &lt;code&gt;footer&lt;/code&gt; slot is not used in this example. By default the existing slot content will be used. In our case the &lt;code&gt;footer&lt;/code&gt; slot is defined like this:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;slot name=&amp;quot;footer&amp;quot;&amp;gt;
  &amp;lt;button @click=&amp;quot;$emit(&amp;#39;close&amp;#39;)&amp;quot;&amp;gt;Close&amp;lt;/button&amp;gt;
&amp;lt;/slot&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So, we still have our Close button as is.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;In this chapter we looked into slots and named slots to compose our components and content in a very flexible way. Stay tuned for my upcoming post on scoped slots!&lt;/p&gt;

&lt;p&gt;If you like this post also check out my new course &lt;a href=&quot;/vue-component-patterns-course.html&quot;&gt;Vue.js Component Patterns Course&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Introduction to Components with Vue.js</title>
   <link href="http://fdietz.github.com/2018/08/23/introduction-to-vue-js-components.html"/>
   <updated>2018-08-23T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2018/08/23/introduction-to-vue-js-components</id>
   <content type="html">&lt;p&gt;In this article I’d like to introduce you to the Vue.js component model and show the benefits of component reuse and
encapsulation.&lt;/p&gt;

&lt;p&gt;If you don’t know your way around Vue.js yet, I can highly recommmend the official &lt;a href=&quot;https://vuejs.org/v2/guide/index.html&quot;&gt;Vue.js guide&lt;/a&gt;.
But, please don’t be afraid of diving right into this article with me. I will point you to the relevant official documentation to give you some more background and a chance to read up on some more background material.&lt;/p&gt;

&lt;p&gt;We will start with a simple example component and gradually improve its functionality.&lt;/p&gt;

&lt;figure&gt;
  &lt;img width=&quot;50%&quot; alt=&quot;Who doesn't like cats?&quot; src=&quot;/assets/image_card-8ceb3f696d32c587d735c59301ccdddad8ee5f5a9d11b8275a181397ae86494b.png&quot; /&gt;
  &lt;figcaption&gt;Example 1 - Who doesn't like cats?&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The HTML for this card component consists of a large image area and body with some text:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div id=&amp;quot;demo&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;image-card&amp;quot;&amp;gt;
    &amp;lt;img class=&amp;quot;image-card__image&amp;quot; src=&amp;quot;cat.jpg&amp;quot; /&amp;gt;
    &amp;lt;div class=&amp;quot;image-card__body&amp;quot;&amp;gt;
      &amp;lt;h3 class=&amp;quot;image-card__title&amp;quot;&amp;gt;Striped Tiger Cat&amp;lt;/h3&amp;gt;
      &amp;lt;div class=&amp;quot;image-card__author&amp;quot;&amp;gt;Image by @lemepe&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We use the root HTML element with the &lt;code&gt;demo&lt;/code&gt; id as our element to initiate Vue:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;new Vue({ el: &amp;#39;#demo&amp;#39; })&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;What did we achieve? We used Vue.js to render this image card. But we can’t really reuse this code as is and we don’t want to copy and paste and thereby duplicating code.&lt;/p&gt;

&lt;p&gt;The solution to our problem is to turn this into a component.&lt;/p&gt;

&lt;h2 id=&quot;components-can-be-reused&quot;&gt;Components can be reused&lt;/h2&gt;

&lt;p&gt;So, let’s separate the image card from the remaining Vue.js application.&lt;/p&gt;

&lt;p&gt;First we introduce a template element with all the image card content:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;template id=&amp;quot;template-image-card&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;image-card&amp;quot;&amp;gt;
    &amp;lt;img class=&amp;quot;image-card__image&amp;quot; src=&amp;quot;cat.jpg&amp;quot; /&amp;gt;
    &amp;lt;div class=&amp;quot;image-card__body&amp;quot;&amp;gt;
      &amp;lt;h3&amp;gt;Striped Tiger Cat&amp;lt;/h3&amp;gt;
      &amp;lt;div class=&amp;quot;image-card__author&amp;quot;&amp;gt;Image by @lemepe&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And we define the component with &lt;code&gt;Vue.component&lt;/code&gt; and reference our template id &lt;code&gt;template-image-card&lt;/code&gt;:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;Vue.component(&amp;#39;image-card&amp;#39;, {
  template: &amp;quot;#template-image-card&amp;quot;
})&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is again wrapped in an HTML root element:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div id=&amp;quot;demo&amp;quot;&amp;gt;
  &amp;lt;image-card&amp;gt;&amp;lt;/image-card&amp;gt;
  &amp;lt;image-card&amp;gt;&amp;lt;/image-card&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And then instantiated:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;new Vue({ el: &amp;#39;#demo&amp;#39; })&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And voila! We have two cats :-)&lt;/p&gt;

&lt;figure&gt;
  &lt;img width=&quot;75%&quot; alt=&quot;Example 2 - two cats!&quot; src=&quot;/assets/image_card_two_cats-b760f8d695c2b2b825c7d273bd767e7215b1003658d34fa850df7e87df84a8c3.png&quot; /&gt;
  &lt;figcaption&gt;Example 2 - two cats!&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Now, two cats are obviously better than one cat and we showed that we can have several instances of our &lt;code&gt;image-card&lt;/code&gt; component on the same page.&lt;/p&gt;

&lt;p&gt;We now have the means to reuse this component in our app. And if you think about it, it’s actually quite remarkable that this includes our HTML, CSS and Javascript code all wrapped up in a component.&lt;/p&gt;

&lt;p&gt;But still, this component is not very useful, isn’t it? It is just not flexible enough! It would be awesome if we could change
the image and text body for each component.&lt;/p&gt;

&lt;h2 id=&quot;passing-data-to-child-components-as-props&quot;&gt;Passing data to child components as props&lt;/h2&gt;

&lt;p&gt;In order to customize the component’s behaviour, we will use props.&lt;/p&gt;

&lt;p&gt;Let’s start with how we want to use our component:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div id=&amp;quot;demo&amp;quot;&amp;gt;
  &amp;lt;image-card image-src=&amp;quot;cat1.jpg&amp;quot; heading=&amp;quot;Striped Tiger Cat&amp;quot; text=&amp;quot;Image by @lemepe&amp;quot;&amp;gt;&amp;lt;/image-card&amp;gt;
  &amp;lt;image-card image-src=&amp;quot;cat2.jpg&amp;quot; heading=&amp;quot;Alternative Text&amp;quot; text=&amp;quot;alternative subtitle&amp;quot;&amp;gt;&amp;lt;/image-card&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We introduce three new props &lt;code&gt;image-src&lt;/code&gt;, &lt;code&gt;heading&lt;/code&gt;, and &lt;code&gt;text&lt;/code&gt;. When using the component these will be passed along as HTML attributes.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;prop&lt;/code&gt; definition of our component comes next:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;Vue.component(&amp;#39;image-card&amp;#39;, {
  template: &amp;quot;#template-image-card&amp;quot;,
  props: {
    heading: String,
    text: String,
    imageSrc: String
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note, how the prop &lt;code&gt;imageSrc&lt;/code&gt; is written in camelCase whereas the HTML attributes is using a dash &lt;code&gt;image-src&lt;/code&gt;. You can read more about &lt;code&gt;props&lt;/code&gt; in the official &lt;a href=&quot;https://vuejs.org/v2/guide/components-props.html&quot;&gt;Vue.js Guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And the accompanying template uses this props in the camelCase format again:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;template id=&amp;quot;template-image-card&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;image-card&amp;quot;&amp;gt;
    &amp;lt;img class=&amp;quot;image-card__image&amp;quot; :src=&amp;quot;imageSrc&amp;quot; /&amp;gt;
    &amp;lt;div class=&amp;quot;image-card__body&amp;quot;&amp;gt;
      &amp;lt;h3&amp;gt;{{heading}}&amp;lt;/h3&amp;gt;
      &amp;lt;div class=&amp;quot;image-card__author&amp;quot;&amp;gt;{{text}}&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Let’s have a look at the result:&lt;/p&gt;

&lt;figure&gt;
  &lt;img width=&quot;75%&quot; alt=&quot;Example 3 - image cards with props&quot; src=&quot;/assets/image_card_with_props-4a9fd4570d37679b5cd5b82ffcc4d8e37f66ae62105d817e823d54235a735896.png&quot; /&gt;
  &lt;figcaption&gt;Example 3 - image cards with props&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;It worked! We have used two instances of our &lt;code&gt;image-card&lt;/code&gt; component with different props.&lt;/p&gt;

&lt;p&gt;Isn’t it nice that we can render a component differently using props as inputs?&lt;/p&gt;

&lt;h3 id=&quot;components-have-state&quot;&gt;Components have state&lt;/h3&gt;

&lt;p&gt;In my typical day job a product manager would most probably note that the &lt;code&gt;image-card&lt;/code&gt; by itself looks quite nice with the cats and such. But, it is not really engaging yet. How about we let users like our cat and we could then keep a count of which cat had the most likes?&lt;/p&gt;

&lt;p&gt;Components can have state using the &lt;code&gt;data&lt;/code&gt; attribute:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;Vue.component(&amp;#39;image-card&amp;#39;, {
    template: &amp;quot;#template-image-card&amp;quot;,
    props: {
      heading: String,
      text: String,
      imageSrc: String
    },
    data: function () {
      return {
        count: 0
      }
    }
  });&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note, that &lt;code&gt;data&lt;/code&gt; is returning a function instead of only a Javascript object &lt;code&gt;data: { count: 0 }&lt;/code&gt;.
This is required, so that each component instance can maintain an independent copy of the returned data.
Read more about this in the &lt;a href=&quot;https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function&quot;&gt;Vue.js Guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Our template uses this count:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;template id=&amp;quot;template-image-card&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;image-card&amp;quot;&amp;gt;
      &amp;lt;img class=&amp;quot;image-card__image&amp;quot; :src=&amp;quot;imageSrc&amp;quot; /&amp;gt;
    &amp;lt;div class=&amp;quot;image-card__body&amp;quot;&amp;gt;
        &amp;lt;h3 class=&amp;quot;image-card__heading&amp;quot;&amp;gt;{{heading}}&amp;lt;/h3&amp;gt;
      &amp;lt;div class=&amp;quot;image-card__author&amp;quot;&amp;gt;{{text}}&amp;lt;/div&amp;gt;
      &amp;lt;button class=&amp;quot;image-card__heart&amp;quot; @click=&amp;quot;count++&amp;quot;&amp;gt;
        &amp;lt;svg viewBox=&amp;quot;0 0 32 29.6&amp;quot;&amp;gt;
          &amp;lt;path d=&amp;quot;M16,28.261c0,0-14-7.926-14-17.046c0-9.356,13.159-10.399,14-0.454c1.011-9.938,14-8.903,14,0.454 C30,20.335,16,28.261,16,28.261z&amp;quot;/&amp;gt;            
        &amp;lt;/svg&amp;gt;
      &amp;lt;/button&amp;gt;
      &amp;lt;div class=&amp;quot;image-card__count&amp;quot; v-if=&amp;quot;count &amp;gt; 0&amp;quot;&amp;gt;{{count}}&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;figure&gt;
  &lt;img width=&quot;75%&quot; alt=&quot;Example 4 - image card with state&quot; src=&quot;/assets/image_card_with_state-9470feccb041125ba402b03ebb74dc6dafd64ba1085d902e9e0cc9ddf39b3fb7.png&quot; /&gt;
  &lt;figcaption&gt;Example 4 - image card with state&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;We use an SVG element to render a little heart and on the &lt;code&gt;click&lt;/code&gt; event we increment the count by 1. A little count is displayed next to the heart with the current &lt;code&gt;count&lt;/code&gt; value.&lt;/p&gt;

&lt;p&gt;If you are more interested in working with SVG, have a look in the &lt;a href=&quot;https://vuejs.org/v2/cookbook/editable-svg-icons.html&quot;&gt;Vue.js Cookbook&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;Note, that each component instance has its own local state of &lt;code&gt;count&lt;/code&gt; which can be changed independently from the other component’s &lt;code&gt;count&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Whereas in the previous example we only encapsulated the HTML code and made it more flexible with props. We now also encapsulate some business logic to keep count.&lt;/p&gt;

&lt;p&gt;Whereas &lt;code&gt;props&lt;/code&gt; are the input parameters of our component, the state is something internal to the component and is hidden from a user of our component’s code. We could change the name of our variable from &lt;code&gt;count&lt;/code&gt; to &lt;code&gt;clickCount&lt;/code&gt; and a user of our component wouldn’t even need to know. This is awesome because we can keep improving our component without breakings our user’s code.&lt;/p&gt;

&lt;h2 id=&quot;sending-messages-to-parents-with-events&quot;&gt;Sending messages to parents with events&lt;/h2&gt;

&lt;p&gt;Now that we know how to pass data down to children and how to encapsulate state. There one thing missing: How can we get data back from a child?&lt;/p&gt;

&lt;p&gt;In Vue.js we can emit a custom event from the component to it’s parent which listens to that specific event. This event can additionally pass along data.&lt;/p&gt;

&lt;p&gt;In our example we can use &lt;code&gt;$emit&lt;/code&gt; to send an event called &lt;code&gt;change&lt;/code&gt; with data to the parent:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;Vue.component(&amp;#39;image-card&amp;#39;, {
  template: &amp;quot;#template-image-card&amp;quot;,
  props: {
    heading: String,
    text: String,
    imageSrc: String
  },
  data: function () {
    return {
      count: 0
    }
  },
  methods: {
    handleClick() {
      this.count++;
      // leanpub-start-insert
      this.$emit(&amp;quot;change&amp;quot;, this.count);
      // leanpub-end-insert
    }
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We defined the method &lt;code&gt;handleClick&lt;/code&gt; which not only increments our &lt;code&gt;count&lt;/code&gt; state, but additionally uses &lt;code&gt;$emit&lt;/code&gt; to send a message to our parent. The &lt;code&gt;handleClick&lt;/code&gt; is called in the on &lt;code&gt;click&lt;/code&gt; event of our heart:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;template id=&amp;quot;template-image-card&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;image-card&amp;quot;&amp;gt;
    &amp;lt;img class=&amp;quot;image-card__image&amp;quot; :src=&amp;quot;imageSrc&amp;quot; /&amp;gt;
    &amp;lt;div class=&amp;quot;image-card__body&amp;quot;&amp;gt;
        &amp;lt;h3 class=&amp;quot;image-card__heading&amp;quot;&amp;gt;{{heading}}&amp;lt;/h3&amp;gt;
      &amp;lt;div class=&amp;quot;image-card__author&amp;quot;&amp;gt;{{text}}&amp;lt;/div&amp;gt;
      &amp;lt;button class=&amp;quot;image-card__heart&amp;quot; @click=&amp;quot;handleClick&amp;quot;&amp;gt;
        &amp;lt;svg viewBox=&amp;quot;0 0 32 29.6&amp;quot;&amp;gt;
          &amp;lt;path d=&amp;quot;M16,28.261c0,0-14-7.926-14-17.046c0-9.356,13.159-10.399,14-0.454c1.011-9.938,14-8.903,14,0.454 C30,20.335,16,28.261,16,28.261z&amp;quot;/&amp;gt;            
        &amp;lt;/svg&amp;gt;
      &amp;lt;/button&amp;gt;
      &amp;lt;div class=&amp;quot;image-card__count&amp;quot; v-if=&amp;quot;count &amp;gt; 0&amp;quot;&amp;gt;{{count}}&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now the parent template can use this to listen to the &lt;code&gt;change&lt;/code&gt; event to increment a &lt;code&gt;totalCount&lt;/code&gt;:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div id=&amp;quot;demo&amp;quot;&amp;gt;
  &amp;lt;image-card image-src=&amp;quot;cat.jpg&amp;quot; heading=&amp;quot;Striped Tiger Cat&amp;quot; text=&amp;quot;Image by @lemepe&amp;quot; @change=&amp;quot;handleChange&amp;quot;&amp;gt;&amp;lt;/image-card&amp;gt;
  &amp;lt;image-card image-src=&amp;quot;cat.jpg&amp;quot; heading=&amp;quot;Alternative Text&amp;quot; text=&amp;quot;alternative subtitle&amp;quot; @change=&amp;quot;handleChange&amp;quot;&amp;gt;&amp;lt;/image-card&amp;gt;
  &amp;lt;p&amp;gt;Total Count: {{totalCount}}&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Together with the Vue.js instance to keep track of a &lt;code&gt;totalCount&lt;/code&gt;:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;new Vue({
  el: &amp;#39;#demo&amp;#39;,
  data: {
    totalCount: 0
  },
  methods: {
    handleChange(count) {
      console.log(&amp;quot;count changed&amp;quot;, count);
      this.totalCount++;
    }
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note, that the parent doesn’t know about the component’s internals. It just knows that there’s a change event available and that the message sends the component’s &lt;code&gt;count&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The event emitted via &lt;code&gt;this.$emit(&quot;event&quot;)&lt;/code&gt; is only send to the parent component. It will not bubble up the component hierarchy similar to native DOM events.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;In this article we explored the base concepts of a component model. We discussed component reuse and encapsulation,
how to use props to pass data to children and how to emit events to pass messages to the parent.&lt;/p&gt;

&lt;p&gt;If you like this post also check out my new course &lt;a href=&quot;/vue-component-patterns-course.html&quot;&gt;Vue.js Component Patterns Course&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Published Vue.js Component Patterns Course</title>
   <link href="http://fdietz.github.com/2018/08/16/published-vue-js-component-patterns-course.html"/>
   <updated>2018-08-16T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2018/08/16/published-vue-js-component-patterns-course</id>
   <content type="html">&lt;p&gt;I’ve just published my new course 🎉 &lt;a href=&quot;/vue-component-patterns-course.html&quot;&gt;Vue.js Component Patterns&lt;/a&gt; 🎉&lt;/p&gt;

&lt;p&gt;The course consists of an ebook (PDF, mobi, epub) and an optional set of exercises with solutions to apply what you learn.&lt;/p&gt;

&lt;p&gt;Following the &lt;strong&gt;lean publishing style&lt;/strong&gt; the course is still a work in progress, but can be purchased already. Early buyers get a discount and can help improve the course by joining the
spectrum.chat &lt;a href=&quot;https://spectrum.chat/vue-c-p-book&quot;&gt;Community&lt;/a&gt;. I’m looking forward to get in touch with readers and gather as much feedback as possible!&lt;/p&gt;

&lt;p&gt;While we are at it: I’m currently &lt;strong&gt;searching for early reviewers&lt;/strong&gt; to get some more thorough feedback on the current content. Ping me if you are interested! You get the whole thing for free, of course! Many thanks in advance for spreading the message!&lt;/p&gt;

&lt;p&gt;Currently, the book consists of &lt;strong&gt;12 chapters&lt;/strong&gt; with around &lt;strong&gt;30 examples&lt;/strong&gt; which gradually build on each other in each chapter. Additionally, I’ve created &lt;strong&gt;12 exercises with solutions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I have currently 3 more chapters in the pipeline and want to work much more on the exercise/solutions part. Additionally, work has been started on a well behaving component checklist for buyers of the complete package.&lt;/p&gt;

&lt;h2 id=&quot;faq&quot;&gt;FAQ&lt;/h2&gt;

&lt;h3 id=&quot;why-are-there-no-videos&quot;&gt;Why are there no videos?&lt;/h3&gt;

&lt;p&gt;That’s probably the first question which comes up, since nowadays most stuff is offered in some kind of video format. 
Honestly, this is just a matter of personal taste. Learning by watching videos was never my thing. I learn much faster when I can read my content and the exercises with solutions help applying what I learn.&lt;/p&gt;

&lt;h3 id=&quot;why-focus-on-components&quot;&gt;Why focus on components?&lt;/h3&gt;

&lt;p&gt;Having build frontends in multiple frameworks, I’m fascinated by how all these frameworks converge on the very same idea of a reusable component.
And it really is a repeating pattern. You have a component which encapsulates state, logic and even styling. With props in and events out, you can use these components to compose complex UIs.
I am fascinated how this enables to transfer my knowledge from Angular, to React and Vue.js!&lt;/p&gt;

&lt;p&gt;If you are a software developer who just moved from jQuery to Vue.js, this should be your next step in my humble opinion!&lt;/p&gt;

&lt;h3 id=&quot;get-a-discount&quot;&gt;Get a discount&lt;/h3&gt;

&lt;p&gt;If you are a student or otherwise the book is too expensive for you, ping me for a discount!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Day 5 - How to build your own team chat in five days - Angular Filters and Directives</title>
   <link href="http://fdietz.github.com/2015/04/17/day-5-how-to-build-your-own-team-chat-in-five-days-angular-filters-and-directives.html"/>
   <updated>2015-04-17T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2015/04/17/day-5-how-to-build-your-own-team-chat-in-five-days-angular-filters-and-directives</id>
   <content type="html">&lt;p&gt;This is part 5 of an ongoing series of blog posts. Read &lt;a href=&quot;/2015/04/13/day-1-how-to-build-your-own-team-chat-in-five-days.html&quot;&gt;part 1&lt;/a&gt; first and then come back, please!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Welcome back to day 5 of “How to build your own team chat in five days”! Since yesterday has been quite an extensive Socket.IO day where we switched back and forth between client and server, I figured it would be nice for the final day to work on the client only. I’d like to therefore focus today on adding some final touches to “chitchat”.&lt;/p&gt;

&lt;h2 id=&quot;relative-date-time-angular-filter-using-momentjs&quot;&gt;Relative date time Angular filter using moment.js&lt;/h2&gt;

&lt;p&gt;Let’s start with a simple Angular filter to render the message creation timestamp as a user-friendly relative time instead, for example “7 minutes ago”.&lt;/p&gt;

&lt;div class=&quot;centered-image&quot;&gt;
  &lt;img src=&quot;/images/relative_time.png&quot; /&gt;
  &lt;p&gt;From timestamp to user-friendly relative time&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;The Angular filter &lt;code&gt;relativeDate&lt;/code&gt; is used via a &lt;code&gt;|&lt;/code&gt; (pipe) character:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;span class=&amp;quot;date&amp;quot;&amp;gt;{{messageContent.created_at | relativeDate }}&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And here’s the code leveraging &lt;a href=&quot;http://momentjs.com/&quot;&gt;moment.js&lt;/a&gt; for the actual conversion:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import moment from &amp;quot;moment&amp;quot;;

export default function relativeDateFilter() {
  return function(dateString) {
    return moment(dateString).fromNow();
  };
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now how did I get moment.js installed? I’ve used the &lt;code&gt;jspm install moment&lt;/code&gt; command and then it was only a matter of importing the library inside the filter.&lt;/p&gt;

&lt;p&gt;Don’t forget that the &lt;code&gt;relativeDate&lt;/code&gt; filter needs to be registered using the &lt;code&gt;message-list&lt;/code&gt; module:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;export default angular.module(&amp;#39;MessageList&amp;#39;, [])
  .filter(&amp;#39;relativeDate&amp;#39;, relativeDateFilter);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;rendering-an-avatar-with-an-angular-directive&quot;&gt;Rendering an avatar with an Angular directive&lt;/h2&gt;

&lt;p&gt;Instead of my own avatar image I wanted to use something which always works just based on the name of the user without the user uploading an image. The easiest solution I came up with is using the initials.&lt;/p&gt;

&lt;div class=&quot;centered-image&quot;&gt;
  &lt;img src=&quot;/images/avatar_directive.png&quot; /&gt;
  &lt;p&gt;Rendering the avatar with its initials&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;This time I’m using an component directive again, which can be used in the &lt;code&gt;message_list.html&lt;/code&gt; template like that:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;avatar user=&amp;quot;messageContent.user&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The directive’s template itself looks pretty straight-forward:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div class=&amp;quot;avatar&amp;quot; style=&amp;quot;background-color: {{color}}&amp;quot;&amp;gt;
  &amp;lt;span class=&amp;quot;initials&amp;quot;&amp;gt;{{initials}}&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We need our directive to provide the initials and a background color to work with.&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import template from &amp;quot;./avatar.html!text&amp;quot;;

function avatarDirective() {
  let colorMapping = {};

  return {
    restrict: &amp;quot;E&amp;quot;,
    replace: true,
    scope: {
      user: &amp;quot;=&amp;quot;
    },
    template: template,
    link: function($scope) {

      // http://stackoverflow.com/questions/1484506/random-color-generator-in-javascript
      function randomColor() {
        var letters = &amp;#39;0123456789ABCDEF&amp;#39;.split(&amp;#39;&amp;#39;);
        var color = &amp;#39;#&amp;#39;;
        for (var i = 0; i &amp;lt; 6; i++ ) {
            color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
      }

      var unwatch = $scope.$watch(&amp;quot;user&amp;quot;, function(user) {
        if (user) {
          $scope.initials = (user.name[0] || &amp;quot;A&amp;quot;);

          if (!colorMapping[user.id]) colorMapping[user.id] = randomColor();
          $scope.color    = colorMapping[user.id];

          unwatch();
        }
      });
    }
  };
}

avatarDirective.$inject = [];

export default avatarDirective;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The directive’s scope configuration is very similar to our other component directives. Let’s focus on the &lt;code&gt;user&lt;/code&gt; which is passed as attribute to the directive.&lt;/p&gt;

&lt;p&gt;I’ve setup a watcher using &lt;code&gt;$scope.$watch&lt;/code&gt; to make sure that the user is set and resolved correctly. Then I use the first character of the name and a pretty random color generator for the color. Note, that I memorize the color for the specific user id in &lt;code&gt;colorMapping&lt;/code&gt;, since we want it to stay the same at all times.&lt;/p&gt;

&lt;p&gt;Dont’ forgot to register the directive to make it usable for Angular compiled templates! Let’s have another look at the message list next.&lt;/p&gt;

&lt;h2 id=&quot;formatting-and-auto-linking-the-message&quot;&gt;Formatting and auto linking the message&lt;/h2&gt;

&lt;p&gt;If you played around and wrote a couple of messages you notice that it doesn’t handle line breaks correctly. Additionally, it would be awesome if the message would automatically create links out of URLs in the message body.&lt;/p&gt;

&lt;div class=&quot;centered-image&quot;&gt;
  &lt;img src=&quot;/images/formatted_message_directive.png&quot; /&gt;
  &lt;p&gt;Autolinking and line breaks&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;This is again a job for an Angular directive. Let’s have a look how it would be used in the &lt;code&gt;message_list.html&lt;/code&gt; template:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div class=&amp;quot;message&amp;quot; formatted-message=&amp;quot;messageContent.message&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The idea is that you pass in a string and it will set the text of the HTML element for you nicely formatted. Let’s have a look at the directives code:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import FormatMessageService from &amp;quot;./format_message.service&amp;quot;;

function formattedMessage() {
  return {
    restrict: &amp;quot;A&amp;quot;,
    scope: {
      &amp;quot;formattedMessage&amp;quot; : &amp;quot;=&amp;quot;
    },
    link: function($scope, element, attrs) {
      var unwatch = $scope.$watch(&amp;quot;formattedMessage&amp;quot;, function(str) {
        if (str) {
          str = FormatMessageService.breakNewLine(str);
          str = FormatMessageService.autoLink(str);
          element.html(str);

          unwatch();
        }
      });
    }
  };
}

formattedMessage.$inject = [];

export default formattedMessage;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The directive is a behaviour directive and not a component directive. That’s way it’s usage is restricted to HTML attributes. We pass in the message string in the context and use an Angular watcher again to check if the message is resolved correctly before starting to change it.&lt;/p&gt;

&lt;p&gt;Then we use a new service &lt;code&gt;FormatMessageService&lt;/code&gt; to do the actual hard work. Before we go into further details, note that I’m calling the &lt;code&gt;unwatch()&lt;/code&gt; function - the return value of the &lt;code&gt;$watch&lt;/code&gt; call - to stop watching. Otherwise, it would reformat the message on each digest. Since we don’t intend to change the message, we can skip this here.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;FormatMessageService&lt;/code&gt; look the following:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import Autolinker from &amp;quot;autolinker&amp;quot;;

export default class FormatMessageService {

  static breakNewLine(str) {
    return str.replace(/(\r|\n)/g, &amp;#39;&amp;lt;br&amp;gt;&amp;#39;);
  }

  static autoLink(str) {
    return Autolinker.link(str, {
      newWindow: true,
      className: &amp;quot;auto-link&amp;quot;,
      twitter: false,
      hashtag: false
    });
  }

}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;It uses a simple string &lt;code&gt;replace&lt;/code&gt; to replace &lt;code&gt;\r&lt;/code&gt; and &lt;code&gt;\n&lt;/code&gt; with a &lt;code&gt;&amp;lt;br&amp;gt;&lt;/code&gt; element. The auto linking is a bit more complicated and since I didn’t want to make you suffer with a horrible piece of regular expression, I’ve used the library &lt;a href=&quot;https://github.com/gregjacobs/Autolinker.js&quot;&gt;Autolinker.js&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I didn't want to make you suffer with a horrible piece of regular expression.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Again the library was just an easy &lt;code&gt;jspm install npm:autolink&lt;/code&gt; away and then I was able to import it in my service.&lt;/p&gt;

&lt;p&gt;One last directive I’d like to discuss with you is trying to solve the scrolling behaviour.&lt;/p&gt;

&lt;h2 id=&quot;making-sure-the-message-scrolls-to-the-bottom&quot;&gt;Making sure the message scrolls to the bottom&lt;/h2&gt;
&lt;p&gt;You might have noticed that the message list scroll position stays the same even when you create or receive new messages. That’s quite annoying and users expect for their newly written messages to be visible right away.&lt;/p&gt;

&lt;p&gt;Let’s look into how this can be achived with a directive. How about we simple extend the existing message list directive:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function messageListDirective() {
  return {
    // omitted directive configuration
    link: function($scope, element) {

      function scrollToBottom() {
        element.scrollTop(element.prop(&amp;quot;scrollHeight&amp;quot;));
      }

      var observer = new window.MutationObserver(scrollToBottom);
      observer.observe(element[0], { childList: true });

      $scope.$on(&amp;quot;$destroy&amp;quot;, () =&amp;gt; {
        observer.disconnect();
      });
    }
  };
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We want to achieve a scroll effect to the bottom of the message list whenever a new message is added to the list. Fortunately, there’s a &lt;a href=&quot;https://developer.mozilla.org/en/docs/Web/API/MutationObserver&quot;&gt;MutationObserver&lt;/a&gt; available in most browsers which let you register a callback in case the children of our list are added or removed.&lt;/p&gt;

&lt;p&gt;The observer is initialized with the &lt;code&gt;scrollToBottom&lt;/code&gt; function which sets the scroll position to the height of the scrollable view area.&lt;/p&gt;

&lt;p&gt;Note, that I unregister the observer using the &lt;code&gt;disconnect&lt;/code&gt; function when the scope is destroyed. We dont’ want to have any memory leaks in our app!&lt;/p&gt;

&lt;p&gt;Now there’s one problem with the code. We don’t want to always scroll to the bottom of the message list. What if the user scrolled all the way up to some older messages. A new incoming message would scroll him/her down to the bottom of the list again - that would be certainly annoying!&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var alreadyAtBottom = true;

function scrollToBottom() {
  if (alreadyAtBottom) {
    element.scrollTop(element.prop(&amp;quot;scrollHeight&amp;quot;));
  }
}

function isAtBottom() {
  var scrollTop = element.scrollTop();
  var maxHeight = element.prop(&amp;quot;scrollHeight&amp;quot;) - element.prop(&amp;quot;clientHeight&amp;quot;);

  return scrollTop &amp;gt;= maxHeight;
}

// https://developer.mozilla.org/en/docs/Web/API/MutationObserver
var observer = new window.MutationObserver(scrollToBottom);

observer.observe(element[0], { childList: true });

var throttledOnScrollHandler = _.throttle(function() {
  alreadyAtBottom = isAtBottom();
}, 250);

element.on(&amp;quot;scroll&amp;quot;, throttledOnScrollHandler);

$scope.$on(&amp;quot;$destroy&amp;quot;, () =&amp;gt; {
  element.off(&amp;quot;scroll&amp;quot;, throttledOnScrollHandler);
  observer.disconnect();
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The idea how to solve this is pretty simple. I registered an event handler in case the user is scrolling and set the &lt;code&gt;alreadyAtBottom&lt;/code&gt; to true if the user is actually at the bottom of the list already. Only then should the MutationObserver behaviour kick in.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;isAtBottom&lt;/code&gt; function checks the current scroll position, with the maximum height of the scollable area to check if the user is at the bottom. We can then use this information in the &lt;code&gt;scrollToBottom&lt;/code&gt; function to decide if we want to scroll to the bottom.&lt;/p&gt;

&lt;p&gt;Again note, that I unbind the &lt;code&gt;scroll&lt;/code&gt; event again in order to not create any memory leaks. Additionally, I’ve used &lt;a href=&quot;http://underscorejs.org/&quot;&gt;underscore.js&lt;/a&gt; &lt;code&gt;throttle&lt;/code&gt; method for the scroll handler since we don’t want to waste precious CPU cycle when the user starts scrolling quickly.&lt;/p&gt;

&lt;p&gt;Since all the code for the scroll to bottom behaviour is not dependend on any properties of the message list directive, it would probably be a good idea to refactor it out into it’s own directive. That way we can reuse it easily elsewhere.&lt;/p&gt;

&lt;h2 id=&quot;final-words&quot;&gt;Final words&lt;/h2&gt;

&lt;p&gt;Look at what we accomplished in only five days!&lt;/p&gt;

&lt;div class=&quot;centered-image&quot;&gt;
  &lt;img src=&quot;/images/chit_chat_final.png&quot; /&gt;
  &lt;p&gt;Final version&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;That’s already it for the final day. I really hope you enjoyed this series. I certainly had a lot of fun :-) Now it’s your turn to get your hands dirty and start experimenting with your own team chat!&lt;/p&gt;

&lt;div class=&quot;centered-image&quot;&gt;
  &lt;img src=&quot;/images/happy_friday.gif&quot; /&gt;
  &lt;p&gt;About time you get your hands dirty and start experimenting with your own team chat!&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;If you want to learn more about structuring your Angular apps, let me know in the comments! Who knows - I might even consider turning this blog series into a little ebook! There are still so many things left to discuss!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;The complete sourcecode can be found in the &lt;a href=&quot;https://github.com/fdietz/how_to_build_your_own_team_chat_in_five_days/tree/master/day_5/nodejs_express_socketio_chat&quot;&gt;github repository&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/13/day-1-how-to-build-your-own-team-chat-in-five-days.html&quot;&gt;Day 1 - How to build your own team chat in five days&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/14/day-2-how-to-build-your-own-team-chat-in-five-days-es6-modules-angularjs-systemjs-and-jspm.html&quot;&gt;Day 2 - ES6 Modules, AngularJS, SystemJS and JSPM&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/15/day-3-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs.html&quot;&gt;Day 3 - ExpressJS, Socket.io and AngularJS&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/16/day-4-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs-component-based-design-patterns.html&quot;&gt;Day 4 - ExpressJS, Socket.io and AngularJS component-based design patterns&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/17/day-5-how-to-build-your-own-team-chat-in-five-days-angular-filters-and-directives.html&quot;&gt;Day 5 - AngularJS Filters and Directives&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Day 4 - How to build your own team chat in five days - ExpressJS, Socket.io and AngularJS component-based design patterns</title>
   <link href="http://fdietz.github.com/2015/04/16/day-4-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs-component-based-design-patterns.html"/>
   <updated>2015-04-16T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2015/04/16/day-4-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs-component-based-design-patterns</id>
   <content type="html">&lt;p&gt;This is part 4 of an ongoing series of blog posts. Read &lt;a href=&quot;/2015/04/13/day-1-how-to-build-your-own-team-chat-in-five-days.html&quot;&gt;part 1&lt;/a&gt; first and then come back, please!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Welcome back to day 4 of “How to build your own team chat in five days”! I haven’t had the time to introduce you properly to the first “real” iteration of “chitchat”, yesterday.&lt;/p&gt;

&lt;p&gt;First of all, the complete sourcecode can be found in the &lt;a href=&quot;https://github.com/fdietz/how_to_build_your_own_team_chat_in_five_days/tree/master/day_4/nodejs_express_socketio_chat&quot;&gt;github repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And here’s again the directory structure:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;├── public
│   ├── app
│   ├── images
│   ├── jspm_packages
│   ├── config.js
│   ├── styles
│   └── index.html
└── styles
    ├── base
    ├── layout
    ├── modules
    └── application.scss
├── node_modules
├── package.json
├── gulpfile.js
├── app.js
└── README.md&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Let’s dive into the sourcecode starting with the ExpressJS part.&lt;/p&gt;

&lt;h2 id=&quot;expressjs-server-side&quot;&gt;ExpressJS server side&lt;/h2&gt;

&lt;p&gt;If you already have experience in ExpressJS the following configuration and setup code in &lt;code&gt;app.js&lt;/code&gt; should not surprise you:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var express        = require(&amp;#39;express&amp;#39;);
var bodyParser     = require(&amp;#39;body-parser&amp;#39;);
var logger         = require(&amp;#39;morgan&amp;#39;);
var methodOverride = require(&amp;#39;method-override&amp;#39;);
var multer         = require(&amp;#39;multer&amp;#39;);
var path           = require(&amp;#39;path&amp;#39;);

var app            = express();
var http           = require(&amp;#39;http&amp;#39;).createServer(app);

app.set(&amp;#39;port&amp;#39;, process.env.PORT || 3000);

app.use(logger(&amp;#39;dev&amp;#39;));
app.use(methodOverride());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(multer());
app.use(express.static(path.join(__dirname, &amp;#39;public&amp;#39;)));

// development only
if (&amp;#39;development&amp;#39; == app.get(&amp;#39;env&amp;#39;)) {
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
}

// some code omitted here

http.listen(app.get(&amp;#39;port&amp;#39;), function() {
  console.log(&amp;#39;Express server listening on port &amp;#39; + app.get(&amp;#39;port&amp;#39;));
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is a default setup for an ExpressJS server which serves static files from &lt;code&gt;public/&lt;/code&gt;. Additionally, I’ve required the modules &lt;code&gt;body-parser&lt;/code&gt; and &lt;code&gt;method-override&lt;/code&gt; in order to handle JSON requests. So, this is a good basis to implement some routes for a JSON REST API or similar.&lt;/p&gt;

&lt;p&gt;But, since we are going to look into the real-time part of messaging today, let’s see how to integrate Socket.io here first.&lt;/p&gt;

&lt;h2 id=&quot;a-simple-chat-using-socketio&quot;&gt;A simple chat using Socket.io&lt;/h2&gt;

&lt;p&gt;In order to make Socket.io work with ExpressJS we first have to initialize it:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// first the setup of ExpressJS itself
var app            = express();
var http           = require(&amp;#39;http&amp;#39;).createServer(app);

// now socket.io
var io = require(&amp;#39;socket.io&amp;#39;).listen(http);

// and then we can start the server
http.listen(app.get(&amp;#39;port&amp;#39;), function() {
  console.log(&amp;#39;Express server listening on port &amp;#39; + app.get(&amp;#39;port&amp;#39;));
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If you now start your server with &lt;code&gt;node app.js&lt;/code&gt;, or &lt;code&gt;npm start&lt;/code&gt; since that’s configured in &lt;code&gt;package.json&lt;/code&gt;, you are now ready to initiate a websocket connection.&lt;/p&gt;

&lt;p&gt;The Socket.io server goes one step further and also delivers the client library to integrate with. You can actually request it via the following URL &lt;code&gt;localhost:3000/socket.io/socket.io.js&lt;/code&gt; and you can find me do the same in the &lt;code&gt;public/index.html&lt;/code&gt; head via:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;script src=&amp;quot;/socket.io/socket.io.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;After all the setup work is done we can finally initiate a Websocket connection with our client. I’ve put all the Socket.io code into &lt;code&gt;public/app/web_socket.js&lt;/code&gt;, let’s have a look together:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;export default class WebSocket {

  constructor() {
    this.init();
  }

  init() {
    let host = window.location.origin;
    console.log(&amp;quot;WEBSOCKET connecting to&amp;quot;, host);

    this.socket = io.connect(host);

    this.socket.on(&amp;#39;connect&amp;#39;, () =&amp;gt; {
      let sessionId = this.socket.io.engine.id;

      console.log(&amp;quot;WEBSOCKET connected with session id&amp;quot;, sessionId);

      this.socket.emit(&amp;#39;new_user&amp;#39;, { id: sessionId });
    })
  }
}

WebSocket.$inject = [];&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;First we need the url to connect to via Websocket and &lt;code&gt;window.location.origin&lt;/code&gt; returns &lt;code&gt;http://localhost:3000&lt;/code&gt; for us. Perfect!&lt;/p&gt;

&lt;p&gt;Next is the actual connect via &lt;code&gt;io.connect(host)&lt;/code&gt; and then we implement our first callback. Socket.io emits a &lt;code&gt;connect&lt;/code&gt; event when the connection handshake was successful. And we use it and retrieve our &lt;code&gt;sessionID&lt;/code&gt; from it. That is basically as good as it gets for our user in the current prototype.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;WebSocket&lt;/code&gt; class calls &lt;code&gt;init()&lt;/code&gt; in the constructor in order to connect when initializing the class and I’m making sure there’s only a since instance by using it as an Angular service.&lt;/p&gt;

&lt;p&gt;That’s why in &lt;code&gt;main.js&lt;/code&gt; it is integrated in the following way:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import WebSocket from &amp;#39;./web_socket&amp;#39;;

angular.module(&amp;#39;mainApp&amp;#39;, [
    // dependencies omitted
  ]).service(WebSocket.name, WebSocket);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;One last thing here to mention is that I emit a &lt;code&gt;new_user&lt;/code&gt; event with the &lt;code&gt;sessionID&lt;/code&gt; since I want to notify all interested parties that a new participant joined the chat.&lt;/p&gt;

&lt;p&gt;Let’s go back to &lt;code&gt;app.js&lt;/code&gt; on the server side to see how the connection handshake and &lt;code&gt;new_user&lt;/code&gt; event is handled:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// [
//  { session_id: &amp;quot;5W5f-HSzolBOjMj7AAAC&amp;quot;, name: &amp;quot;Peter&amp;quot; },
//  { session_id: &amp;quot;YXlbm_LmHD7oUGwkAAAD&amp;quot;, name: &amp;quot;Martin&amp;quot;}
// ]
var participants = [];
var nameCounter  = 1;

io.on(&amp;quot;connection&amp;quot;, function(socket) {

  socket.on(&amp;quot;new_user&amp;quot;, function(data) {

    var newName = &amp;quot;Guest &amp;quot; + nameCounter++;
    participants.push({ id: data.id, name: newName });

    io.sockets.emit(&amp;quot;new_connection&amp;quot;, {
      user: {
        id: data.id,
        name: newName
      },
      sender:&amp;quot;system&amp;quot;,
      created_at: new Date().toISOString(),
      participants: participants
    });
  });
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;First of all we have the &lt;code&gt;connection&lt;/code&gt; event I’m listening here, which gets triggered whenever a new client is connected to the server. Then the server registered for the &lt;code&gt;new_user&lt;/code&gt; event which we saw on the client-side above. And I basically create a dumb &lt;code&gt;Guest &amp;lt;number&amp;gt;&lt;/code&gt; user name, add it to the array of participants alongside the user id and then emit another event &lt;code&gt;new_connection&lt;/code&gt; which is send to inform all parties that the participants changed.&lt;/p&gt;

&lt;p&gt;Wouldn’t it be cool if we would have some kind of &lt;code&gt;currentUser&lt;/code&gt; on the client? Note that the &lt;code&gt;new_connection&lt;/code&gt; payload also contains the user id and name alongside the participants array. We can use this event on the client side to set our current user including all the information (in our case name only) we gathered on the server.&lt;/p&gt;

&lt;p&gt;So, let’s go back to &lt;code&gt;web_socket.js&lt;/code&gt; on the client:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import Auth from &amp;quot;./auth&amp;quot;;

export default class WebSocket {

  constructor($rootScope) {
    this.$rootScope = $rootScope;
    this.init();
  }

  init() {
    // code omitted

    this.socket.on(&amp;#39;connect&amp;#39;, () =&amp;gt; {
      let sessionId = this.socket.io.engine.id;

      // code ommited

      // this is the new event handler
      this.socket.on(&amp;#39;new_connection&amp;#39;, (data) =&amp;gt; {

        if (data.user.id === sessionId) {
          this.$rootScope.$apply(() =&amp;gt; {
            Auth.setCurrentUser(data.user);
          });
        }
      });
    });
  }
}

WebSocket.$inject = [&amp;#39;$rootScope&amp;#39;];&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I’ve changed a few things but let’s first focus on the &lt;code&gt;new_connection&lt;/code&gt; event handler. It compares the user id which was send from the server with the &lt;code&gt;sessionId&lt;/code&gt; and if they match we set the current user using the &lt;code&gt;Auth&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Auth&lt;/code&gt; class is pretty simple:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;export default class Auth {

  static setCurrentUser(user) {
    this.currentUser = user;
  }

  static getCurrentUser() {
    return this.currentUser;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;It contains a function for setting and getting the current user, but note that the methods are both &lt;code&gt;static&lt;/code&gt; so we can access them using &lt;code&gt;Auth.getCurrentUser()&lt;/code&gt; instead of creating an instance of Auth. I’ve could have used another Angular service in this case but I’d like to look into native ES6 ways of structuring my code first.&lt;/p&gt;

&lt;p&gt;The attentive reader has already spotted one Angular-specific part in our &lt;code&gt;WebSocket&lt;/code&gt; class. I’m wrapping the &lt;code&gt;Auth.setCurrentUser&lt;/code&gt; call in a &lt;code&gt;$rootScope.$apply&lt;/code&gt; to let Angular know that I’ve changed something which it might have access to on the scope. For example when rendering the current user name in our HTML document the change would not get reflected without this &lt;code&gt;$apply&lt;/code&gt; call. BTW, this is a problem which will be gone in AngularJS 2.0 and I’m very much looking forward to it!&lt;/p&gt;

&lt;p&gt;There’s one more function in our &lt;code&gt;WebSocket&lt;/code&gt; class I’d like you to check out:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;export default class WebSocket {

  // details omitted here

  on(key, callback) {
    this.socket.on(key, (data) =&amp;gt; {
      this.$rootScope.$apply(() =&amp;gt; {
        callback(data)
      });
    });
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This &lt;code&gt;on&lt;/code&gt; function let’s other components in my code base register for events emitted by the server. It will come in handy when rendering the list of participants for example. Which brings me to the AngularJS side of the prototype.&lt;/p&gt;

&lt;h2 id=&quot;angularjs-using-a-component-oriented-approach&quot;&gt;AngularJS using a component-oriented approach&lt;/h2&gt;

&lt;p&gt;Let’s starts with the directory structure of the AngularJS app inside the &lt;code&gt;public/&lt;/code&gt; directory:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;├── app
│   ├── message_form
│   ├── message_list
│   ├── participants_list
│   ├── sidebar
│   ├── auth.js
│   ├── bootstrap.js
│   ├── main.js
│   ├── vendor.js
│   └── web_socket.js
├── jspm_packages
├── styles
├── images
├── config.js
├── index.html&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You already know &lt;code&gt;main.js&lt;/code&gt;, &lt;code&gt;bootstrap.js&lt;/code&gt; and most other files from the previous days. And we’ve already talked about &lt;code&gt;auth.js&lt;/code&gt; and &lt;code&gt;web_socket.js&lt;/code&gt;. So, let’s focus now on the way I’ve structured the AngularJS components in &lt;code&gt;index.html&lt;/code&gt;:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;body&amp;gt;
  &amp;lt;sidebar&amp;gt;&amp;lt;/sidebar&amp;gt;

  &amp;lt;div class=&amp;quot;main-content&amp;quot;&amp;gt;

    &amp;lt;div class=&amp;quot;main-header&amp;quot;&amp;gt;
      &amp;lt;div class=&amp;quot;left&amp;quot;&amp;gt;
        &amp;lt;h2&amp;gt;# general&amp;lt;/h2&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;right&amp;quot;&amp;gt;
        &amp;lt;input class=&amp;quot;search&amp;quot; type=&amp;quot;search&amp;quot; placeholder=&amp;quot;Search...&amp;quot;&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;message-list&amp;gt;&amp;lt;/message-list&amp;gt;
    &amp;lt;message-form&amp;gt;&amp;lt;/message-form&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You can see that I’ve introduced new HTML elements for the &lt;code&gt;sidebar&lt;/code&gt;, &lt;code&gt;message-list&lt;/code&gt; and &lt;code&gt;message-form&lt;/code&gt; using Angular directives. And some of these components contain again child components. This can be easily visualized too:&lt;/p&gt;

&lt;div class=&quot;centered-image&quot;&gt;
  &lt;img src=&quot;/images/chitchat_components_2.png&quot; /&gt;
  &lt;p&gt;Components and nested components&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;That way the structure of my code follows very closely the actual visual structure of the dom elements. Here’s the directory structure of these components:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;├── message_form
│   ├── message_form.controller.js
│   ├── message_form.directive.js
│   ├── message_form.html
│   ├── message_form.module.js
│   └── submit_form_on_return.directive.js
├── message_list
│   ├── message_list.controller.js
│   ├── message_list.directive.js
│   ├── message_list.html
│   └── message_list.module.js
├── participants_list
│   ├── participants_list.controller.js
│   ├── participants_list.directive.js
│   ├── participants_list.html
│   └── participants_list.module.js
├── sidebar
│   ├── sidebar.controller.js
│   ├── sidebar.directive.js
│   ├── sidebar.html
│   └── sidebar.module.js
├── auth.js
├── bootstrap.js
├── main.js
├── vendor.js
└── web_socket.js&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The all look pretty much the same. I use a directory for each component and each component contains an Angular module and a directive which itself encapsulates the controller and the template.&lt;/p&gt;

&lt;p&gt;Let’s have a look at some of these components next, starting with the &lt;code&gt;message-form&lt;/code&gt; component.&lt;/p&gt;

&lt;h3 id=&quot;message-form-component&quot;&gt;Message Form Component&lt;/h3&gt;

&lt;p&gt;The message form component is responsible for rendering a textarea where the user can post new messages. Additionally, it also handles the server communication to create the message on the server.&lt;/p&gt;

&lt;div class=&quot;centered-image&quot;&gt;
  &lt;img src=&quot;/images/message_form_component.png&quot; /&gt;
  &lt;p&gt;Message form component&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;We start again with the visual aspects of the &lt;code&gt;message_form.html&lt;/code&gt;:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div class=&amp;quot;message-form&amp;quot;&amp;gt;
  &amp;lt;form ng-submit=&amp;quot;ctrl.sendMessage(ctrl.message)&amp;quot; submit-form-on-return&amp;gt;
    &amp;lt;textarea ng-model=&amp;quot;ctrl.message&amp;quot; placeholder=&amp;quot;Press enter to send message&amp;quot; autofocus/&amp;gt;
  &amp;lt;/form&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;It contains a form with an &lt;code&gt;ng-submit&lt;/code&gt; directive and a textarea with an &lt;code&gt;ng-model&lt;/code&gt;. Nothing fancy here, except that I used a what I call a &lt;code&gt;behaviour directive&lt;/code&gt; in comparison to the &lt;code&gt;component directives&lt;/code&gt; which you have seen visualized above already. The directive submits the form when pressing the &lt;code&gt;enter&lt;/code&gt; or &lt;code&gt;return&lt;/code&gt; button on your keyboard.&lt;/p&gt;

&lt;p&gt;Now you might have noticed that I use &lt;code&gt;ctrl&lt;/code&gt; in the &lt;code&gt;ng-submit&lt;/code&gt; and &lt;code&gt;ng-model&lt;/code&gt; directives, as for example &lt;code&gt;ctrl.message&lt;/code&gt;. So, let’s have a look at the directive implementation and more specifically how the scope is set up:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import template from &amp;quot;./message_form.html!text&amp;quot;;
import MessageFormController from &amp;quot;./message_form.controller&amp;quot;;

function messageFormDirective() {
  return {
    restrict: &amp;quot;E&amp;quot;,
    replace: true,
    scope: {},
    template: template,
    bindToController: true,
    controllerAs: &amp;quot;ctrl&amp;quot;,
    controller: MessageFormController
  };
}

messageFormDirective.$inject = [];

export default messageFormDirective;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Focusing on the scope specific parts here, I’ve started with creating an isolated scope with &lt;code&gt;scope&lt;/code&gt; and the scope is bound to the controller using &lt;code&gt;bindToController&lt;/code&gt; as &lt;code&gt;ctrl&lt;/code&gt; using the &lt;code&gt;controllerAs&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;Now all these properties are way to complicated and there’s a lot of duplication in my code, but with Angular 1.4 (&lt;a href=&quot;https://github.com/angular/angular.js/commit/35498d7045ba9138016464a344e2c145ce5264c1&quot;&gt;Angular bindToController git commit&lt;/a&gt;) there’s most probably going to be a new syntax &lt;code&gt;bindToController&lt;/code&gt; which combines all these properties into a single property - perfect for my component directives! And another nice step towards an easy migration path to Angular 2.0!&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;ctrl&lt;/code&gt; inside the template makes sense but of course in the controller itself we just use the controller’s this syntax:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import Auth from &amp;quot;../auth&amp;quot;;

class MessageFormController {

  constructor($http) {
    this.$http = $http;
  }

  sendMessage(message) {
    let params = {
      message:    message,
      created_at: new Date().toISOString(),
      user_id:    Auth.getCurrentUser().id
    };

    this.$http.post(&amp;quot;/messages&amp;quot;, params).then(
      () =&amp;gt; {
        this.message = &amp;quot;&amp;quot;;
      },
      (reason) =&amp;gt; {
        console.log(&amp;quot;error&amp;quot;, reason);
      }
    );
  }

}

MessageFormController.$inject = [&amp;quot;$http&amp;quot;];

export default MessageFormController;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;sendMessage&lt;/code&gt; function is what’s called in the template and is responsible for doing an AJAX &lt;code&gt;POST&lt;/code&gt; request to the &lt;code&gt;/messages&lt;/code&gt; route. The JSON payload (default format in Angular’s $http service) contains the actual message, the current user id and the current date.&lt;/p&gt;

&lt;p&gt;On the server side in &lt;code&gt;app.js&lt;/code&gt; I’ve defined a route for this &lt;code&gt;messages/&lt;/code&gt; endpoint:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;app.post(&amp;quot;/messages&amp;quot;, function(request, response) {
  var message = request.body.message;

  if(message &amp;amp;&amp;amp; message.trim().length &amp;gt; 0) {
    var user_id    = request.body.user_id;
    var created_at = request.body.created_at;
    var user       = _.findWhere(participants, { id: user_id });

    // let our chatroom know there was a new message
    io.sockets.emit(&amp;quot;incoming_message&amp;quot;, { message: message, user: user, created_at: created_at });

    response.json(200, { message: &amp;quot;Message received&amp;quot; });
  } else {
    return response.json(400, { error: &amp;quot;Invalid message&amp;quot; });
  }
})&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;After checking if the request payload contains a &lt;code&gt;message&lt;/code&gt; we extract the &lt;code&gt;user&lt;/code&gt; and the &lt;code&gt;created_at&lt;/code&gt; and emit an event &lt;code&gt;incoming_message&lt;/code&gt; to let all other participants receive this message via Socket.io. Now, the logical next step here would be to add a persistence layer and actually store the message, but not for this current state of the prototype.&lt;/p&gt;

&lt;p&gt;We want to focus next on the message list component which listens for this &lt;code&gt;incoming_message&lt;/code&gt; event.&lt;/p&gt;

&lt;h3 id=&quot;message-list-component&quot;&gt;Message list component&lt;/h3&gt;
&lt;p&gt;The message list component renders a list of messages and handles the &lt;code&gt;incoming_message&lt;/code&gt; event.&lt;/p&gt;

&lt;div class=&quot;centered-image&quot;&gt;
  &lt;img src=&quot;/images/message_list_component.png&quot; /&gt;
  &lt;p&gt;Message list component&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Let’s start again with the template:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div class=&amp;quot;message-list&amp;quot;&amp;gt;
  &amp;lt;div ng-repeat=&amp;quot;messageContent in ctrl.messages&amp;quot; class=&amp;quot;message-item {{messageContent.type}}&amp;quot;&amp;gt;
    &amp;lt;img src=&amp;quot;images/profile.jpg&amp;quot; class=&amp;quot;avatar&amp;quot; ng-if=&amp;quot;messageContent.type == &amp;#39;message&amp;#39;&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;message-container&amp;quot;&amp;gt;
      &amp;lt;div class=&amp;quot;meta&amp;quot;&amp;gt;
        &amp;lt;span class=&amp;quot;author&amp;quot;&amp;gt;{{messageContent.user.name}}&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;date&amp;quot;&amp;gt;{{messageContent.created_at}}&amp;lt;/span&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;message&amp;quot;&amp;gt;
        {{messageContent.message}}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The message list uses the &lt;code&gt;ng-repeat&lt;/code&gt; directive to render a list of messaging. Note, that I’ve introduced two types of messages. The type &lt;code&gt;message&lt;/code&gt; is used for a user generated message, the type &lt;code&gt;notification&lt;/code&gt; for a system generated message, for example: “User Guest 1 joined”, etc. Nothing fancy here, let’s skip the setup of the directive too, because it’s so similar to the other directives and focus instead on the controller:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;class MessageListController {

  constructor(WebSocket) {
    this.messages = [];

    this.WebSocket = WebSocket;

    this.register();
  }

  register() {
    this.WebSocket.on(&amp;#39;incoming_message&amp;#39;, (data) =&amp;gt; {
      this.handleIncomingMessage(data);
    });

    this.WebSocket.on(&amp;#39;new_connection&amp;#39;, (data) =&amp;gt; {
      this.handleNewConnection(data);
    });

    this.WebSocket.on(&amp;#39;user_disconnected&amp;#39;, (data) =&amp;gt; {
      this.handleUserDisconnected(data);
    });
  }

  handleIncomingMessage(data) {
    this.messages.push({ message: data.message, user: data.user, created_at: data.created_at, type: &amp;quot;message&amp;quot; });
  }

  handleUserDisconnected(data) {
    this.messages.push({ message: `User ${data.user.name} disconnected`, name: &amp;quot;System&amp;quot;, created_at: data.created_at, type: &amp;quot;notification&amp;quot; });
  }

  handleNewConnection(data) {
    this.messages.push({ message: `User ${data.user.name} joined`, name: &amp;quot;System&amp;quot;, created_at: data.created_at, type: &amp;quot;notification&amp;quot; });
  }

}

MessageListController.$inject = [&amp;quot;WebSocket&amp;quot;];

export default MessageListController;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The controller is starting with an empty array of messages and registers a whole lot of listeners for various events. The &lt;code&gt;incoming_message&lt;/code&gt; event we discussed above already will simply add the user generated message to &lt;code&gt;messages&lt;/code&gt; array. The other events &lt;code&gt;new_connection&lt;/code&gt; and &lt;code&gt;user_disconned&lt;/code&gt; will add system notification to the message list.&lt;/p&gt;

&lt;p&gt;Now one could argue why this complexity on the client side and in fact I might decide for a future iteration to move all this to the server which then handles the various events and emits a single &lt;code&gt;new_message&lt;/code&gt;. We’ll see how this works out for this week!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;There are two more components namely the &lt;code&gt;sidebar&lt;/code&gt; and the &lt;code&gt;participants-list&lt;/code&gt;, but they are in fact pretty similar to what you’ve seen here already so I’m not going to go into further explaining them here.&lt;/p&gt;

&lt;p&gt;That’s it for today! I’m going to get back to coding. So, stay tuned for tomorrow where I hopefully have the time to add some more polish to the frontend!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;The complete sourcecode can be found in the &lt;a href=&quot;https://github.com/fdietz/how_to_build_your_own_team_chat_in_five_days/tree/master/day_4/nodejs_express_socketio_chat&quot;&gt;github repository&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;This is part 4 of an ongoing series of blog posts. Continue reading &lt;a href=&quot;/2015/04/17/day-5-how-to-build-your-own-team-chat-in-five-days-angular-filters-and-directives.html&quot;&gt;part 5&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/13/day-1-how-to-build-your-own-team-chat-in-five-days.html&quot;&gt;Day 1 - How to build your own team chat in five days&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/14/day-2-how-to-build-your-own-team-chat-in-five-days-es6-modules-angularjs-systemjs-and-jspm.html&quot;&gt;Day 2 - ES6 Modules, AngularJS, SystemJS and JSPM&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/15/day-3-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs.html&quot;&gt;Day 3 - ExpressJS, Socket.io and AngularJS&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/16/day-4-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs-component-based-design-patterns.html&quot;&gt;Day 4 - ExpressJS, Socket.io and AngularJS component-based design patterns&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/17/day-5-how-to-build-your-own-team-chat-in-five-days-angular-filters-and-directives.html&quot;&gt;Day 5 - AngularJS Filters and Directives&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Day 3 - How to build your own team chat in five days - ExpressJS, Socket.io and AngularJS</title>
   <link href="http://fdietz.github.com/2015/04/15/day-3-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs.html"/>
   <updated>2015-04-15T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2015/04/15/day-3-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs</id>
   <content type="html">&lt;p&gt;This is part 3 of an ongoing series of blog posts. Read &lt;a href=&quot;/2015/04/13/day-1-how-to-build-your-own-team-chat-in-five-days.html&quot;&gt;part 1&lt;/a&gt; first and then come back, please!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Welcome back to day 3 of “How to build your own team chat in five days”!&lt;/p&gt;

&lt;p&gt;After two days full of thinkering with the design/HTML/CSS frontend part and first steps towards a complete ES6 based AngularJS structure, I’m actually quite excited to present you the first prototype of “chitchat”. There’s the obligatory screenshot:&lt;/p&gt;

&lt;div class=&quot;centered-image full-size&quot;&gt;
  &lt;img src=&quot;/images/chitchat_screen_2.png&quot; /&gt;
  &lt;p&gt;First prototype with real-time messaging backend&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;You can see on the left the “Guest 5” user’s browser and on the right the “Guest 6” user’s browser. And they have actually exchanged a couple of messages already and you can also see notifications generated by the system, as for example “User Guest 5 joined”.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Without a screenshot - it doesn't count!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ve implemented the backend using NodeJS and specifically &lt;a href=&quot;http://expressjs.com/&quot;&gt;ExpressJS&lt;/a&gt; and &lt;a href=&quot;http://socket.io/&quot;&gt;Socket.IO&lt;/a&gt;. And I’ve integrated my previous gulp workflow and design files. The whole project can be seen in the &lt;a href=&quot;https://github.com/fdietz/how_to_build_your_own_team_chat_in_five_days/tree/master/day_3/nodejs_express_socketio_chat&quot;&gt;github repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here’s the directory structure:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;├── public
│   ├── app
│   ├── images
│   ├── jspm_packages
│   ├── config.js
│   ├── styles
│   └── index.html
└── styles
    ├── base
    ├── layout
    ├── modules
    └── application.scss
├── node_modules
├── package.json
├── gulpfile.js
├── app.js
└── README.md&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The server backend can be found in &lt;code&gt;app.js&lt;/code&gt; and all it’s required npm modules are listed in &lt;code&gt;package.json&lt;/code&gt; and installed in &lt;code&gt;node_modules&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;styles&lt;/code&gt; directory contains the same structure from my previous days and the same &lt;code&gt;gulpfile.js&lt;/code&gt;. But, the configuration is slightly changed since we want the output of the SCSS compilation to be placed in &lt;code&gt;public/styles&lt;/code&gt;. The &lt;code&gt;public/&lt;/code&gt; directory is served by the ExpressJS server and contains static files only. Main entry point as always is the &lt;code&gt;index.html&lt;/code&gt;, the Javascript code can be found in &lt;code&gt;app/&lt;/code&gt; and we have the usual candidates for JSPM here too.&lt;/p&gt;

&lt;p&gt;Let’s have a look at the code more closely tomorrow - sadly I don’t have the time today to finish the article. But stay tuned and see you tomorrow!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;The complete sourcecode can be found in the &lt;a href=&quot;https://github.com/fdietz/how_to_build_your_own_team_chat_in_five_days/tree/master/day_3/nodejs_express_socketio_chat&quot;&gt;github repository&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;This is part 3 of an ongoing series of blog posts. Continue reading &lt;a href=&quot;/2015/04/16/day-4-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs.html&quot;&gt;part 4&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/13/day-1-how-to-build-your-own-team-chat-in-five-days.html&quot;&gt;Day 1 - How to build your own team chat in five days&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/14/day-2-how-to-build-your-own-team-chat-in-five-days-es6-modules-angularjs-systemjs-and-jspm.html&quot;&gt;Day 2 - ES6 Modules, AngularJS, SystemJS and JSPM&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/15/day-3-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs.html&quot;&gt;Day 3 - ExpressJS, Socket.io and AngularJS&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/16/day-4-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs-component-based-design-patterns.html&quot;&gt;Day 4 - ExpressJS, Socket.io and AngularJS component-based design patterns&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/17/day-5-how-to-build-your-own-team-chat-in-five-days-angular-filters-and-directives.html&quot;&gt;Day 5 - AngularJS Filters and Directives&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Day 2 - How to build your own team chat in five days - ES6 Modules, AngularJS, SystemJS and JSPM</title>
   <link href="http://fdietz.github.com/2015/04/14/day-2-how-to-build-your-own-team-chat-in-five-days-es6-modules-angularjs-systemjs-and-jspm.html"/>
   <updated>2015-04-14T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2015/04/14/day-2-how-to-build-your-own-team-chat-in-five-days-es6-modules-angularjs-systemjs-and-jspm</id>
   <content type="html">&lt;p&gt;This is part 2 of an ongoing series of blog posts. Read &lt;a href=&quot;/2015/04/13/day-1-how-to-build-your-own-team-chat-in-five-days.html&quot;&gt;part 1&lt;/a&gt; first and then come back, please!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Welcome again to Day 2! We have quite a lot to cover today. Since I’m very much into using ES6 syntax, I’ve spend lots of time looking into module loading and workflows today.&lt;/p&gt;

&lt;p&gt;First we’ll have a look at module loading, then we develop an AngularJS seed project which can be used as a basis for new projects and finally we discuss how to use ES6 classes and module loading with AngularJS.&lt;/p&gt;

&lt;h2 id=&quot;commonjs-vs-amd-vs-angularjs-modules-vs-es6-modules&quot;&gt;CommonJS vs AMD vs AngularJS Modules vs ES6 modules&lt;/h2&gt;

&lt;p&gt;Before we can get our hands dirty we have to look into how modules are loaded using Javascript. A module can mean various things to different people. For this article, let’s use this definition:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Modules allow code to be logically separated for developers. It additionally prevents namespace conflicts in Javascript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Probably the most famous module in the Javascript community is &lt;a href=&quot;https://jquery.com/&quot;&gt;jQuery&lt;/a&gt; but it also could be some shared code in your team or even a component or feature in your codebase.&lt;/p&gt;

&lt;p&gt;Let’s look into a namespace conflict using jQuery as an example of the current state of module loading. If you use jQuery, it will set the global variable &lt;code&gt;$&lt;/code&gt;. But, if you have an existing variable &lt;code&gt;$&lt;/code&gt; in your codebase those variables will conflict. jQuery’s solution was to introduce a &lt;code&gt;noConflict&lt;/code&gt; mode which basically let’s you define the variable name of the library.&lt;/p&gt;

&lt;p&gt;A rather clumsy solution which is why the community created lots of workarounds. The most interesting standards in my opinion are &lt;a href=&quot;http://wiki.commonjs.org/wiki/CommonJS&quot;&gt;CommonJS&lt;/a&gt; due to its popularity in the &lt;a href=&quot;https://nodejs.org/&quot;&gt;NodeJS&lt;/a&gt; community and AMD (Asynchronous Module Definition) with the most popular implementation being &lt;a href=&quot;http://requirejs.org/&quot;&gt;Require.JS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;CommonJS is commonly used with NodeJS where Javascript is executed on the server. In this case all modules are loaded synchronously. This is in contrast to AMD which was designed to be used in browsers on the client side where modules are loaded asynchronously. Somewhere in between lies &lt;a href=&quot;http://browserify.org/&quot;&gt;browserify&lt;/a&gt; which uses the CommonJS standard to bundle all Javascript code on the server before running it on the client. If you are interested in all the glory details I can recommend &lt;a href=&quot;http://addyosmani.com/writing-modular-js/&quot;&gt;Addy Osmani - Writing modular Javascript with AMD, CommonJS &amp;amp; ES Harmony&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now when AngularJS appeared it introduced dependency injection. AngularJS modules, controllers, directives etc. can define their dependencies and everything is taken care of for the developer. One can even use dependency injection to mock things like HTTP requests in unit tests. Great! But, it relies on all the Javascript to be available in the browser and is not able to request modules asynchronously.&lt;/p&gt;

&lt;p&gt;There are are projects which combined &lt;a href=&quot;https://github.com/angular-ui/ui-router&quot;&gt;ui-router&lt;/a&gt; with &lt;a href=&quot;https://github.com/ocombe/ocLazyLoad&quot;&gt;ocLazyLoad&lt;/a&gt; to lazy load angular modules as defined by the routing configuration. But, this feels more like another workaround and even more specific due to its coupling with Angular’s routing configuration.&lt;/p&gt;

&lt;p&gt;Now here come EcmaScript 6 modules to the rescue. The standard tries to make both users of CommonJS and AMD happy and (hopefully) solves all our problems.&lt;/p&gt;

&lt;p&gt;Let’s have a look at an example with &lt;code&gt;named&lt;/code&gt; exports:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// lib.js
export function sum(x, y) {
  return x + y;
}

export function multiply(x, y) {
  return x * y;
}

// main.js
import {sum, multiply} from &amp;quot;./lib&amp;quot;;

console.log(sum(1, 2));
console.log(multiply(1, 2));&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Here’s another example with a &lt;code&gt;default&lt;/code&gt; export:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// lib.js
export default function sum(x, y) {
  return x + y;
}

// main.js
import sum from &amp;quot;./lib&amp;quot;;

console.log(sum(1, 2));&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The design goals of the spec are the following:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Default exports are favoured&lt;/li&gt;
  &lt;li&gt;Static module structure&lt;/li&gt;
  &lt;li&gt;Support for both synchronous and asynchronous module loading&lt;/li&gt;
  &lt;li&gt;Support for cyclic dependencies between modules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For even more details read &lt;a href=&quot;http://www.2ality.com/2014/09/es6-modules-final.html&quot;&gt;Axel Rauschmayer - ECMAScript 6 modules: the final syntax&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, the only problem is that browsers don’t all support the new standard yet, so we have to transpile our code to ES5 in order to work with the new module syntax today.&lt;/p&gt;

&lt;h2 id=&quot;gulp-workflow-using-gulp-with-systemjs-and-jspm&quot;&gt;Gulp Workflow using gulp with SystemJS and JSPM&lt;/h2&gt;
&lt;p&gt;Let’s have a look into a gulp workflow which uses &lt;a href=&quot;https://github.com/systemjs/systemjs&quot;&gt;SystemJS&lt;/a&gt; and &lt;a href=&quot;http://jspm.io/&quot;&gt;JSPM&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;SystemJS builds on top of the &lt;a href=&quot;https://github.com/ModuleLoader/es6-module-loader&quot;&gt;es6-module-loader&lt;/a&gt; polyfill and adds the capability to load modules that are defined in a variety of syntaxes:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;CommonJS&lt;/li&gt;
  &lt;li&gt;AMD&lt;/li&gt;
  &lt;li&gt;ES6 Modules (using either &lt;a href=&quot;https://babeljs.io/&quot;&gt;Babel&lt;/a&gt; or &lt;a href=&quot;https://github.com/google/traceur-compiler&quot;&gt;traceur-compiler&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;modules that export a global variable (as for example jQuery) via a shim config&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JSPM is a Javascript package manager that sits on top of SystemJS and is able to load modules directory from any registry such as npm, github or bower. In development mode it loads modules as separate files with ES6 and in production it optimizes the modules into a self-executing bundle (without runtime dependency).&lt;/p&gt;

&lt;p&gt;This is how our index.html file looks using SystemJS:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;script src=&amp;quot;jspm_packages/system.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;quot;config.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script&amp;gt;
      System.import(&amp;#39;app/bootstrap&amp;#39;);
    &amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    // fancy stuff here
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;First it loads the SystemJS library and then the &lt;code&gt;config.js&lt;/code&gt; file which contains the configuration for your modules. Then we can use &lt;code&gt;System.import&lt;/code&gt;, the proposed browser loader API for dynamically loading ES6 modules, to import the file &lt;code&gt;app/bootstrap&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now JSPM is used to install all our dependencies using the &lt;code&gt;jspm install&lt;/code&gt; command, for example:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;jspm install jquery&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;JSPM looks up jquery in its registry and installs jQuery in the current file system. Additionally, it adds jQuery to the &lt;code&gt;package.json&lt;/code&gt;, so that your jQuery is only a &lt;code&gt;jspm install&lt;/code&gt; away in the future.&lt;/p&gt;

&lt;p&gt;If we look at &lt;code&gt;config.js&lt;/code&gt;, we can see that JSPM has modified it:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;System.config({
  &amp;quot;paths&amp;quot;: {
    &amp;quot;*&amp;quot;: &amp;quot;*.js&amp;quot;,
    &amp;quot;github:*&amp;quot;: &amp;quot;jspm_packages/github/*.js&amp;quot;
  }
});

System.config({
  &amp;quot;map&amp;quot;: {
    &amp;quot;jquery&amp;quot;: &amp;quot;github:components/jquery@^2.1.3&amp;quot;
  }
});

System.config({
  &amp;quot;versions&amp;quot;: {
    &amp;quot;github:components/jquery&amp;quot;: &amp;quot;2.1.3&amp;quot;
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;These paths and mappings tell JSPM how to install and resolve your module. Most of the time you wont’ need to change anything but sometimes it can be useful to map a longer package name to a smaller one.&lt;/p&gt;

&lt;p&gt;Now, you can load jQuery using ES6 syntax:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import $ from &amp;#39;jquery&amp;#39;;

console.log($.fn.jquery);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;JSPM has several advantages over tools like RequireJS or browserify. With RequireJS you have to install via tools like &lt;a href=&quot;http://bower.io/&quot;&gt;bower&lt;/a&gt;, but then manage the mappings and naming of modules manually. Additionally, with SystemJS you don’t need any type of build tool since it’s all run and compiled in the browser.&lt;/p&gt;

&lt;h2 id=&quot;angular-seed-project&quot;&gt;Angular Seed Project&lt;/h2&gt;

&lt;p&gt;Let’s now check out the &lt;a href=&quot;https://github.com/fdietz/how_to_build_your_own_team_chat_in_five_days/tree/master/day_2/angular_es6_seed&quot;&gt;Angular seed project&lt;/a&gt;. It contains some Angular example code to request and render a list of Github users and to showcase Angular working together with ES6 features.&lt;/p&gt;

&lt;div class=&quot;centered-image&quot;&gt;
  &lt;img src=&quot;/images/github_user_list.png&quot; /&gt;
  &lt;p&gt;Using Angular to render a list of Github users&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Let’s have a look into the structure:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;├── app
│   ├── bootstrap.js
│   ├── main.js
│   ├── user.controller.js
│   ├── user.service.js
│   ├── user_list
│   │   ├── reverse_name.service.js
│   │   ├── user_list.controller.js
│   │   ├── user_list.directive.js
│   │   ├── user_list.module.js
│   │   └── user_list_directive.html
│   └── vendor.js
├── styles
├── node_modules
├── jspm_packages
├── index.html
├── config.js
├── gulpfile.js
├── package.json
└── README.md&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;index.html&lt;/code&gt; file contains the SystemJS based bootstrap as describe above and some initial Angular example code:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;styles/application.css&amp;quot;&amp;gt;

    &amp;lt;script src=&amp;quot;jspm_packages/system.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;quot;config.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script&amp;gt;
      System.import(&amp;#39;app/bootstrap&amp;#39;);
    &amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;

    &amp;lt;div ng-controller=&amp;quot;UserController as ctrl&amp;quot;&amp;gt;

      &amp;lt;h1 ng-hide=&amp;quot;!ctrl.loading&amp;quot;&amp;gt;Loading list of Github users&amp;lt;/h1&amp;gt;

      &amp;lt;div class=&amp;quot;medium progress&amp;quot; ng-show=&amp;quot;ctrl.loading&amp;quot;&amp;gt;
        &amp;lt;div&amp;gt;Loading…&amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;user-list users=&amp;quot;ctrl.users&amp;quot;&amp;gt;&amp;lt;user-list&amp;gt;
    &amp;lt;/div&amp;gt;

  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Since we use SystemJS we cannot use the &lt;code&gt;ng-app&lt;/code&gt; directive in our &lt;code&gt;index.html&lt;/code&gt;. We need to load the main Angular module using SystemJS explicitly. Let’s have a look into &lt;code&gt;app/bootstrap.js&lt;/code&gt; which starts our Angular app:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import mainModule from &amp;#39;./main&amp;#39;;

angular.element(document).ready(function() {
  angular.bootstrap(document, [mainModule.name], { strictDi: true });
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And here’s our first &lt;code&gt;import&lt;/code&gt; statement which contains our actual main module of our shiny new Angular app:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import &amp;#39;./vendor&amp;#39;;

import UserController from &amp;#39;./user.controller&amp;#39;;
import UserService from &amp;#39;./user.service&amp;#39;;

import userListModule from &amp;#39;./user_list/user_list.module&amp;#39;;

let mainModule = angular.module(&amp;#39;mainApp&amp;#39;, [userListModule.name])
  .controller(UserController.name, UserController)
  .service(UserService.name, UserService);

export default mainModule;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note, the last line where the &lt;code&gt;mainModule&lt;/code&gt; is exported using the default export mechanism which let’s us import it using: &lt;code&gt;import mainModule from './main';&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next we are going to look into how to use ES6 classes to define Angular controllers and services.&lt;/p&gt;

&lt;h2 id=&quot;angularjs-using-es6-classes-and-modules&quot;&gt;AngularJS using ES6 classes and modules&lt;/h2&gt;

&lt;p&gt;Let’s start with the &lt;code&gt;UserController&lt;/code&gt; class imported in &lt;code&gt;main.js&lt;/code&gt; above since it is the first mentioned in &lt;code&gt;index.html&lt;/code&gt;:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;class UserController {

  constructor(UserService) {
    this.UserService = UserService;
    this.loading = true;
    this.init();
  }

  init() {
    this.UserService.getUsers().then(users =&amp;gt; {
      this.users = users;
      this.loading = false;
    });
  }
}

UserController.$inject = [&amp;#39;UserService&amp;#39;];

export default UserController;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;UserController&lt;/code&gt; uses the new ES6 constructor to define it’s dependency to the &lt;code&gt;UserService&lt;/code&gt; - it is a best practice to handle all model-specific business logic (as for example loading users from the backend) in services. In the &lt;code&gt;init()&lt;/code&gt; function it actually requests the users and assigns them to the &lt;code&gt;users&lt;/code&gt; attribute. Note the use of the &lt;code&gt;=&amp;gt;&lt;/code&gt; (hash rocket) syntax which is a shortcut for a function and additionally binds the &lt;code&gt;this&lt;/code&gt; context to the &lt;code&gt;UserController&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;loading&lt;/code&gt; attribute is used in &lt;code&gt;index.html&lt;/code&gt; to show a loading indicator while the user list is fetched.&lt;/p&gt;

&lt;p&gt;Angular is now able to dependency inject the &lt;code&gt;UserService&lt;/code&gt; into the &lt;code&gt;UserController&lt;/code&gt; since we imported it and registered it in the main module definition. Here’s the code again from our &lt;code&gt;main.js&lt;/code&gt; file:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import UserService from &amp;#39;./user.service&amp;#39;;

let mainModule = angular.module(&amp;#39;mainApp&amp;#39;, [userListModule.name])
  .controller(UserController.name, UserController)
  .service(UserService.name, UserService);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note that our service was registered using the &lt;code&gt;service&lt;/code&gt; function instead of the &lt;code&gt;factory&lt;/code&gt; function. The service function expects a constructor function (an ES6 class) - similar to the controller function - whereas the factory function is syntactic sugar in case you are not using classes.&lt;/p&gt;

&lt;p&gt;Now since we use &lt;code&gt;strictDi&lt;/code&gt; (strict dependency injection) we must declare our injected class explicitly for &lt;code&gt;UserController&lt;/code&gt;. This is also required for production builds which minify the Javascript code.&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;UserController.$inject = [&amp;#39;UserService&amp;#39;];&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Okay, so we have an initial Angular Controller and Service running. Let’s have a look into the user list directive:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div ng-controller=&amp;quot;UserController as ctrl&amp;quot;&amp;gt;
  &amp;lt;user-list users=&amp;quot;ctrl.users&amp;quot;&amp;gt;&amp;lt;user-list&amp;gt;
&amp;lt;/user-list&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The user list directive is defined very traditionally and not as an ES6 class:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import template from &amp;quot;./user_list_directive.html!text&amp;quot;;
import UserListController from &amp;quot;./user_list.controller&amp;quot;;

function userListDirective(ReverseNameService) {
  return {
    restrict: &amp;quot;E&amp;quot;,
    scope: {
      users: &amp;quot;=&amp;quot;
    },
    template: template,
    bindToController: true,
    controllerAs: &amp;quot;ctrl&amp;quot;,
    controller: UserListController,
    link: function($scope, element) {
      element.on(&amp;quot;mouseover&amp;quot;, &amp;quot;li&amp;quot;, function(event) {
        let name = $(event.currentTarget).find(&amp;quot;.primary&amp;quot;).text();
        let reverseName = ReverseNameService.reverse(name);

        console.log(&amp;quot;hover... &amp;quot;, name, &amp;quot;reverse&amp;quot;, reverseName);
      });
    }
  };
}

userListDirective.$inject = [&amp;quot;ReverseNameService&amp;quot;];

export default userListDirective;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Here I export the function as is, since this is the only straight-forward way to support dependency injection.&lt;/p&gt;

&lt;p&gt;The user list is a “component” in the sense that it contains a controller and a template with the responsibility to render the user list and handle various events. I’m therefore using the &lt;code&gt;bindToController&lt;/code&gt; syntax and an externally defined &lt;code&gt;UserListController&lt;/code&gt; for the business logic and use the isolated scope to define the &lt;code&gt;users&lt;/code&gt; attribute as the external interface for passing data from &lt;code&gt;index.html&lt;/code&gt; to the directive. I’m already looking forward to use Angular 1.4 since it supports a much cleaner syntax for &lt;code&gt;bindToController&lt;/code&gt;. There’s currently a lot of code required to setup such a component.&lt;/p&gt;

&lt;p&gt;Have you spotted the strange import statement for the template?&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import template from &amp;quot;./user_list_directive.html!text&amp;quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I’m using here the SystemJS &lt;a href=&quot;https://github.com/systemjs/plugin-text&quot;&gt;text plugin&lt;/a&gt; to load the HTML template and then assign this template as a string to the directive. Note, the &lt;code&gt;!text&lt;/code&gt; expression at the end of the import statement.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;This must be the most horrible example of a service usage inside a directive ever! Don't try this at home.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Never mind my weird &lt;code&gt;link&lt;/code&gt; function where I tried hard to come up with an example to use the injected &lt;code&gt;ReverseNameService&lt;/code&gt;, just to prove my point that you can use dependency injection in this context.&lt;/p&gt;

&lt;p&gt;Now if you followed me closely you found that I’m using the Angular module syntax and the ES6 module syntax side by side. Why is that?&lt;/p&gt;

&lt;p&gt;All controllers, directives or services which are dependency injected are required to be registered via Angular’s &lt;code&gt;controller&lt;/code&gt;, &lt;code&gt;service&lt;/code&gt; and &lt;code&gt;directive&lt;/code&gt; functions. So, I’ve used ES6 modules wherever possible and only used Angular modules where required by Angular. As we are heading towards Angular 2.0 all these Angular modules will be replaced with ES6 modules anyways and I tried to structure the code in a way which makes a migration as simple as possible.&lt;/p&gt;

&lt;p&gt;Now, in my case I created a user list Angular module which contains everything required for the user list directive. It is therefore completely self contained and could be easily copy and pasted into another project. It does not have any dependencies to it’s parent module.&lt;/p&gt;

&lt;p&gt;To finish off for today I will show you the &lt;code&gt;UserListController&lt;/code&gt; quickly:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;class UserListController {

  constructor() {
  }

  onClick(user) {
    console.log(&amp;quot;on user clicked&amp;quot;, user)
  }
}

UserListController.$inject = [];

export default UserListController;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Nothing new here really. The &lt;code&gt;onClick&lt;/code&gt; function is referenced in the template of the directive here:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;ul class=&amp;quot;user-list&amp;quot;&amp;gt;
  &amp;lt;li ng-repeat=&amp;quot;user in ctrl.users&amp;quot; ng-click=&amp;quot;ctrl.onClick(user)&amp;quot;&amp;gt;
    &amp;lt;img ng-src=&amp;quot;&amp;quot; width=&amp;quot;36px&amp;quot; height=&amp;quot;36px&amp;quot; alt=&amp;quot;&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;meta&amp;quot;&amp;gt;
      &amp;lt;span class=&amp;quot;primary&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;
      &amp;lt;span class=&amp;quot;secondary&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;hr /&gt;

&lt;p&gt;If you want to use the Angular seed project for your own projects you can directly access and git clone it from &lt;a href=&quot;https://github.com/fdietz/angular_es6_seed&quot;&gt;github.com/fdietz/angular_es6_seed&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;That’s it for today! Hope I haven’t lost you in the confusing world of Javascript modules. See you tomorrow but this time I’m really starting with “chitchat” ;-)&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;This is part 2 of an ongoing series of blog posts. Continue reading &lt;a href=&quot;/2015/04/15/day-3-how-to-build-your-own-team-chat-in-five-days.html&quot;&gt;part 3&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/13/day-1-how-to-build-your-own-team-chat-in-five-days.html&quot;&gt;Day 1 - How to build your own team chat in five days&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/14/day-2-how-to-build-your-own-team-chat-in-five-days-es6-modules-angularjs-systemjs-and-jspm.html&quot;&gt;Day 2 - ES6 Modules, AngularJS, SystemJS and JSPM&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/15/day-3-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs.html&quot;&gt;Day 3 - ExpressJS, Socket.io and AngularJS&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/16/day-4-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs-component-based-design-patterns.html&quot;&gt;Day 4 - ExpressJS, Socket.io and AngularJS component-based design patterns&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/17/day-5-how-to-build-your-own-team-chat-in-five-days-angular-filters-and-directives.html&quot;&gt;Day 5 - AngularJS Filters and Directives&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Day 1 - How to build your own team chat in five days</title>
   <link href="http://fdietz.github.com/2015/04/13/day-1-how-to-build-your-own-team-chat-in-five-days.html"/>
   <updated>2015-04-13T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2015/04/13/day-1-how-to-build-your-own-team-chat-in-five-days</id>
   <content type="html">&lt;p&gt;Hi and welcome to my little experiment! I’d like to built my own team chat in five days and invite you to join me along the way.&lt;/p&gt;

&lt;p&gt;You probably know &lt;a href=&quot;https://slack.com/&quot;&gt;Slack&lt;/a&gt;, &lt;a href=&quot;https://www.hipchat.com/&quot;&gt;Hipchat&lt;/a&gt;, &lt;a href=&quot;https://campfirenow.com/&quot;&gt;Campfire&lt;/a&gt; and the like. All these are without a doubt excellent services but they are not as open as I’d like them to be. This starts with the fact that there are all data silos and use proprietary protocols and obviously the source code is not open to contribution.&lt;/p&gt;

&lt;p&gt;In the next 5 days I’d like to show you how to build your own chat service and will give you a basis you can work with to add your own unique ideas. So, the emphasize here will be learning how to build your own system in comparison to all these hipster startups out there who focus on saving the world ;-)&lt;/p&gt;

&lt;div class=&quot;centered-image full-size&quot;&gt;
  &lt;img src=&quot;/images/DSCF2636.JPG&quot; /&gt;
  &lt;p&gt;Obligatory hipster workspace pic&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Since I haven’t really done any upfront planing or detailed product definition we both won’t really know how this is going to work out or how the final product is going to look like. But, I promise this will not be just another polished blog serious about how to use Socket.IO to implement a chat room :) Instead I’m going to write my progress in this blog on a daily basis and you can join me along for the ride. It’ll be hopefully much more personal and give you more insights how I approach such a task.&lt;/p&gt;

&lt;p&gt;I will focus much more on the design and implementation challenges on the frontend instead of the backend. So, this will be especially interesting for AngularJS developers who want to learn how to structure more complex projects. For some more AngularJS background knowledge I recommend &lt;a href=&quot;http://fdietz.github.io/recipes-with-angular-js/&quot;&gt;Recipes with AngularJS&lt;/a&gt; from your truly! Since I’d like to challenge myself, I’m going to use ES6 which is currently not really well documented. But, it is certainly the future of Javascript development and I’m eager to get to know it better in these upcoming days.&lt;/p&gt;

&lt;p&gt;As a prerequisite I assume you have basic knowledge of HTML, CSS, Javascript and AngularJS - bonus points for NodeJS and things like &lt;a href=&quot;http://gulpjs.com/&quot;&gt;gulp&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, take a deep breath and a cup of tea and let’s get started!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Usually when I start working on a “new” idea, I first search on Google what’s out there already. Resources as for example &lt;a href=&quot;https://dribbble.com/search?q=UI&quot;&gt;dribbble&lt;/a&gt; or &lt;a href=&quot;https://www.behance.net/search?field=51&quot;&gt;behance&lt;/a&gt; are a great source of inspiration for me - especially since I’m not a designer! So without further gequassel I proudly present you “chitchat”.&lt;/p&gt;

&lt;div class=&quot;centered-image shadow&quot;&gt;
  &lt;img src=&quot;/images/chitchat_screen_1.png&quot; /&gt;
  &lt;p&gt;HTML mockup of chitchat&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;I know - it’s not pixel perfect. But, it’s a first iteration done in HTML, SCSS and is therefore a nice basis for adding interaction using AngularJS later on.&lt;/p&gt;

&lt;p&gt;You can already see where this is heading from the mockup. The sidebar shows some public channels and some private one-to-one conversations. So, we will definitely need some user management and a way to join a public channel. The little red badge shows two recent messages and I should probably come up with a distinction for important messages as for example a person being mentioned vs an ongoing conversation in a public channel.&lt;/p&gt;

&lt;p&gt;Then there’s the main view showing the ongoing conversation and of course it would be awesome if we can get this to work real time using a server push mechanism. I’m not sure yet if adding support for file sharing should be part of this five days sprint.&lt;/p&gt;

&lt;p&gt;In the right hand corner there’s a search field, but we’ll have to see if there’s enough time for that at the end of the week.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;You can find the complete sourcecode on the accompanying &lt;a href=&quot;https://github.com/fdietz/how_to_build_your_own_team_chat_in_five_days/tree/master/day_1&quot;&gt;Github repo&lt;/a&gt;. You can either download the repository as a zip file or use &lt;a href=&quot;http://git-scm.com/&quot;&gt;git&lt;/a&gt; to clone the repository.&lt;/p&gt;

&lt;p&gt;Let’s have a look at the content using the &lt;a href=&quot;http://mama.indstate.edu/users/ice/tree/&quot;&gt;tree&lt;/a&gt; command:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;└── day_1
    ├── fonts
    ├── images
    ├── styles
    ├── gulpfile.js
    ├── index.html
    ├── package.json
    └── README.md&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I’ve started with a simple &lt;code&gt;index.html&lt;/code&gt; and created directories for fonts, images and css files. The &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;gulpfile.js&lt;/code&gt; are used for my CSS workflow. I’m a fan of &lt;a href=&quot;http://sass-lang.com/&quot;&gt;Sass&lt;/a&gt; and the &lt;a href=&quot;https://smacss.com/&quot;&gt;SMACSS style guide&lt;/a&gt;, hence the directory structure:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;└── styles
    ├── application.css
    ├── application.scss
    ├── base
    │   ├── _fonts.scss
    │   ├── _globals.scss
    │   ├── _normalize.scss
    │   └── _variables.scss
    ├── layout
    │   └── _scaffold.scss
    ├── modules
    │   ├── _badge.scss
    │   ├── _input.scss
    │   ├── _main_header.scss
    │   ├── _message_form.scss
    │   ├── _message_list.scss
    │   └── _sidebar.scss
    └── pages&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I’ve used a gulp task to compile my &lt;code&gt;scss&lt;/code&gt; files to &lt;code&gt;css&lt;/code&gt; for me.&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var gulp         = require(&amp;#39;gulp&amp;#39;);
var sass         = require(&amp;#39;gulp-sass&amp;#39;);
var sourcemaps   = require(&amp;#39;gulp-sourcemaps&amp;#39;);
var autoprefixer = require(&amp;#39;gulp-autoprefixer&amp;#39;);

gulp.task(&amp;#39;styles&amp;#39;, function() {
  gulp.src(&amp;#39;styles/*.scss&amp;#39;)
    .pipe(sourcemaps.init())
      .pipe(sass({ style: &amp;#39;expanded&amp;#39; }))
      .pipe(autoprefixer(&amp;#39;last 2 version&amp;#39;))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest(&amp;#39;styles&amp;#39;))
});

gulp.task(&amp;#39;watch&amp;#39;, function(){
  gulp.watch(&amp;#39;./styles/**/*.scss&amp;#39;, [&amp;#39;styles&amp;#39;]);
});

gulp.task(&amp;#39;build&amp;#39;, [&amp;#39;styles&amp;#39;]);

gulp.task(&amp;#39;default&amp;#39;, [&amp;#39;build&amp;#39;, &amp;#39;watch&amp;#39;]);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You can run it by executing &lt;code&gt;gulp&lt;/code&gt; on the commandline. This will trigger the &lt;code&gt;default&lt;/code&gt; task which will in turn call the &lt;code&gt;build&lt;/code&gt; task. A file watcher is used to rebuild the CSS on file changes using the &lt;code&gt;watch&lt;/code&gt; task. The output will be place in &lt;code&gt;styles/application.css&lt;/code&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;You can find the complete sourcecode on the accompanying &lt;a href=&quot;https://github.com/fdietz/how_to_build_your_own_team_chat_in_five_days/tree/master&quot;&gt;Github repo&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Okidoki. This is it for day 1 - hope you liked it! Tomorrow we will look into using AngularJS to structure our team chat and get some initial interaction going. See you tomorrow!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;This is part 1 of an ongoing series of blog posts. Continue reading &lt;a href=&quot;/2015/04/14/day-2-how-to-build-your-own-team-chat-in-five-days.html&quot;&gt;part 2&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/13/day-1-how-to-build-your-own-team-chat-in-five-days.html&quot;&gt;Day 1 - How to build your own team chat in five days&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/14/day-2-how-to-build-your-own-team-chat-in-five-days-es6-modules-angularjs-systemjs-and-jspm.html&quot;&gt;Day 2 - ES6 Modules, AngularJS, SystemJS and JSPM&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/15/day-3-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs.html&quot;&gt;Day 3 - ExpressJS, Socket.io and AngularJS&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/16/day-4-how-to-build-your-own-team-chat-in-five-days-expressjs-socket-io-and-angularjs-component-based-design-patterns.html&quot;&gt;Day 4 - ExpressJS, Socket.io and AngularJS component-based design patterns&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/04/17/day-5-how-to-build-your-own-team-chat-in-five-days-angular-filters-and-directives.html&quot;&gt;Day 5 - AngularJS Filters and Directives&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Recipes with Angular.js is free</title>
   <link href="http://fdietz.github.com/2014/01/12/recipes-with-angular-js-is-free.html"/>
   <updated>2014-01-12T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2014/01/12/recipes-with-angular-js-is-free</id>
   <content type="html">&lt;p&gt;I’m very pleased to announce that my ebook “Recipes with Angular.js” is now free under &lt;a href=&quot;http://creativecommons.org/licenses/by-sa/3.0/deed.en_US&quot;&gt;Creative Commons License&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That means you are free to copy, distribute, adapt and even make commercial use of it! The &lt;a href=&quot;https://github.com/fdietz/recipes-with-angular-js-examples&quot;&gt;examples repository&lt;/a&gt; was always free, but now you can also use the &lt;a href=&quot;https://github.com/fdietz/recipes-with-angular-js-manuscript&quot;&gt;manuscript&lt;/a&gt;. Note, that you can still support me and buy the book on &lt;a href=&quot;https://leanpub.com/recipes-with-angular-js&quot;&gt;leanpub&lt;/a&gt; or &lt;a href=&quot;http://www.amazon.com/Recipes-Angular-js-Frederik-Dietz-ebook/dp/B00DK95V48/ref=sr_1_1?ie=UTF8&amp;amp;qid=1389523586&amp;amp;sr=8-1&amp;amp;keywords=recipes+with+angular.js&quot;&gt;Amazon&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Last but not least, I’ve created a new website &lt;a href=&quot;http://fdietz.github.io/recipes-with-angular-js/&quot;&gt;Recipes with Angular.js&lt;/a&gt; which contains all the original book’s content nicely formatted, with full-text search and direct edit support using &lt;a href=&quot;http://jsfiddle.net/&quot;&gt;JSFiddle&lt;/a&gt;. From now on this will be the place to look for new recipes or fine-tune existing ones. Everyone can contribute via github!&lt;/p&gt;

&lt;p&gt;Many thanks again for all my readers who initially bought the book and supported the ongoing work!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Team Dashboard v2.0.0 released</title>
   <link href="http://fdietz.github.com/2013/05/05/team-dashboard-v2-0-0-released.html"/>
   <updated>2013-05-05T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2013/05/05/team-dashboard-v2-0-0-released</id>
   <content type="html">&lt;p&gt;I’ve just tagged the &lt;code&gt;v2.0.0&lt;/code&gt; release of &lt;a href=&quot;http://fdietz.github.io/team_dashboard/&quot;&gt;Team Dashboard&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/fdietz/team_dashboard/blob/master/CHANGELOG.md&quot;&gt;changelog&lt;/a&gt; has all the gory details. For a more user friendly read visit:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://fdietz.github.io/2013/03/16/team-dashboard-2-release-candidate.html&quot;&gt;2.0.0 Release Candidate 1&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://fdietz.github.io/2013/04/14/team-dashboard-2-release-candidate-2.html&quot;&gt;2.0.0 Release Candidate 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Recipes with Angular.js: Update available</title>
   <link href="http://fdietz.github.com/2013/05/05/recipes-with-angular-js-update-available.html"/>
   <updated>2013-05-05T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2013/05/05/recipes-with-angular-js-update-available</id>
   <content type="html">&lt;p&gt;I’ve just published a new version of &lt;a href=&quot;https://leanpub.com/recipes-with-angular-js&quot;&gt;Recipes with Angular.js&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Many changes were made to improve the overall quality, some chapters were completely rewritten. You will be delighted to find improved formatting of the sourcecode examples to fit nicely on the PDF version and each recipe has a direct link to the complete sourcecode on Github.&lt;/p&gt;

&lt;p&gt;Additionally, it features a new chapter on deferred and promise usage in Angular.js, which was requested by some readers.&lt;/p&gt;

&lt;p&gt;The is the second to the last and final update to the book. The last update will only include fixes by my english editor.&lt;/p&gt;

&lt;p&gt;Hope you like it!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Team Dashboard 2 Release Candidate 2</title>
   <link href="http://fdietz.github.com/2013/04/14/team-dashboard-2-release-candidate-2.html"/>
   <updated>2013-04-14T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2013/04/14/team-dashboard-2-release-candidate-2</id>
   <content type="html">&lt;p&gt;This is the second release candidate of &lt;a href=&quot;https://github.com/fdietz/team_dashboard&quot;&gt;Team Dashboard&lt;/a&gt; and hopefully the last one before the final version 2 release. There are some really exciting new features in this release candidate. So, please give it a try and report issues!&lt;/p&gt;

&lt;p&gt;Changelog:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Number widget optionally displays a metric suffix.&lt;/li&gt;
  &lt;li&gt;Number widget supports datapoints data source (number widget now completely replaced the counter widget which was already removed in RC1) as for example graphite (choose &lt;code&gt;datapoints&lt;/code&gt; as source to view all options)&lt;/li&gt;
  &lt;li&gt;New meter widget (using jQuery knob) which uses the number data source.&lt;/li&gt;
  &lt;li&gt;New alert widget with its own data source. Initially supports &lt;a href=&quot;http://www.sonian.com/cloud-monitoring-sensu/&quot;&gt;sensu&lt;/a&gt; (thanks to DraganMileski). Should be useful for future plugins as for example nagios alerts or similar.&lt;/li&gt;
  &lt;li&gt;Graph widget supports max y-axis value. Useful if your data has lots of outliers which makes the automatic scaling work nicely again.&lt;/li&gt;
  &lt;li&gt;The graph widget has a max y axis value option which is useful if the autoscaling is confused by very large outliers&lt;/li&gt;
  &lt;li&gt;Unicorn is the new default rack server. This makes deployment on a free Heroku plan a viable option (#68 - thanks to deathowl)&lt;/li&gt;
  &lt;li&gt;Dashboards can be shown in fullscreen mode using &lt;a href=&quot;https://github.com/bdougherty/BigScreen&quot;&gt;bigscreen.js&lt;/a&gt; (Thanks to ngbroadbent)&lt;/li&gt;
  &lt;li&gt;Bugfix: Broken Number::NewRelic source #78&lt;/li&gt;
  &lt;li&gt;Bugfix: CI widget loses the light indicator #76&lt;/li&gt;
  &lt;li&gt;Bugfix: Sensu bugfixes #72 (thanks to DraganMileski)&lt;/li&gt;
  &lt;li&gt;Bugfix: Changing targets length #71 (thanks to hamann)&lt;/li&gt;
  &lt;li&gt;Bugfix: Exception Tracker Widget does not work #77&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Team Dashboard 2 Release Candidate</title>
   <link href="http://fdietz.github.com/2013/03/16/team-dashboard-2-release-candidate.html"/>
   <updated>2013-03-16T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2013/03/16/team-dashboard-2-release-candidate</id>
   <content type="html">&lt;p&gt;May I present you the all new &lt;a href=&quot;https://github.com/fdietz/team_dashboard&quot;&gt;Team Dashboard&lt;/a&gt; version 2.&lt;/p&gt;

&lt;p&gt;It is a release candidate to get things stable again, so give it a try and report bugs!&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/fdietz/team_dashboard/blob/master/VERSION2_MIGRATION.markdown&quot;&gt;migration guide&lt;/a&gt; should help you getting started.&lt;/p&gt;

&lt;p&gt;Changelog:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;I’ve replaced Backbone.js and now use Angular.js. Some of you may already know that I’m working on a leanpub book &lt;a href=&quot;https://leanpub.com/recipes-with-angular-js&quot;&gt;Recipes with Angular.js&lt;/a&gt;. So, this shouldn’t be really surprising. I don’t want to start an emotional discussion about what’s the better Javascript MVC Framework, but for me using Angular.js leads to less code which is much easier to maintain and understand.&lt;/li&gt;
  &lt;li&gt;Moving to Angular.js I was finally able to make it super straight forward to add new widgets. Read more in the &lt;a href=&quot;https://github.com/fdietz/team_dashboard/blob/master/WIDGETS.markdown&quot;&gt;Widgets Developer Guide&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Data source plugin implementations are now simplified too in order to make adding new sources even easier. All data source plugins use a single controller to expose the JSON API to the rails app. Additionally, I’ve deprecated the plugin repository since there wasn’t much going on anyways. Instead I will focus to have good quality plugins shipped with Team Dashboard out of the box. There’s a &lt;a href=&quot;https://github.com/fdietz/team_dashboard/blob/master/SOURCE_PLUGINS.markdown&quot;&gt;Data Source Plugin Developer Guide&lt;/a&gt; available as well.&lt;/li&gt;
  &lt;li&gt;The counter and number widgets were combined into the number widget. This was a source of confusion for beginners anyways.&lt;/li&gt;
  &lt;li&gt;The dashboard uses &lt;a href=&quot;http://gridster.net/&quot;&gt;gridster.js&lt;/a&gt; instead of &lt;a href=&quot;http://jqueryui.com/sortable/&quot;&gt;jQuery UI Sortable&lt;/a&gt; which finally makes it possible to have different widget sizes in both dimensions. This also means that all widgets support only a single data source - leading to much simpler configuration and API usage.&lt;/li&gt;
  &lt;li&gt;New data source plugins: &lt;a href=&quot;https://www.pingdom.com/&quot;&gt;Pingdom&lt;/a&gt;, Shell script, &lt;a href=&quot;http://hockeyapp.net/&quot;&gt;Hockey App&lt;/a&gt;, &lt;a href=&quot;https://github.com/errbit/errbit&quot;&gt;Errbit&lt;/a&gt; and &lt;a href=&quot;http://newrelic.com/&quot;&gt;New Relic&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;A more fine tuned look and feel for the widgets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Last but not least. I’d like to make it as easy as possible to contribute to Team Dashboard. Learning a new framework always takes time. That’s why every contributor will receive a free copy of my &lt;a href=&quot;https://leanpub.com/recipes-with-angular-js&quot;&gt;book&lt;/a&gt;!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Recipes with Angular.js: New Chapters Added</title>
   <link href="http://fdietz.github.com/2013/02/26/recipes-with-angular-js-new-chapters-added.html"/>
   <updated>2013-02-26T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2013/02/26/recipes-with-angular-js-new-chapters-added</id>
   <content type="html">&lt;p&gt;I’ve just published a new version of &lt;a href=&quot;https://leanpub.com/recipes-with-angular-js&quot;&gt;Recipes with Angular.js&lt;/a&gt;! with the next chapters.&lt;/p&gt;

&lt;p&gt;Chapter 8 &lt;em&gt;Common User Interface Patterns&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Filtering and Sorting a List&lt;/li&gt;
  &lt;li&gt;Paginating Through Client-Side Data&lt;/li&gt;
  &lt;li&gt;Paginating Through Server-Side Data&lt;/li&gt;
  &lt;li&gt;Paginating Using Infinite Results&lt;/li&gt;
  &lt;li&gt;Displaying a Flash Notice/Failure Message&lt;/li&gt;
  &lt;li&gt;Editing Text In-Place using HTML5 ContentEditable&lt;/li&gt;
  &lt;li&gt;Displaying a Modal Dialog&lt;/li&gt;
  &lt;li&gt;Displaying a Loading Spinner&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Chapter 9 &lt;em&gt;Backend Integration with Ruby on Rails&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Consuming REST APIs&lt;/li&gt;
  &lt;li&gt;Implementing Client-Side Routing&lt;/li&gt;
  &lt;li&gt;Validating Forms Server-Side&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Chapter 10 &lt;em&gt;Backend Integration with Node Express&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Consuming REST APIs&lt;/li&gt;
  &lt;li&gt;Implementing Client-Side Routing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hope you like the new content! Please let me know if you have any suggestions or find mistakes!&lt;/p&gt;

&lt;p&gt;I’ve got now all the planned content in the book and like to focus next on the quality before adding new recipes. Additionally, I found a professional copy writer who is correcting my English writing.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Angular.js Controllers: Changing a Model Value with a Controller Function</title>
   <link href="http://fdietz.github.com/2013/02/19/angular-js-controllers-changing-a-model-value-with-a-controller-function.html"/>
   <updated>2013-02-19T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2013/02/19/angular-js-controllers-changing-a-model-value-with-a-controller-function</id>
   <content type="html">&lt;p&gt;This is a post of a series about &lt;a href=&quot;http://angularjs.org/&quot;&gt;Angular.js&lt;/a&gt;, the Superheroic Javascript MVW Framework. It is extracted from my ebook &lt;a href=&quot;https://leanpub.com/recipes-with-angular-js&quot;&gt;Recipes with Angular.js&lt;/a&gt;. If you like this post please support me and buy it!&lt;/p&gt;

&lt;h3 id=&quot;problem&quot;&gt;Problem&lt;/h3&gt;
&lt;p&gt;You want to increment a model value by 1.&lt;/p&gt;

&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;
&lt;p&gt;Implement an increment function which changes the scope.&lt;/p&gt;

&lt;p&gt;We use the &lt;code&gt;ng-init&lt;/code&gt; Directive to call the &lt;code&gt;incrementValue&lt;/code&gt; function in the template.&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div ng-controller=&amp;quot;MyCtrl&amp;quot;&amp;gt;
  &amp;lt;p ng-init=&amp;quot;incrementValue(5)&amp;quot;&amp;gt;{{value}}&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The controller defines the default value and the &lt;code&gt;incrementValue&lt;/code&gt; function.&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function MyCtrl($scope) {
  $scope.value = 1;

  $scope.incrementValue = function(value) {
    $scope.value += 1;
  };
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;discussion&quot;&gt;Discussion&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;ng-init&lt;/code&gt; directive is executed on page load and calls the function defined in &lt;code&gt;MyCtrl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can find the complete &lt;a href=&quot;https://github.com/fdietz/recipes-with-angular-js-examples/tree/master/chapter2/recipe2&quot;&gt;example&lt;/a&gt; on Github.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Recipes with Angular.js: Updated With New Content</title>
   <link href="http://fdietz.github.com/2013/02/16/recipes-with-angular-js-updated-with-new-content.html"/>
   <updated>2013-02-16T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2013/02/16/recipes-with-angular-js-updated-with-new-content</id>
   <content type="html">&lt;p&gt;I’ve just published a new version of &lt;a href=&quot;https://leanpub.com/recipes-with-angular-js&quot;&gt;Recipes with Angular.js&lt;/a&gt;! It contains numerous small fixes and improvements but also a lot of new content for you!&lt;/p&gt;

&lt;p&gt;Chapter 2 &lt;em&gt;Controllers&lt;/em&gt; has new recipes:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Sharing Models Between Nested Controllers&lt;/li&gt;
  &lt;li&gt;Sharing Code Between Controllers using Services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The new chapter: &lt;em&gt;URLs, Routing and Partials&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Client-Side Routing with Hashbang URLs&lt;/li&gt;
  &lt;li&gt;Using Regular URLs with the HTML5 History API&lt;/li&gt;
  &lt;li&gt;Using Route Location to Implement a Navigation Menu&lt;/li&gt;
  &lt;li&gt;Listening on Route Changes to Implement a Login Mechanism&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And another new chapter: &lt;em&gt;Using Forms&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Implementing a Basic Form&lt;/li&gt;
  &lt;li&gt;Validating a Form Model Client-Side&lt;/li&gt;
  &lt;li&gt;Displaying Form Validation Errors&lt;/li&gt;
  &lt;li&gt;Displaying Form Validation Errors with the Twitter Bootstrap Framework&lt;/li&gt;
  &lt;li&gt;Only Enabling the Submit Button if the Form is Valid&lt;/li&gt;
  &lt;li&gt;Implementing Custom Validations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please, let me know if you are interested in more recipes in these particular chapters.&lt;/p&gt;

&lt;p&gt;Next, I’m going to work on the &lt;em&gt;Common User Interface Patterns&lt;/em&gt; chapter, which will be a lot of fun. You are going to learn about severals types of Pagination, Sorting, Filtering, Flash Messages, Modal Dialogs, Loading Spinners, etc.&lt;/p&gt;

&lt;p&gt;I hope you enjoy the new content.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Angular.js Controllers - Assigning a Default Value to a Model</title>
   <link href="http://fdietz.github.com/2013/02/15/angular-js-controllers-assigning-a-default-value-to-a-model.html"/>
   <updated>2013-02-15T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2013/02/15/angular-js-controllers-assigning-a-default-value-to-a-model</id>
   <content type="html">&lt;p&gt;This is the first of a series of posts about &lt;a href=&quot;http://angularjs.org/&quot;&gt;Angular.js&lt;/a&gt;, the Superheroic Javascript MVW Framework. It is extracted from my ebook &lt;a href=&quot;https://leanpub.com/recipes-with-angular-js&quot;&gt;Recipes with Angular.js&lt;/a&gt;. If you like this post please support me and buy it!&lt;/p&gt;

&lt;h3 id=&quot;problem&quot;&gt;Problem&lt;/h3&gt;
&lt;p&gt;You want to assign a default value to the scope in the controllers context.&lt;/p&gt;

&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;
&lt;p&gt;Use the &lt;code&gt;ng-controller&lt;/code&gt; directive in your template:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;div ng-controller=&amp;quot;MyCtrl&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;{{value}}&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And define the scope variable in your controller function:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var MyCtrl = function($scope) {
  $scope.value = &amp;quot;some value&amp;quot;;
};&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;discussion&quot;&gt;Discussion&lt;/h3&gt;
&lt;p&gt;Depending on where you use the ng-controller directive, you define its assigned scope. The scope is hierachical and follows the DOM nodes hierarchy. In our example the value expression is correctly evaluated to &lt;code&gt;some value&lt;/code&gt;, since value is set in the &lt;code&gt;MyCtrl&lt;/code&gt; controller.&lt;/p&gt;

&lt;p&gt;Note, that this would not work if the value expression is moved outside the controllers scope:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;p&amp;gt;{{value}}&amp;lt;/p&amp;gt;

&amp;lt;div ng-controller=&amp;quot;MyCtrl&amp;quot;&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;In this case &lt;code&gt;{{value}}&lt;/code&gt; will simply be not rendered at all.&lt;/p&gt;

&lt;p&gt;You can find the complete &lt;a href=&quot;https://github.com/fdietz/recipes-with-angular-js-examples/tree/master/chapter2/recipe1&quot;&gt;example&lt;/a&gt; on Github.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Team Dashboard v0.4 released</title>
   <link href="http://fdietz.github.com/2012/09/06/team-dashboard-version-0-4-released.html"/>
   <updated>2012-09-06T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2012/09/06/team-dashboard-version-0-4-released</id>
   <content type="html">&lt;p&gt;This was a busy week, lots of new stuff to check out!&lt;/p&gt;

&lt;p&gt;Most notable changes are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Graphite Function Editing made easy with a built-in function browser (including reference documentation) and improved error reporting.&lt;/li&gt;
  &lt;li&gt;HTTP Proxy Sources also got a preview mode where you can see the JSON response and can easily select a specific attribute from it.&lt;/li&gt;
  &lt;li&gt;All source plugins can easily specify their own configuration params. These will automatically appear in the widget editor dialog and are persisted as part of the widget configuration. The existing internal sources are already using it. Documentation can be found in the &lt;a href=&quot;https://github.com/fdietz/team_dashboard&quot;&gt;README&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apart from that we fixed a nasty bug in the Ganglia source (&lt;a href=&quot;https://github.com/fdietz/team_dashboard/issues/15&quot;&gt;Issue&lt;/a&gt;), another one in the Graphite source (you can now again fetch multiple targets &lt;a href=&quot;https://github.com/fdietz/team_dashboard/issues/4&quot;&gt;Issue&lt;/a&gt;), updated to the latest Twitter Bootstrap version and documented Team Dashboard’s own &lt;a href=&quot;https://github.com/fdietz/team_dashboard&quot;&gt;REST API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Warning:&lt;/em&gt; This release might break some widget configuration due to the changes in the source plugin configuration. Sorry for any inconveniences!&lt;/p&gt;

&lt;p&gt;So, go ahead and git pull to the latest version!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/fdietz/team_dashboard/issues?milestone=2&amp;amp;state=closed&quot;&gt;Milestone v0.4 Issues&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More information on how to get started on &lt;a href=&quot;https://github.com/fdietz/team_dashboard&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks go to &lt;a href=&quot;http://www.xing.com&quot;&gt;XING&lt;/a&gt; for sponsoring this weeks development on Team Dashboard&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Team Dashboard v0.3 released</title>
   <link href="http://fdietz.github.com/2012/08/25/team-dashboard-version-0-3-released.html"/>
   <updated>2012-08-25T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2012/08/25/team-dashboard-version-0-3-released</id>
   <content type="html">&lt;p&gt;This release includes 69 commits of shiny new features, bug fixes and polishing.&lt;/p&gt;

&lt;p&gt;Most notable changes are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Improved targets/metrics selection UI element &lt;a href=&quot;https://github.com/fdietz/team_dashboard/issues/7&quot;&gt;#7&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Do not always re-fetch metrics/targets collection &lt;a href=&quot;https://github.com/fdietz/team_dashboard/issues/6&quot;&gt;#6&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Use faraday gem and provide single place for all HTTP requests &lt;a href=&quot;https://github.com/fdietz/team_dashboard/issues/8&quot;&gt;#8&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Improved error handling with helpful errors messages &lt;a href=&quot;https://github.com/fdietz/team_dashboard/issues/9&quot;&gt;#9&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Travis CI build&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, go ahead and git pull to the latest version!&lt;/p&gt;

&lt;p&gt;More information on how to get started on &lt;a href=&quot;https://github.com/fdietz/team_dashboard&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Team Dashboard supports Ganglia</title>
   <link href="http://fdietz.github.com/2012/08/09/team-dashboard-supports-ganglia.html"/>
   <updated>2012-08-09T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2012/08/09/team-dashboard-supports-ganglia</id>
   <content type="html">&lt;p&gt;Team Dashboard adds a Ganglia data source to show your system metrics as graph or counter widgets.&lt;/p&gt;

&lt;p&gt;In order to get started you have to configure the URL to your Ganglia installation. The easiest way is to use the environment variable GANGLIA_URL.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;GANGLIA_URL=http://ganglia-host rails server&lt;/p&gt;

&lt;p&gt;More information on how to get started on &lt;a href=&quot;https://github.com/fdietz/team_dashboard&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Team Dashboard introduces Data Source Plugin Repository</title>
   <link href="http://fdietz.github.com/2012/08/09/team-dashboard-introduces-plugin-repository.html"/>
   <updated>2012-08-09T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2012/08/09/team-dashboard-introduces-plugin-repository</id>
   <content type="html">&lt;p&gt;Team Dashboard supports all kinds of data sources. But, there’s always something missing.&lt;/p&gt;

&lt;p&gt;I’d like to use the &lt;a href=&quot;https://github.com/fdietz/team_dashboard_plugins&quot;&gt;team_dashboard_plugins&lt;/a&gt; Github repository as the central place to browse, download and request plugins.&lt;/p&gt;

&lt;p&gt;More information on how to get started on &lt;a href=&quot;https://github.com/fdietz/team_dashboard_plugins&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Team Dashboard supports Jenkins and Travis with a new widget</title>
   <link href="http://fdietz.github.com/2012/08/05/team-dashboard-supports-jenkins-and-travis-with-a-new-widget.html"/>
   <updated>2012-08-05T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2012/08/05/team-dashboard-supports-jenkins-and-travis-with-a-new-widget</id>
   <content type="html">&lt;p&gt;Team Dashboard adds a new widget for all kinds of Continous Integration Server Build Status Information. Jenkins and Travis CI data sources are included out of the box and its easy to add even more.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Team Dashboard HTTP Proxy support much cooler now</title>
   <link href="http://fdietz.github.com/2012/08/05/team-dashboard-http-proxy-much-cooler-now.html"/>
   <updated>2012-08-05T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2012/08/05/team-dashboard-http-proxy-much-cooler-now</id>
   <content type="html">&lt;p&gt;Team Dashboard Number and Boolean Widgets support a HTTP Proxy data source already. Idea is to give it a URL of an existing JSON service which follows the format as specified in the documentation. It will then extract the current value from the JSON structure for you.&lt;/p&gt;

&lt;p&gt;But what if you have an existing service with a different structure? With the new version you can additionally set a value path using a dot notation to select a specific value in your JSON structure.&lt;/p&gt;

&lt;p&gt;Example JSON:&lt;/p&gt;

&lt;p&gt;{
  “parent” : {
    “child” : {
      “child2” : “myValue”
    }
  }
}&lt;/p&gt;

&lt;p&gt;A value path of “parent.child.child2” would resolve “myValue”.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Team Dashboard cloc stats</title>
   <link href="http://fdietz.github.com/2012/07/29/team-dashboard-cloc-stats.html"/>
   <updated>2012-07-29T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2012/07/29/team-dashboard-cloc-stats</id>
   <content type="html">&lt;p&gt;These are the &lt;a href=&quot;http://cloc.sourceforge.net/&quot;&gt;cloc&lt;/a&gt; (Count Lines of Code) stats for Team Dashboard:&lt;/p&gt;

&lt;pre style=&quot;font-size: 12px;&quot;&gt;
&amp;gt; cloc . --exclude-dir=vendor
     201 text files.
     198 unique files.
      92 files ignored.

http://cloc.sourceforge.net v 1.53  T=0.5 s (278.0 files/s, 10878.0 lines/s)
--------------------------------------------------------------------------------
Language                      files          blank        comment           code
--------------------------------------------------------------------------------
Javascript                       56            562             65           2587
Ruby                             66            236            170           1074
Bourne Shell                      8             54            137            249
HTML                              3              3              3             71
YAML                              4             10             77             36
CSS                               1             11              8             34
Bourne Again Shell                1              5             29             18
--------------------------------------------------------------------------------
SUM:                            139            881            489           4069
--------------------------------------------------------------------------------
&lt;/pre&gt;

</content>
 </entry>
 
 <entry>
   <title>Team Dashboard released to the public</title>
   <link href="http://fdietz.github.com/2012/07/28/team-dashboard-released-to-the-public.html"/>
   <updated>2012-07-28T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2012/07/28/team-dashboard-released-to-the-public</id>
   <content type="html">&lt;p&gt;I’ve finally released my weekend project Team Dashboard to the public.&lt;/p&gt;

&lt;p&gt;Website: &lt;a href=&quot;http://fdietz.github.com/team_dashboard/&quot;&gt;http://fdietz.github.com/team_dashboard/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Heroku hosted Demo: &lt;a href=&quot;http://team-dashboard.herokuapp.com/&quot;&gt;http://team-dashboard.herokuapp.com&lt;/a&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>An Introduction to JavaScript this</title>
   <link href="http://fdietz.github.com/2009/09/27/introduction-to-javascript-this.html"/>
   <updated>2009-09-27T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2009/09/27/introduction-to-javascript-this</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://justin.harmonize.fm/index.php/2009/09/an-introduction-to-javascripts-this/&quot;&gt;Caffeinated Simpleton  » Blog Archive  » An Introduction to JavaScript’s “this”&lt;/a&gt;.Nice summary of using apply() and bind() to make functions work in the right context.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Adding Columns to large MySQL Tables Quickly</title>
   <link href="http://fdietz.github.com/2009/09/19/adding-columns-to-large-mysql-tables-quickly.html"/>
   <updated>2009-09-19T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2009/09/19/adding-columns-to-large-mysql-tables-quickly</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://onehub.com/past/2009/9/15/adding_columns_to_large_mysql_tables/&quot;&gt;Onehub • Adding Columns to large MySQL Tables Quickly&lt;/a&gt;.Simple Example Rails migration creates a copy of the original table and then deletes the old table while renaming the new table. Performance impact is frustratingly high - oh MySQL, &lt;em&gt;sigh&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>State of the Couch</title>
   <link href="http://fdietz.github.com/2009/09/08/state-of-the-couch.html"/>
   <updated>2009-09-08T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2009/09/08/state-of-the-couch</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://jan.prima.de/plok/archives/180-The-State-of-the-Couch-The-Invited-Talk-at-the-Erlang-Workshop-at-ICFP-in-Edinburgh-in-2009.html&quot;&gt;http://jan.prima.de/plok/archives/180-The-State-of-the-Couch-The-Invited-Talk-at-the-Erlang-Workshop-at-ICFP-in-Edinburgh-in-2009.html&lt;/a&gt;Nice summary of CouchDB’s status from Jan Lenhardt speaking at the Erlang Workshop at ICFP in Edinburgh. Especially interesting to me are his concerns for Erlang’s “Open Source-ness”. Remember how many problems the Java community had with similar problems? Or the benevolent dictatorship problems other projects have? It seems to help initially to get things rollin’ but in later stages it becomes more and more of a problem. Let’s see what’s going to happen next!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Why should I use ruby-config instead of ...</title>
   <link href="http://fdietz.github.com/2009/09/07/why-should-i-use-ruby-config-instead-of.html"/>
   <updated>2009-09-07T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2009/09/07/why-should-i-use-ruby-config-instead-of</id>
   <content type="html">&lt;p&gt;Why should I use ruby-config instead of rvm? From what I can tell after examining their website is that &lt;a href=&quot;http://github.com/wayneeseguin/rvm/tree/master&quot;&gt;rvm&lt;/a&gt; works very similar to &lt;a href=&quot;http://github.com/fdietz/ruby-config/tree/master&quot;&gt;ruby-config&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It has the same basic feature set and works quite similar by changing symlinks and environment settings. It definitely looks more polished to me and has most probably seen more usage lately due to its recent popularity. BTW, I love their website design.&lt;/p&gt;

&lt;p&gt;So, what speaks for ruby-config? It is written in Ruby and has complete test coverage. It will probably attract the more ruby-oriented developer, since it has a low entry barrier for contributing back. Personally, I refrain from maintaining large bash scripts, having them replaced several years ago with Perl scripts, which I replaced later on happily with Ruby. No pun intended ;-) And I simply enjoy working with Ruby!&lt;/p&gt;

&lt;p&gt;Healthy competition is good in my opinion. I’ll get in touch with rvm’s maintainer to see where both projects strengths are and how we can both improve our projects by learning from each other.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Very nice vector drawing using javascrip...</title>
   <link href="http://fdietz.github.com/2009/09/07/very-nice-vector-drawing-using-javascrip.html"/>
   <updated>2009-09-07T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2009/09/07/very-nice-vector-drawing-using-javascrip</id>
   <content type="html">&lt;p&gt;Very nice vector drawing using javascript and DOM. Meaning you can actually attach javascript events to DOM elements. And on top of that it works with all existing browsers, unlike Canvas. http://ajaxian.com/archives/raphael-10-rc-get-your-graphics-on&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>THE Apple Snow Leopard Review: http://ar...</title>
   <link href="http://fdietz.github.com/2009/09/06/the-apple-snow-leopard-review-httpar.html"/>
   <updated>2009-09-06T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2009/09/06/the-apple-snow-leopard-review-httpar</id>
   <content type="html">&lt;p&gt;THE Apple Snow Leopard Review: http://arstechnica.com/apple/reviews/2009/08/mac-os-x-10-6.ars. This is 24 pages!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Nice summary on the reasoning of Desktop...</title>
   <link href="http://fdietz.github.com/2009/09/06/nice-summary-on-the-reasoning-of-desktop.html"/>
   <updated>2009-09-06T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2009/09/06/nice-summary-on-the-reasoning-of-desktop</id>
   <content type="html">&lt;p&gt;Nice summary on the reasoning of Desktop vs Web Apps: http://www.kalzumeus.com/2009/09/05/desktop-aps-versus-web-apps/&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How to use Perforce's Merge Tool http:/...</title>
   <link href="http://fdietz.github.com/2009/09/06/how-to-use-perforces-merge-tool-http.html"/>
   <updated>2009-09-06T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2009/09/06/how-to-use-perforces-merge-tool-http</id>
   <content type="html">&lt;p&gt;How to use Perforce’s Merge Tool http://onestepback.org/index.cgi/Tech/Git/UsingP4MergeWithGit.red&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Gem Packaging Best Practices: http://web...</title>
   <link href="http://fdietz.github.com/2009/09/06/gem-packaging-best-practices-httpweb.html"/>
   <updated>2009-09-06T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2009/09/06/gem-packaging-best-practices-httpweb</id>
   <content type="html">&lt;p&gt;Gem Packaging Best Practices: http://weblog.rubyonrails.org/2009/9/1/gem-packaging-best-practices.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Just released ruby-config 0.7. Most inte...</title>
   <link href="http://fdietz.github.com/2009/09/05/just-released-ruby-config-0-7-most-inte.html"/>
   <updated>2009-09-05T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2009/09/05/just-released-ruby-config-0-7-most-inte</id>
   <content type="html">&lt;p&gt;Just released ruby-config 0.7. Most interestingly I changed the user interface to be command based instead of using option switches. So, instead of:&lt;code&gt;ruby-config --list-installed&lt;/code&gt; you can do a simple:&lt;code&gt;ruby-config list&lt;/code&gt;In case you missed the 0.6 release. Most noteworthy I fixed the chicken-egg problem where a newly installed Ruby runtime doesn’t have the ruby-config gem installed yet. I’ve started maintaining &lt;a href=&quot;http://github.com/fdietz/ruby-config/blob/5a1a79284b24f63ef0fc07fb966eb07eab43f25e/ReleaseNotes.md&quot;&gt;Release Notes&lt;/a&gt; to make it more convenient to follow changes in the future.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Using jeweler for ruby-config</title>
   <link href="http://fdietz.github.com/2009/08/29/using-jeweler-for-ruby-config.html"/>
   <updated>2009-08-29T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2009/08/29/using-jeweler-for-ruby-config</id>
   <content type="html">&lt;p&gt;I’ve been using &lt;a href=&quot;http://github.com/technicalpickles/jeweler/tree/master&quot;&gt;jeweler&lt;/a&gt; for ruby-config and am very surprised how smooth everything went. What I especially like about jeweler is that its absolutely a no-brainer to create gems and post them via github. And with the versioning support its a joy to push out new releases! Am probably going to move over my hoe based projects to jeweler now.So, in order to get started with jeweler you have to install the jeweler gem first:&lt;code&gt;gem install technicalpickles-jeweler&lt;/code&gt;Next to bootstrap a new project you do:&lt;code&gt;jeweler --create-repo --summary &quot;Ruby-Config&quot; ruby-config&lt;/code&gt;This will create a project skeleton with all the usual candidates. What’s left to do now is edit the Rakefile to setup the gem configuration and adding some sourcecode. Don’t forget the tests!Now, you simply create an initial version with:&lt;code&gt;rake version:write MAJOR=0 MINOR=1 PATCH=0&lt;/code&gt;which update the VERSION file in your project for you.When you do a “rake release”, jeweler will create a new gemspec file for you, commit and push the update, create a version tag and push it, too.When simply updating a minor feature, I do a “rake version:bump:minor” and afterwards a “rake release” and I’m done. Great stuff!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Have been doing some more work on ruby-c...</title>
   <link href="http://fdietz.github.com/2009/08/29/178.html"/>
   <updated>2009-08-29T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2009/08/29/178</id>
   <content type="html">&lt;p&gt;Have been doing some more work on ruby-config again. First of all there’s finally some documentation available in the &lt;a href=&quot;http://github.com/fdietz/ruby-config/blob/fc973b5e0d35113593c0912e58113e4fe5167ac9/README.md&quot;&gt;Readme&lt;/a&gt; file.&lt;/p&gt;

&lt;p&gt;Also one can now use “ruby-config –setup” which helps configuring bash’s profile to set the ruby and gem paths correctly. Again, this is done really unobtrusive.&lt;/p&gt;

&lt;p&gt;First, the task shows you what changes it wants to do, then it prompts you for a yes or no. You can always cancel and apply the changes manually.I’ve generated a new gem spec with version 0.5. So, please upgrade!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Initial commit of ruby-config now availa...</title>
   <link href="http://fdietz.github.com/2009/08/24/initial-commit-of-ruby-config-now-availa.html"/>
   <updated>2009-08-24T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2009/08/24/initial-commit-of-ruby-config-now-availa</id>
   <content type="html">&lt;p&gt;Initial commit of ruby-config now available on http://github.com/fdietz/ruby-config/tree/master.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>jwz threading on GitHub</title>
   <link href="http://fdietz.github.com/2008/08/31/jwz-threading-on-github.html"/>
   <updated>2008-08-31T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2008/08/31/jwz-threading-on-github</id>
   <content type="html">&lt;p&gt;Just posted a preliminary version of my &lt;a href=&quot;https://github.com/fdietz/jwz_threading/tree&quot;&gt;jwz threading library&lt;/a&gt; on GitHub.&lt;/p&gt;

&lt;p&gt;Took me the whole day to get a first project including complete set of Rake tests up and running. Since I’m still &lt;a href=&quot;http://www.infoq.com/news/2008/08/gems-from-rubyforge-and-github&quot;&gt;not sure if posting gems via GitHub is sufficient&lt;/a&gt;, I’ve registered a new project on &lt;a href=&quot;http://rubyforge.org/&quot;&gt;RubyForge&lt;/a&gt;. &lt;a href=&quot;http://drnicwilliams.com/2008/04/08/git-for-rubyforge-accounts/&quot;&gt;They now support Git&lt;/a&gt; too, which makes it super easy to push my changes to both “hubs”.&lt;/p&gt;

&lt;p&gt;So, you will most probably be able to download some ruby gems soon! Now, that the setup phase is done I can concentrate on cleaning up my &lt;a href=&quot;http://rspec.info/&quot;&gt;specs&lt;/a&gt; and getting the API design right.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>ActiveRecord Dynamic Finder - behind the scenes</title>
   <link href="http://fdietz.github.com/2008/08/26/activerecord-dynamic-finder-behind-the-scenes.html"/>
   <updated>2008-08-26T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2008/08/26/activerecord-dynamic-finder-behind-the-scenes</id>
   <content type="html">&lt;p&gt;Wanted to finally post more about the dynamic finders, but then found &lt;a href=&quot;http://weblog.jamisbuck.org&quot;&gt;Jamis Buck’&lt;/a&gt;s blog entries which seems to be much better anyways than anything I would have been able to scribble down in my blog.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://weblog.jamisbuck.org/2006/11/20/under-the-hood-activerecord-base-find-part-2&quot;&gt;http://weblog.jamisbuck.org/2006/11/20/under-the-hood-activerecord-base-find-part-2&lt;/a&gt;&lt;a href=&quot;http://weblog.jamisbuck.org/2006/12/1/under-the-hood-activerecord-base-find-part-3&quot;&gt;http://weblog.jamisbuck.org/2006/12/1/under-the-hood-activerecord-base-find-part-3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Symbol#to_proc and Ruby's Open Classes</title>
   <link href="http://fdietz.github.com/2008/08/21/symbolto_proc-and-rubys-open-classes.html"/>
   <updated>2008-08-21T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2008/08/21/symbolto_proc-and-rubys-open-classes</id>
   <content type="html">&lt;p&gt;Just saw an &lt;a href=&quot;http://www.infoq.com/articles/ruby-open-classes-monkeypatching&quot;&gt;article&lt;/a&gt; related to my &lt;a href=&quot;http://fdietz.wordpress.com/2008/08/12/symbolto_proc-what/&quot;&gt;last post&lt;/a&gt; about Symbol#to_proc. Very interesting read!&lt;/p&gt;

&lt;p&gt;And even more fun is this article which explains the same mechanism and &lt;a href=&quot;http://www.infoq.com/news/2008/02/to_proc-currying-ruby19&quot;&gt;currying&lt;/a&gt; on top:&lt;code&gt;proc {|x, y, z| x + y + z }.curry&lt;/code&gt; returns the equivalent of: &lt;code&gt;proc {|x| proc {|y| proc {|z| x + y + z } } }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here’s the example: &lt;code&gt;plus_five = proc { |x,y,z| x + y + z }.curry.call(2).call(3)plus_five[10]  #=&amp;gt; 15&lt;/code&gt; I’ve seen something similar in &lt;a href=&quot;http://www.scala-lang.org/&quot;&gt;Scala&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A good explanation of Scala function currying can be found in &lt;a href=&quot;http://www.codecommit.com/blog/scala/function-currying-in-scala&quot;&gt;Daniel Spiewak’s blog&lt;/a&gt;. BTW, Scala finally got a new website!&lt;/p&gt;

&lt;p&gt;And even better: Just got an E-Mail from &lt;a href=&quot;http://www.artima.com/&quot;&gt;Artima.com&lt;/a&gt; that the 4th edition of “&lt;a href=&quot;http://www.artima.com/shop/programming_in_scala&quot;&gt;Programming in Scala&lt;/a&gt;” arrived. Something to read for the weekend!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Symbol#to_proc - what?</title>
   <link href="http://fdietz.github.com/2008/08/12/symbolto_proc-what.html"/>
   <updated>2008-08-12T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2008/08/12/symbolto_proc-what</id>
   <content type="html">&lt;p&gt;While reading &lt;a href=&quot;http://www.amazon.com/Advanced-Rails-Brad-Ediger/dp/0596510322/ref=pd_bxgy_b_img_a&quot;&gt;Advanced Rails&lt;/a&gt; by Brad Ediger, I’ve stumbled upon this little helper in ActiveSupport.&lt;/p&gt;

&lt;p&gt;The to_proc method is an extension to Symbol. Let me shamelessly copy Brad’s example here:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;(1..5).map { |i| i.to_s } # =&amp;gt; [&amp;quot;1&amp;quot;, &amp;quot;2&amp;quot;, &amp;quot;3&amp;quot;, &amp;quot;4&amp;quot;, &amp;quot;5&amp;quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is already pretty nice, but now look what happens when using Symbol#to_proc:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;(1..5).map(&amp;amp;:to_s) # =&amp;gt; [&amp;quot;1&amp;quot;, &amp;quot;2&amp;quot;, &amp;quot;3&amp;quot;, &amp;quot;4&amp;quot;, &amp;quot;5&amp;quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is even shorter and does produce exactly the same output. So what happened here? The “&amp;amp;” character tells Ruby that you want to call map with “to_s” as a block argument. It will force Ruby to call the Symbol’s to_proc method. The method will create a Proc and send the symbol to the object calling the to_proc method. And this leads to iterating over the numbers specified by the range and then calling the block, passing in the numbers and converting them to strings. Okay…&lt;/p&gt;

&lt;p&gt;This is a typical example of me not being able to figure out what some code actually means and then by accident finding the explanation somewhere else. How the heck am I supposed to know where to find the documentation to such a cool extensions? I will let you know when I’m finally able to solve this mystery…&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Migrations and Foreign Key Handling</title>
   <link href="http://fdietz.github.com/2008/08/03/migrations-and-foreign-key-handling.html"/>
   <updated>2008-08-03T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2008/08/03/migrations-and-foreign-key-handling</id>
   <content type="html">&lt;p&gt;A question which came up real quick was how to add a foreign key to your migrations. In my example rails app I’m using a project with a has_many association to tasks, like this:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;class Project &amp;lt; ActiveRecord::Base  
  has_many :tasks
end

class Task &amp;lt; ActiveRecord::Base  
  belongs_to :project
end&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now I want my task database to look like the following:&lt;/p&gt;

&lt;pre&gt;
mysql&amp;gt; describe tasks;

+------------+--------------+------+-----+---------+
| Field      | Type         | Null | Key | Default |
+------------+--------------+------+-----+---------+
| id         | int(11)      | NO   | PRI | NULL    |
| title      | varchar(255) | YES  |     | NULL    |
| body       | text         | YES  |     | NULL    |
| status     | tinyint(1)   | YES  |     | NULL    |
| created_at | datetime     | YES  |     | NULL    |
| updated_at | datetime     | YES  |     | NULL    |
| project_id | int(11)      | NO   | MUL | NULL    |
+------------+--------------+------+-----+---------+

7 rows in set (0.00 sec)
&lt;/pre&gt;

&lt;p&gt;Note, that I’ve removed the last “extra” column which is usually shown by the MySQL describe command. It only shows the auto_increment for the primary key but it would have overlapped my fixed-width wordpress theme.&lt;/p&gt;

&lt;p&gt;First we have to create a new migration for adding a new column using:&lt;/p&gt;

&lt;pre&gt;
script/generate migration add_project_column
&lt;/pre&gt;

&lt;p&gt;This will generate an initial ruby file where I only added the two lines to add and delete a column.&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;class AddProjectColumn &amp;lt; ActiveRecord::Migration
  def self.up
    add_column :tasks, :project_id, :integer, :null =&amp;gt; false
  end

  def self.down
    delete_column :tasks, :project_id
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Next step is the foreign key which we can put directly in the migration, like this:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;class AddProjectColumn &amp;lt; ActiveRecord::Migration
  def self.up
    add_column :tasks, :project_id, :integer, :null =&amp;gt; false

    execute &amp;#39;ALTER TABLE tasks ADD CONSTRAINT fk_tasks_projects FOREIGN KEY ( project_id ) references projects( id )&amp;#39;
  end

  def self.down
    delete_column :tasks, :project_id
    execute &amp;#39;ALTER TABLE tasks DROP FOREIGN KEY fk_tasks_projects&amp;#39;
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note, that I’m actually executing a MySQL command to add a foreign key. So, this code most probably won’t work when used with different databases.&lt;/p&gt;

&lt;p&gt;For now this is good enough, but I should probably look into refactoring these two lines by extracting them into a migration helper class. This way it will be easier to modify in a single central place in case the database will be changed.&lt;/p&gt;

&lt;p&gt;I’m still searching for database independent foreign key management handled in migrations. So, please let me know if you find a better way to do this!&lt;/p&gt;

&lt;p&gt;Until then some more &lt;a href=&quot;http://wiki.rubyonrails.org/rails/pages/UsingMigrations&quot;&gt;readings&lt;/a&gt;…&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>ActiveRecord dynamic attribute-based finders</title>
   <link href="http://fdietz.github.com/2008/08/03/activerecord-dynamic-attribute-based-finders.html"/>
   <updated>2008-08-03T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2008/08/03/activerecord-dynamic-attribute-based-finders</id>
   <content type="html">&lt;p&gt;I’m more used to Java ORM frameworks as for example JPA and Hibernate but started to play around with ActiveRecord lately. Probably all has been said already and I will spare you the introduction and point you to some &lt;a href=&quot;http://rails-doc.org/rails/ActiveRecord/Base&quot;&gt;documentation&lt;/a&gt; instead. It took me some time to realize that there is much more than what is shown mostly in online articles, blog postings and books. &lt;/p&gt;

&lt;p&gt;Let’s start with the typical example of a book model containing articles defined with a simple has_many relation.&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;class Book &amp;lt; ActiveRecord::Base  
  has_many :chapters
end

class Chapter &amp;lt; ActiveRecord::Base  
  belongs_to :book
end&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;A typical query for all books would then look like this:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;Book.find(:all)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;and a query for all published books would be something similar to:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;Book.find(:all, :conditions =&amp;gt; [ &amp;#39;status = ?&amp;#39;, false])&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now to simplify this we can instead use the dynamic finder:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;Book.find_all_by_status(false)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Until now this is pretty straightforward, but now comes the interesting part. Imagine now that you have got a book and you want to retrieve a list of chapters:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;@book = Book.find(params[:id])
@chapters = @book.chapters.find_all_by_title(title)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Notice how one can use the same dynamic finders directly on the child association? Much easier than making a query using the book_id foreign key in the chapters table!&lt;/p&gt;

&lt;p&gt;In fact, ActiveRecord automatically makes the class-level methods of the Chapter model available directly for the associations. This also works in case you have added your own finder methods in the model.&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;class Chapter &amp;lt; ActiveRecord::Base  
  belongs_to :book  

  def self.find_finished  
    Chapter.find_all_by_status(false)  
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note, the “self” since we are adding a class-level method to Chapter. ActiveRecord will automatically make this now available in the association:&lt;/p&gt;

&lt;div&gt;
  &lt;pre data-line=&quot;&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;@chapters = @book.chapters.find_finished&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Hope you got the idea. It simply is beautiful. Next time we should probably look into what’s behind the &lt;a href=&quot;http://rails-doc.org/rails/ActiveRecord/Base/find/class&quot;&gt;dynamic finder method&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Apple Leopard Tech Talk in DÃ¼sseldorf, Germany</title>
   <link href="http://fdietz.github.com/2007/12/02/apple-leopard-tech-talk-in-dusseldorf-germany.html"/>
   <updated>2007-12-02T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2007/12/02/apple-leopard-tech-talk-in-dusseldorf-germany</id>
   <content type="html">&lt;p&gt;I’ve attended the &lt;a href=&quot;http://developer.apple.com/events/techtalks/europe.html&quot;&gt;Leopard Tech Talk&lt;/a&gt; last week in Düsseldorf. The tech talks are a great opportunity to meet other Mac developers face-to-face. Apple experts gave presentations about the latest Leopard development.  I’m not really counting me in as a Mac developer, as I was always more of a Java Swing guy. But the Mac OS X as a development platform and especially its aesthetics are quite appealing to me and were always and inspiration. The latest “official “support for Ruby, specifically the &lt;a href=&quot;http://rubyosa.rubyforge.org/&quot;&gt;RubyOSA&lt;/a&gt; and &lt;a href=&quot;http://rubycocoa.sourceforge.net/&quot;&gt;Ruby Cocoa&lt;/a&gt;, make things even more interesting.But, lets come to more interesting things. You’ve probably all read about those &lt;a href=&quot;http://www.apple.com/ical/&quot;&gt;300+ new Leopard&lt;/a&gt; features ;-) So, I’m not going to list them all here for you again. I only sum up the little niceties which you probably won’t have read that often… &lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight:bold;&quot;&gt;Resolution Independence&lt;/span&gt; was the first topic. This gets more and more important as people’s displays become bigger. I run a 20” wide screen, so no problem here yet. You can actually play around with the DPI numbers with the Quartz Debug tool, located in “Developer Applications-&amp;gt; Graphics Tools”. Most application look pretty good already, expect funnily the Finder which is still pretty much thinking in pixels here. &lt;br /&gt;Next came&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight:bold;&quot;&gt;Spotlight&lt;/span&gt;, which not only lets you search for menu items out-of-the-box, but also lets you index your whole user interfaces. Think of a completed configuration dialog where it might help to search for a specific option. If you are a Java Developer for yourself, you most probably used the search box in the Eclipse Preferences Dialog… Only thing you have to do to activate this is to tell xcode to index your user interface. Oh and by the way - it seems that Spotlight might be able to also search os servers in the future and not only on your local hard drive. Something else I didn’t know is that Spotlight is most importantly an API which can be used inside your application, too. Nice!&lt;br /&gt;Then we have of course the &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight:bold;&quot;&gt;64 bit support in Leopard&lt;/span&gt; now in much more places, even in Java 6 which is hopefully shipping soon. Nobody knows when and why it takes that long, but we’ll see. No reason yet to panic and sell my Macbook Pro &lt;em&gt;hehe&lt;/em&gt;&lt;br /&gt;The &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight:bold;&quot;&gt;Core Animation Library&lt;/span&gt; was next and this one is actually funny as it wasn’t development for Leopard specifically, but first appeared somewhere else. Rumor’s tell it was the iPhone. That reminds me that I should look into Chet Haase’s &lt;a href=&quot;http://weblogs.java.net/blog/chet/archive/2007/10/move_it.html&quot;&gt;Animation and Transition Library&lt;/a&gt;, after reading &lt;a href=&quot;http://www.amazon.com/gp/product/0132413930?ie=UTF8&amp;amp;tag=filriccli-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0132413930&quot;&gt;Filthy Rich Clients&lt;/a&gt;…&lt;br /&gt;Next was &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight:bold;&quot;&gt;Time Machine&lt;/span&gt;. I didn’t know that one can actually restore a complete system by using the Migration Assistant which comes with the Leopard Installer. Still, haven’t got the time yet to buy me a new external hard drive. Also very cool is that Spotlight is Time Machine aware and can actually show several older revisions as search result.&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight:bold;&quot;&gt; Automator&lt;/span&gt; has gotten some new flow controls and rules. Additionally, a cool virtual user recording lets you basically record macros. Lets see if this works as good as in Photoshop. Did I mention the AppleScript bridges for Python and Ruby yet?&lt;br /&gt;Then comes of course &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight:bold;&quot;&gt;Objective-C 2.0&lt;/span&gt;, which now supports Garbage Collection which the Apple engineers have been tinkering about for a dozen years but now seem to have found a way to make this work really well. Appearantly, they managed the generational (incremental) Garbage Collector to run faster then the manual retain and release. Then also very nice is the properties support, which has been discussed in length for Java, too. They use an easy dot notation as almost everyone else. Exceptions have been optimized, now the throwing is expense but the try is cheap. In older versions it was the other way around.&lt;br /&gt;Last thing I found very interesting was the Image related libraries including &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight:bold;&quot;&gt;Image I/O&lt;/span&gt; for reading and writing various file formats and metadata including RAW formats and high dynamic range support. Then &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight:bold;&quot;&gt;ImageKit&lt;/span&gt; which offers some nice of the self components to find, browse, display and edit images. And last but not least the &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight:bold;&quot;&gt;Core Imag&lt;/span&gt;e, which is actually using the GPU for all its image processing - thing OpenGL. It offers more than 100 common image processing filters, basically the usual candidates you wouldn’t want to miss in Photoshop.&lt;br /&gt;That’s it for today. On a last note, the food was excellent ;-) and the Mac crowd quite friendly with more than 200 visitors. I’m off for today, heading to Frankfurt, Germany tomorrow for the Java Tech Days! Meet you there. &lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>EasyMock IllegalStateException</title>
   <link href="http://fdietz.github.com/2007/10/05/easymock-love.html"/>
   <updated>2007-10-05T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2007/10/05/easymock-love</id>
   <content type="html">&lt;p&gt;I’ve started using &lt;a href=&quot;http://www.easymock.org/&quot;&gt;EasyMock &lt;/a&gt;last year and since then it has become an integral part of my development toolset. I especially love the Java 5 syntax and how self-explaining tests with mock objects are.But today I stumpled over my first &lt;a href=&quot;http://www.easymock.org/&quot;&gt;EasyMock &lt;/a&gt;exception which kept me pondering for an hour until I found the solution in another &lt;a href=&quot;http://marcels-javanotes.blogspot.com/2007/03/easymock-and-illegalstateexception.html&quot;&gt;blog&lt;/a&gt;.  The problem was that I was calling a method with an Array of Objects as input parameters.This caused problems because equals of the array failed as expected, but a solution was nicely explained in the docs. Simply use &lt;strong&gt;aryEq()&lt;/strong&gt; method, which does the equality check for the objects in the array. Very nice! But, then the **IllegalStateException **caught me. It complained that two matchers were found, but only one recorded. The solution is simple but not really intuitive. Once you starting using matchers you have to use matchers for all arguments of a method call.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>So Long, and Thanks for All the Fish</title>
   <link href="http://fdietz.github.com/2007/08/12/so-long-and-thanks-for-all-the-fish.html"/>
   <updated>2007-08-12T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2007/08/12/so-long-and-thanks-for-all-the-fish</id>
   <content type="html">&lt;p&gt;I’ve been working or better playing around with Columba the better half of my student years. Especially the latest release was quite difficult to manage. RL (aka real life) kept me quite busy and is also the reason why I now finally decided to stop developing on Columba.
I had so much fun meeting and working with all different kinds of people from throughout the world. Thank you all for your support!It was not quite the ride we planned. Thinking about it - we never really planned anything ;-) But, that’s probably the reason why it was so much fun!As Timo and me are now both not able to contribute any more, I hope that someone is interested in taking over from here. Java and especially Desktop Java is becoming more and more interesting. If so drop me an &lt;a href=&quot;mailto:fdietz@gmail.com&quot;&gt;email&lt;/a&gt;, please!Whoever wants to stay in touch - I’ve got some good news. I’ve reactivated my blog again! So, cu at &lt;a href=&quot;http://fdietz.wordpress.com//&quot;&gt;http://fdietz.wordpress.com&lt;/a&gt; !&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Columba Webserver Hard Drive Crash</title>
   <link href="http://fdietz.github.com/2007/02/17/columba-webserver-hard-drive-crash.html"/>
   <updated>2007-02-17T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2007/02/17/columba-webserver-hard-drive-crash</id>
   <content type="html">&lt;p&gt;Columba’s server at &lt;a href=&quot;http://columbamail.org&quot;&gt;http://columbamail.org&lt;/a&gt; is currently shutdown due to a hardware failure. The hard drive needs to be replaced. We have backups of nearly everything, so its just a matter of setting up the system again.For the time being we will keep you posted about the status here.Funnily we were planning to release a major new version this weekend. So, stay tuned!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Happy New Year!</title>
   <link href="http://fdietz.github.com/2007/01/01/happy-new-year.html"/>
   <updated>2007-01-01T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2007/01/01/happy-new-year</id>
   <content type="html">&lt;p&gt;Hope everyone out there had a “Guten Rutsch” which is a German term describing the transition from the old into the new year - need something for my headache before I can go on!Its been awhile since I wrote in my blog. First of all you might have noticed the changes in my address. Yes, its not “.de” anymore - its now “.name”. My old domain was hijacked!  You might ask how this can happen, but its pretty simple actually. I had my nice blog, website and email server running hosted by some company and wanted to move all my stuff to a new host. Thing is you have to change the domain to point to the new address. Usually the old host sends you a note that the domain is free again and with that note you can go to the new host. Very simple process! But, in my case something went wrong in the middle, I did receive the note too late, someone else already took it :-( I refuse to pay a whole lot of my money for a domain, which was only bought by that individual to make me buy it back!In case you send me emails to my mail@frederikdietz.de account, you didn’t even get any notifications or bounce messages. I guess, I lost quite a few messages from people who have most probably know idea about my problems. So, in case you send me an email and have not received an answer yet, try mail@frederikdietz.name, please.The &lt;a href=&quot;http://columbamail.org&quot;&gt;Columba&lt;/a&gt; Development &lt;a href=&quot;http://columbamail.org/drupal/?q=blog&quot;&gt;Blog&lt;/a&gt; is still on the main website. I will try to reference back and forth to not confuse people, if there’s something relevant.A lot of things happenend in the Java Realm. We have a very nice Java6 Release out of  the door, Java is going to be Open Source… Who would have thought that 5 years ago! So, there will be still quite a lot of Java related topics here, also Enterprise Java as this is my daily job, but still Swing will not be forgotten ;-)Happy New Year!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Columba development blog on main Columba website now</title>
   <link href="http://fdietz.github.com/2005/08/09/columba-development-blog-on-main-columba-website-now.html"/>
   <updated>2005-08-09T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/08/09/columba-development-blog-on-main-columba-website-now</id>
   <content type="html">&lt;p&gt;I’ve created a blog on the main Columba website. This way you guys have a single place in order to follow development.Visit at:&lt;a href=&quot;http://columbamail.org/drupal/?q=blog&quot;&gt;http://columbamail.org/drupal/?q=blog&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Update your Eclipse .project file</title>
   <link href="http://fdietz.github.com/2005/07/28/update-your-eclipse-project-files.html"/>
   <updated>2005-07-28T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/07/28/update-your-eclipse-project-files</id>
   <content type="html">&lt;p&gt;I’ve just commited an updated Eclipse &lt;strong&gt;.project&lt;/strong&gt; file to CVS.  Every plugin and necessary libraries are now added to the project build settings. This way, doing refactoring in core, the changes will automatically propagate. Or at least, they are marked as bugs ;-) This was way to much work in the past.Nevertheless, Columba will not use the class files compiled by Eclipse to load the plugins. Instead it will always use the &lt;strong&gt;plugin.jar&lt;/strong&gt;. So, you have to run “&lt;code&gt;ant plugins&lt;/code&gt;” and compile all of them to see the changes.I really like this behaviour, but we could also change it. For example, always trying to load the class files from Columba’s classpath first would be an option.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Plugins must specify src/ directory</title>
   <link href="http://fdietz.github.com/2005/07/28/plugins-must-specify-src-directory.html"/>
   <updated>2005-07-28T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/07/28/plugins-must-specify-src-directory</id>
   <content type="html">&lt;p&gt;Plugins now have to additionally specify all directories containing sourcecode. Same goes for resource files.As always all changes have to be made in &lt;strong&gt;build.properties&lt;/strong&gt;.Building of all plugins can now be started by simply calling “&lt;code&gt;ant plugins&lt;/code&gt;”.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Plugin resource loader issue fixed</title>
   <link href="http://fdietz.github.com/2005/07/28/plugin-resource-loader-issue-fixed.html"/>
   <updated>2005-07-28T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/07/28/plugin-resource-loader-issue-fixed</id>
   <content type="html">&lt;p&gt;I’ve just fixed the plugin resource loading bug. Loading of images or xml-files or whatsoever didn’t work.Again, you have to specify your plugin resource folder in build.properties. Then to load the resource  simply do a “&lt;code&gt;this.getClass().getResourceAsStream(String resource)&lt;/code&gt;“.I’ve had to change a couple of methods in core to make this work. All these methods didn’t use **InputStream **as the parameter to pass resource file content. Instead they used the path to the resource as String. This is wrong from an API user’s point of view, because the internal loader doesn’t know where these resources come from. You might even want to load resources from a webserver. So, simply using **InputStream **makes the API much more decoupled from the internal implementation.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Checking multiple IMAP folders for new messages</title>
   <link href="http://fdietz.github.com/2005/07/28/checking-multiple-imap-folders-for-new-messages.html"/>
   <updated>2005-07-28T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/07/28/checking-multiple-imap-folders-for-new-messages</id>
   <content type="html">&lt;p&gt;Enough people complained about this missing functionality! I’ve added it to our after 1.0 roadmap.We will add a new dialog similar to the IMAP Subscribe Dialog to select the folders which should be checked automatically.Still, we didn’t decide if this is going into core, or will be provided as optional plugin.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Being platform independent or what?</title>
   <link href="http://fdietz.github.com/2005/07/28/being-platform-independent-or-what.html"/>
   <updated>2005-07-28T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/07/28/being-platform-independent-or-what</id>
   <content type="html">&lt;p&gt;Just read a user’s complain about Columba following &lt;a href=&quot;http://developer.gnome.org/projects/gup/hig/&quot;&gt;Gnome User Interface Guidelines&lt;/a&gt;. These guidelines also dictact how to layout the menus. For example: the &lt;strong&gt;Preferences **menuitem should always be the last item in the **Edit **menu. At least in Gnome. On Windows it should be better placed in **Utilities&lt;/strong&gt;.I actually just saw that in Firefox. They change their menu based on the platform. So, they are more strictly following the platform they are just running on. Whereas we aim to provide the same experience for user’s on all platforms.And my feeling is that we do right so. Many of our users choose Columba, because its written in Java, and because you can use it on every operating system and even reuse one single configuration folder. These users would be really upset, if the menu layout would change everytime they switch the platform.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>ClientJava.com Columba interview</title>
   <link href="http://fdietz.github.com/2005/07/06/clientjavacom-columba-interview.html"/>
   <updated>2005-07-06T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/07/06/clientjavacom-columba-interview</id>
   <content type="html">&lt;p&gt;Read the &lt;a href=&quot;http://columba.sourceforge.net/index.php?option=com_content&amp;amp;task=view&amp;amp;id=145&amp;amp;Itemid=2&quot;&gt;news item&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Free Indian Language Software is hot</title>
   <link href="http://fdietz.github.com/2005/06/26/free-indian-language-software-is-hot.html"/>
   <updated>2005-06-26T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/06/26/free-indian-language-software-is-hot</id>
   <content type="html">&lt;p&gt;The IT ministry of India is giving away free CDs of Hindi versions of OpenOffice, Firefox, Gaim and Columba among others.&lt;a href=&quot;http://columba.sourceforge.net/index.php?option=com_content&amp;amp;task=view&amp;amp;id=143&amp;amp;Itemid=2&quot;&gt;Read more…&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Scripting Java with Beanshell</title>
   <link href="http://fdietz.github.com/2005/06/16/scripting-java-with-beanshell.html"/>
   <updated>2005-06-16T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/06/16/scripting-java-with-beanshell</id>
   <content type="html">&lt;p&gt;Another article written by Frank Sommers about &lt;a href=&quot;http://www.artima.com/lejava/articles/beanshell.html&quot;&gt;Scripting Java: The BeanShell JSR&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Columba 1.0 RC3 Released</title>
   <link href="http://fdietz.github.com/2005/06/13/columba-10-rc3-released.html"/>
   <updated>2005-06-13T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/06/13/columba-10-rc3-released</id>
   <content type="html">&lt;p&gt;Hi everyone,we finally released 1.0 RC3!I’d like to thank especially, Mark for tracking down sooo many bugs and Timo for not getting tired to fix all of them…Personally for me and I know for Timo, too, this was a very hard release. Timo just moved to Saarbrücken and is doing his Ph.D. in Computer Science, I started work at SAP Germany. We both had almost no spare time to work on Columba. Nevertheless, I’m really proud of this new release. It has a couple of very interesting new features, &lt;em&gt;lots&lt;/em&gt; of code/design cleanups and dozens of bugfixes.Last month alone, we had almost 300.000 web hits on our new website. Columba’s is a great success in India where it is shipped alongside OpenOffice and Mozilla Firefox. And still, my feeling is that its going to become even more exciting.As you might have heard already, this is our last release candidate before the final 1.0 release, which is about to happen in 4-6 weeks. So, stay tuned, help us tracking down the remaining problems and download the new version&lt;img src=&quot;http://columba.sourceforge.net/index.php?option=com_content&amp;amp;task=view&amp;amp;id=18&amp;amp;Itemid=84&quot; alt=&quot;Download&quot; /&gt;&lt;a href=&quot;http://columba.sourceforge.net/index.php?option=com_content&amp;amp;task=view&amp;amp;id=139&amp;amp;Itemid=2&quot;&gt;Release Notes&lt;/a&gt;Have fun,-Frederik&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>No - Columba is not sponsored by a company</title>
   <link href="http://fdietz.github.com/2005/06/12/no-columba-is-not-sponsored-by-a-company.html"/>
   <updated>2005-06-12T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/06/12/no-columba-is-not-sponsored-by-a-company</id>
   <content type="html">&lt;p&gt;Timo and me are currently preparing some answers for an interview on &lt;a href=&quot;http://www.clientjava.com/blog/&quot;&gt;ClientJava.com&lt;/a&gt;. This first question is “Who sponsors Columba?”.Hmmm… Nobody does. We are a group of open source developers, who like to play with new technologies, most notably Java. And we are convinced that the time is right for Java-based desktop software. We are not a company, selling some product!To circumvent such confusion in the future, I’ve added a prominent PayPal donation button on the &lt;a href=&quot;http://columba.sourceforge.net/&quot;&gt;front page&lt;/a&gt; and also a page &lt;a href=&quot;http://columba.sourceforge.net/index.php?option=com_content&amp;amp;task=view&amp;amp;id=138&amp;amp;Itemid=105&quot;&gt;dedicated to this matter&lt;/a&gt;. Additionally, checkout Timo’s and my Amazon wishlist on the page bottom :-)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Java Content Repository API</title>
   <link href="http://fdietz.github.com/2005/06/12/java-content-repository-api.html"/>
   <updated>2005-06-12T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/06/12/java-content-repository-api</id>
   <content type="html">&lt;p&gt;There’s an interesting &lt;a href=&quot;http://www.artima.com/lejava/articles/contentrepository.html&quot;&gt;article&lt;/a&gt; from Frank Sommers on artima.com_Relational and object databases lack many data management features required by modern applications, such as versioning, rich data references, inheritence, or fine-grained security. Content repositories extend databases with such additional capabilities. The Java Content Repository API (JSR 170) defines a standard to access content repositories from Java code, and promises to greatly simplify Java database programming. This article reviews the Java Content Repository API and its open-source implementation, Apache Jackrabbit, from a developer’s perspective.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Addicted to Questionable Content web comic</title>
   <link href="http://fdietz.github.com/2005/06/12/addicted-to-questionable-content-web-comic.html"/>
   <updated>2005-06-12T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/06/12/addicted-to-questionable-content-web-comic</id>
   <content type="html">&lt;p&gt;My name is Frederik, I am 27 years old, working as a software engineer and I am an addict for 3 months now:-)A must read:&lt;a href=&quot;http://www.questionablecontent.net/&quot;&gt;http://www.questionablecontent.net/&lt;/a&gt;You have been warned!Thanks Jeph for saving my Monday mornings…&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>JNLP 1.5 and Desktop Integration</title>
   <link href="http://fdietz.github.com/2005/06/08/jnlp-15-and-desktop-integration.html"/>
   <updated>2005-06-08T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/06/08/jnlp-15-and-desktop-integration</id>
   <content type="html">&lt;p&gt;Java Webstart has a couple of very interesting &lt;a href=&quot;http://weblogs.java.net/blog/stanleyh/archive/2005/06/java_deployment.html&quot;&gt;new features&lt;/a&gt;.Especially the improved desktop integration is very nice, featuring shortcuts creation, file extensions and MIME association and related content integration in the Start Menu.Additionally, on Windows Java Webstart Applications integrate in the Control Panel’s Add/Remove Programs Panel.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Font subpixel antialiasing in JDK 6.0</title>
   <link href="http://fdietz.github.com/2005/06/08/font-subpixel-antialiasing-in-jdk-60.html"/>
   <updated>2005-06-08T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/06/08/font-subpixel-antialiasing-in-jdk-60</id>
   <content type="html">&lt;p&gt;Its finally there. Take a look at some &lt;a href=&quot;http://www.javalobby.org/java/forums/t18998.html&quot;&gt;screenshots&lt;/a&gt;.And download the &lt;a href=&quot;http://www.java.net/download/jdk6/binaries/&quot;&gt;JDK 6.0 Binary Snapshot Releases&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Another JGoodies Binding Tutorial</title>
   <link href="http://fdietz.github.com/2005/06/08/another-jgoodies-binding-tutorial.html"/>
   <updated>2005-06-08T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/06/08/another-jgoodies-binding-tutorial</id>
   <content type="html">&lt;p&gt;Rob Smith has written an interesting article &lt;a href=&quot;http://www.ociweb.com/jnb/jnbJun2005.html&quot;&gt;Introduction to JGoodies Binding&lt;/a&gt;.Currently, the Binding framework is not used in Columba, instead we use a simpler approach which works nicely for easy dialogs. Usually, we have a simply model for the data and use updateComponents(boolean), method to pass the data from the model to the view and back.I definitly will take the time to evaluate the further application of Karsten’s Binding Framework. Additionally, I’d like to suggest the Validation Framework. There a &lt;a href=&quot;http://www.jgoodies.com/download/demos/validation/validationdemo.jnlp&quot;&gt;demo available&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Scripting support is in development</title>
   <link href="http://fdietz.github.com/2005/06/06/scripting-support-is-in-development.html"/>
   <updated>2005-06-06T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/06/06/scripting-support-is-in-development</id>
   <content type="html">&lt;p&gt;Celso proposed this actually and already started work on a separate branch.Guess, this feature is going to be the first new thing right after the 1.0 release.You can read the draft here:&lt;a href=&quot;http://columba.sourceforge.net/index.php?option=com_content&amp;amp;task=view&amp;amp;id=130&amp;amp;Itemid=97&quot;&gt;Scripting Engine Draft&lt;/a&gt;Feel free to join our discussion in our &lt;a href=&quot;http://columba.sourceforge.net/index.php?option=com_content&amp;amp;task=view&amp;amp;id=30&amp;amp;Itemid=50&quot;&gt;mailinglist&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>RC3 release scheduled for 12th June</title>
   <link href="http://fdietz.github.com/2005/06/06/rc3-release-scheduled-for-12th-june.html"/>
   <updated>2005-06-06T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/06/06/rc3-release-scheduled-for-12th-june</id>
   <content type="html">&lt;p&gt;Leaving asside divine intervention, the next stable Columba release is about to happen this weekend.Until then you can always play with our latest Webstart-enabled development snapshot:&lt;a href=&quot;http://columba.sf.net/webstarttest/columba.jnlp&quot;&gt;http://columba.sf.net/webstarttest/columba.jnlp&lt;/a&gt;Stay tuned!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Swing swinging</title>
   <link href="http://fdietz.github.com/2005/05/31/swing-swinging.html"/>
   <updated>2005-05-31T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/05/31/swing-swinging</id>
   <content type="html">&lt;p&gt;Santhosh Kumar has collected a couple of very neat things you can do with Swing.&lt;a href=&quot;http://jroller.com/page/santhosh/Weblog&quot;&gt;http://jroller.com/page/santhosh/Weblog&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Columba mentioned on CNet</title>
   <link href="http://fdietz.github.com/2005/05/31/columba-mentioned-on-cnet.html"/>
   <updated>2005-05-31T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/05/31/columba-mentioned-on-cnet</id>
   <content type="html">&lt;p&gt;Just a little motivation for getting the RC3 release out of the door :-)Read this:&lt;a href=&quot;http://news.com.com/Free+CDs+spread+open+source+in+India/2100-7344_3-5720008.html?tag=nl&quot;&gt;news.com.com&lt;/a&gt;and this:&lt;a href=&quot;http://news.zdnet.co.uk/software/applications/0,39020384,39199972,00.htm&quot;&gt;news.zdnet.co.uk&lt;/a&gt;and this:&lt;a href=&quot;http://linuxtoday.com/infrastructure/2005052601626OSDPPB&quot;&gt;http://linuxtoday.com/infrastructure/2005052601626OSDPPB&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Apple released Java 5</title>
   <link href="http://fdietz.github.com/2005/05/02/apple-released-java-5.html"/>
   <updated>2005-05-02T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/05/02/apple-released-java-5</id>
   <content type="html">&lt;p&gt;Unique features to this release for Mac OS X include:    * A new Cocoa Java Plugin API. The release notes say that this API can be used to embed Java into your Cocoa application.    * Support for the javax.print package    * and changes to the Java versioning mechanism    * Resolutions to a number of other issues in Hotspot, AWT, and other areas.For Columba, this means that we can finally start developing using some Java5 features!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Columba will have 3 millon Indian users</title>
   <link href="http://fdietz.github.com/2005/04/26/columba-will-have-3-millon-indian-users.html"/>
   <updated>2005-04-26T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2005/04/26/columba-will-have-3-millon-indian-users</id>
   <content type="html">&lt;p&gt;Just got a message from Raman from India.  His group is working on localizing OpenOffice, Columba and other important standard software to the Indian language. They got the IT Minister of the coutnry to put Columba on a CD amoung other tools. This CD will be distributed for free with all major Tamil magazines and newspapers and targets 3 million people.See the following links:&lt;a href=&quot;http://www.hindu.com/2005/04/16/stories/2005041600292200.htm&quot;&gt;http://www.hindu.com/2005/04/16/stories/2005041600292200.htm&lt;/a&gt;&lt;a href=&quot;http://www.tamilnation.org/digital/chennai.htm&quot;&gt;http://www.tamilnation.org/digital/chennai.htm&lt;/a&gt;&lt;a href=&quot;http://www.cdac.in/html/press/2q05/prs_rl164.asp&quot;&gt;http://www.cdac.in/html/press/2q05/prs_rl164.asp&lt;/a&gt;&lt;a href=&quot;http://www.ildc.in/GIST/htm/email.htm&quot;&gt;http://www.ildc.in/GIST/htm/email.htm&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Development starting again at April</title>
   <link href="http://fdietz.github.com/2005/03/24/development-starting-again-at-april.html"/>
   <updated>2005-03-24T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2005/03/24/development-starting-again-at-april</id>
   <content type="html">&lt;p&gt;Hi developers,I just wanted to let you know that Timo and me are going to work onColumba again in April.Almost all important tasks on our roadmap are finished. Build/Releaseprocess is much easier now. So, hopefully we can do the RC3 release soon.&lt;a href=&quot;http://columba.sourceforge.net/phpwiki/index.php/Roadmap&quot;&gt;http://columba.sourceforge.net/phpwiki/index.php/Roadmap&lt;/a&gt;Additionally, I’m tinkering around with some CMS, so that the core teamcan help us keeping our website up-to-date easily. This was way to complexin the past.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Feature Overview Wiki Page</title>
   <link href="http://fdietz.github.com/2005/01/14/feature-overview-wiki-page.html"/>
   <updated>2005-01-14T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2005/01/14/feature-overview-wiki-page</id>
   <content type="html">&lt;p&gt;I’ve started writing a &lt;a href=&quot;http://columba.sourceforge.net/phpwiki/index.php/FeatureOverview&quot;&gt;feature overview page&lt;/a&gt;. This is meant for first-time user’s who want to check quickly if Columba supports a certain functionality. Of course, this is going to be placed on our website, including some nice screenshots.Additionally, this is going to be merged with &lt;a href=&quot;http://columba.sourceforge.net/phpwiki/index.php/Why%20use%20Columba&quot;&gt;Why use Columba&lt;/a&gt;.Contributions are welcome!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Bug day results</title>
   <link href="http://fdietz.github.com/2005/01/08/bug-day-results.html"/>
   <updated>2005-01-08T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2005/01/08/bug-day-results</id>
   <content type="html">&lt;p&gt;Our bug day didn’t went out as good as expected. Sadly, we didn’t get a great number of testers. Nevertheless, we were able to solve a couple of very critical problems and finished many features.Most notably Timo integrated JDIC (&lt;a href=&quot;https://jdic.dev.java.net/&quot;&gt;https://jdic.dev.java.net/&lt;/a&gt;) for the trayicon support and opening attachments with the system’s default applications. Also, the cleaned up message viewer component is now capable of viewing attachment’s contents inline.So, all in all we are really satisfied with the work done and are much closer now to a RC3 release. We are probably doing another test release next weekend.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Fri 7th, Bug-hunting day - Everyone is invited to join us</title>
   <link href="http://fdietz.github.com/2005/01/04/fri-7th-bug-hunting-day-everyone-is-invited-to-join-us.html"/>
   <updated>2005-01-04T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2005/01/04/fri-7th-bug-hunting-day-everyone-is-invited-to-join-us</id>
   <content type="html">&lt;p&gt;Next Friday, the 7th Jan we are going to have a bug-hunting day. And we need your help to find all those bugs, annoyances and ui inconsistencies.Timo and me are going to be present in IRC, QuakeNet, in the channel #columba. Additionally, also of course in the mailinglist and the forum here (&lt;a href=&quot;http://columba.sourceforge.net/index.php?page=support&quot;&gt;http://columba.sourceforge.net/index.php?page=support&lt;/a&gt;).We are going to release another Webstart testing release and will do so several times on Friday. This way users can easily test if their reported bugs are fixed correctly without the hassle of a new installation or repetitive updates of Columba.Hope you join us!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Screenshots!!!</title>
   <link href="http://fdietz.github.com/2005/01/03/screenshots.html"/>
   <updated>2005-01-03T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2005/01/03/screenshots</id>
   <content type="html">&lt;p&gt;First of all there’s the new filter toolbar. Note, that we now offer complete search functionality inclusive full body search, etc. This is possible because we don’t rely on the Table Model anymore. Instead we use the vFolder search functionality. This way your search is automatically saved as a child vFolder of the “Search Results” folder.And then the “view attachment’s contents inline” message preview component. This is of course an optional feature. What you actually see here is a message which contains another message as attachment. This is a pretty common case, when forward a message as attachment, which is the default in most email clients today. This also works when using text or image attachments, which looks really sexy :-)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>No BerkleyDB header-cache for email component</title>
   <link href="http://fdietz.github.com/2005/01/03/no-berkleydb-header-cache-for-mai-component.html"/>
   <updated>2005-01-03T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2005/01/03/no-berkleydb-header-cache-for-mai-component</id>
   <content type="html">&lt;p&gt;I did some prototyping on the weekend and integrated BerkleyDB in Columba as general core service. Additionally, I’ve added a header-cache implementation which makes use of it.Sadly there are still a couple of smaller issues/annoyances left. I therefore dropped this &lt;a href=&quot;http://columba.sourceforge.net/phpwiki/index.php/Roadmap&quot;&gt;RoadMap&lt;/a&gt; item for now.Nevertheless, I’m finished with code cleanups and optimization of loading/saving speed.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>CVS didnât compile cleanly</title>
   <link href="http://fdietz.github.com/2005/01/03/cvs-didnt-compile-cleanly.html"/>
   <updated>2005-01-03T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2005/01/03/cvs-didnt-compile-cleanly</id>
   <content type="html">&lt;p&gt;I’ve just commited a fix for current CVS. It didn’t compile cleanly when using ant.Now, everything should compile cleanly again.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Cleanup of message preview panel finished</title>
   <link href="http://fdietz.github.com/2005/01/03/cleanup-of-message-preview-panel-finished.html"/>
   <updated>2005-01-03T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2005/01/03/cleanup-of-message-preview-panel-finished</id>
   <content type="html">&lt;p&gt;I’ve spend a whole day cleaning up the message preview component. The code is now much easier to read. Additionally, its now possible to use a composition-like approach when handling different views. So, you can view messages in messages recursively.Additionally, I’m almost finished with the “show attachments inline” viewer, which directly shows attachment contents if an appropriate viewer is available.Screenshots coming real soon!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Groovy language plugin support</title>
   <link href="http://fdietz.github.com/2004/12/31/groovy-language-plugin-support.html"/>
   <updated>2004-12-31T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/12/31/groovy-language-plugin-support</id>
   <content type="html">&lt;p&gt;I’m currently commiting the &lt;a href=&quot;http://groovy.codehaus.org&quot;&gt;Groovy&lt;/a&gt; language support. A Groovy Interpreter plugin contains all the necessary libraries. It therefore has to be installed first, on order to start writing Groovy plugins. I’ve also added a simply Hello World Groovy action plugin to demonstrate how to write plugins with Groovy.Note, that have to use the current CVS version, the plugins won’t work with RC2.Following the Groovy code which opens a swing dialog:&lt;code&gt;public class HelloWorldAction extends AbstractColumbaAction {public HelloWorldAction(FrameMediator controller) {super(controller, &quot;Hello, World!&quot;)putValue(AbstractColumbaAction.SHORT_DESCRIPTION,                                 &quot;Show me this tooltip, please&quot;)}public void actionPerformed(ActionEvent evt) {JOptionPane.showMessageDialog(null, &quot;Hello World!&quot;)}}&lt;/code&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Development after RC2 started</title>
   <link href="http://fdietz.github.com/2004/12/23/development-after-rc2-started.html"/>
   <updated>2004-12-23T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/12/23/development-after-rc2-started</id>
   <content type="html">&lt;p&gt;I’ve started collecting bugs in our &lt;a href=&quot;http://sourceforge.net/tracker/?group_id=21217&amp;amp;atid=121217&quot;&gt;bug-tracker&lt;/a&gt; specific to RC2.Our &lt;a href=&quot;http://columba.sourceforge.net/phpwiki/index.php/Roadmap&quot;&gt;roadmap&lt;/a&gt; contains the planned features which will be implemented by Timo (tstich) and me.I’ve already finished the cleanup of the message list model. Additionally, the new filter toolbar for the mail component is in CVS.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Columba 1.0 RC2 Released</title>
   <link href="http://fdietz.github.com/2004/12/20/columba-10-rc2-released.html"/>
   <updated>2004-12-20T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/12/20/columba-10-rc2-released</id>
   <content type="html">&lt;p&gt;A new stable version of Columba is now available.Release Notes:&lt;a href=&quot;http://columba.sourceforge.net/index.php?page=release&quot;&gt;http://columba.sourceforge.net/index.php?page=release&lt;/a&gt;Download:&lt;a href=&quot;http://columba.sourceforge.net/index.php?page=download_stable&quot;&gt;http://columba.sourceforge.net/index.php?page=download_stable&lt;/a&gt;Have fun,!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Mozilla compatible commandline options</title>
   <link href="http://fdietz.github.com/2004/12/04/mozilla-compatible-commandline-options.html"/>
   <updated>2004-12-04T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/12/04/mozilla-compatible-commandline-options</id>
   <content type="html">&lt;p&gt;The RC2 release contains the new Mozilla Mail compatible commandline options which makes integration with third-party software much easier. Most notably OpenOffice, which is the main reason why we changed this. See the screenshot on how to configure your OpenOffice to directly send messages with attached documents. Note, that you can either choose Option1 or Option2.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Message list discussion</title>
   <link href="http://fdietz.github.com/2004/12/03/message-list-discussion.html"/>
   <updated>2004-12-03T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/12/03/message-list-discussion</id>
   <content type="html">&lt;p&gt;Timo and me currently investigate possibilities to improve the threaded-view usability. One idea by &lt;a href=&quot;http://www.research.ibm.com/remail/threads.html&quot;&gt;ibm research&lt;/a&gt;  came to our mind.  Timo already implemented an arc-viewer control, so we would be able to play around with this thing after the RC2 release.Maybe, this way we could get rid of the current JTreeTable message-list and replace it with something more generic. The threaded-view capabilities make this old control a pain in the ass.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>What happens after the RC2 release</title>
   <link href="http://fdietz.github.com/2004/12/02/what-happens-after-the-rc2-release.html"/>
   <updated>2004-12-02T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/12/02/what-happens-after-the-rc2-release</id>
   <content type="html">&lt;p&gt;I’m currently discussing things with Timo as we come closer to a final 1.0 release of Columba. First of all there will be another release candidate RC3. This is necessary in our opinion to fix a couple of micro design issues in Columba. Note, that we focus on stuff which could further lead to more work in the future. We fix stuff for the 1.0 release, so that we can add new features afterwards easily. We will get much more attention and users after the stable 1.0 release. So, we don’t want to stop contributors adding new stuff, because of problems in our code.Our current planning includes a cleanup of the message viewer component and the message list. Both should be much more generic in our opinion.  For example the message list knows about the fact that it displays email message headers, this way we can’t reuse big parts of this swing component. Also on our list is a more generic approach of using the Filters and Filter Actions including the Filter Toolbar and Search Dialog. We would like to move some of the code in the core framework. It currently is a mail-component specific feature. But we want to reuse this code in the addressbook component, too.I’m going to kickstart further discussions in the developer mailinglist. We should really try hard to stay focused on our goals of a quick final 1.0 release.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>JDIC integration for RC2 release</title>
   <link href="http://fdietz.github.com/2004/12/02/jdic-integration-for-rc2-release.html"/>
   <updated>2004-12-02T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/12/02/jdic-integration-for-rc2-release</id>
   <content type="html">&lt;p&gt;Timo already started work on integrating the JDIC project. This currently includes trayicon support with a popup menu and lookup for an appropriate application for the specific mimetype. We also consider to use a better html-viewer instead of the built-in swing JTextPane. But we have to discuss this problem more thoroughly.We will therefore remove the jniwrapper based trayicon support.  Nevertheless, jniwrapper will be useful for us. Most probably for Message and Contact import filters and mime contents viewers using win32 applications integrated in the message viewer.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Indian Language Package contribution</title>
   <link href="http://fdietz.github.com/2004/12/01/indian-language-package-contribution.html"/>
   <updated>2004-12-01T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/12/01/indian-language-package-contribution</id>
   <content type="html">&lt;p&gt;Just got a message from the &lt;a href=&quot;http://www.ncb.ernet.in/bharateeyaoo/&quot;&gt;BharateeyaOO &lt;/a&gt; team, which are currently translating Columba for 6 Indian languages! The BharateeyaOO.o project is an initiative to bring OpenOffice.org  to India in Indian languages and somehow Columba seems to be of interest for them.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Interesting new stuff in upcoming RC2</title>
   <link href="http://fdietz.github.com/2004/11/29/interesting-new-stuff-in-upcoming-rc2.html"/>
   <updated>2004-11-29T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/11/29/interesting-new-stuff-in-upcoming-rc2</id>
   <content type="html">&lt;p&gt;New Features:- international IMAP mailbox naming using UTF-7 encoding/decoding (tstich)&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;added show next/previous message and unread message actions (fdietz)&lt;/li&gt;
  &lt;li&gt;#999257, show/hide message preview panel (fdietz)&lt;/li&gt;
  &lt;li&gt;offer three choices for viewing email headers: default, custom, all (fdietz)&lt;/li&gt;
  &lt;li&gt;#999871, “subject or sender contains” should do filtering on typing (fdietz)&lt;/li&gt;
  &lt;li&gt;show recent message count in folder tree using blue font (fdietz)&lt;/li&gt;
  &lt;li&gt;#999748, in preview panel,full emailadress should be displayed beside (fdietz)&lt;/li&gt;
  &lt;li&gt;added complete sorting and filtering support for contact JTable (fdietz)&lt;/li&gt;
  &lt;li&gt;speedup of IMAP mailbox selection and auto-checking (tstich)&lt;/li&gt;
  &lt;li&gt;set Columba to default-email client on win32 using jniwrapper (tstich)&lt;/li&gt;
  &lt;li&gt;added jpim library for vCard import/export, not complete yet (fdietz)
The #numbers are actually Feature Requests which can be found in our &lt;a href=&quot;http://sourceforge.net/tracker/?atid=371217&amp;amp;group_id=21217&amp;amp;func=browse&quot;&gt;tracker&lt;/a&gt;. We try hard to start using this tool as an official feature plan for developers.  New developers should also look into our &lt;a href=&quot;http://columba.sourceforge.net/phpwiki/index.php/UnassignedProgrammingTasks&quot;&gt;wiki&lt;/a&gt;.What’s most notably for developers is a much cleaner separation of mail and addressbook code, introducing an interface-only API. This way components can use each others functionality but can be compiled against the API safely.Another bigger change is the removal of all interfaces like MainInterface, MailInterface and AddressbookInterface. We now use singleton classes instead which are instanciated lazy on demand. This makes things a lot easier because you don’t have to manually assure that classes are instanciated in the correct order. This further simplifies writing testcases.Also, we introduced a clean concept of a container which embeeds a component. This way you can switch between mail and addressbook components  in the same JFrame.&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>RC2 test release is coming (really) real soon</title>
   <link href="http://fdietz.github.com/2004/11/27/rc2-test-release-is-coming-really-real-soon.html"/>
   <updated>2004-11-27T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/11/27/rc2-test-release-is-coming-really-real-soon</id>
   <content type="html">&lt;p&gt;I didn’t post anything for a while now. So, to just let everyone know, Timo and me are finally finished with our planned changes for RC2. We are going to upload a testing version next week and if everything works correctly the official RC2 is coming a few days afterwards…So, stay tuned!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>TaskManager Dialog added</title>
   <link href="http://fdietz.github.com/2004/06/14/taskmanager-dialog-added.html"/>
   <updated>2004-06-14T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/06/14/taskmanager-dialog-added</id>
   <content type="html">&lt;p&gt;Ok, its finally there! Beautiful isn’t it?I’m also planning to add filters to view only certain types of tasks. This could be useful, if we would like to provide a pop3 download dialog, showing the progress of all pop3 at once. This is comparable to Outlooks dialog or Evolutions progress dialog.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>RC1-test3 released</title>
   <link href="http://fdietz.github.com/2004/06/13/rc1-test3-released.html"/>
   <updated>2004-06-13T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/06/13/rc1-test3-released</id>
   <content type="html">&lt;p&gt;Ok, its finally available.Forum announcement:&lt;a href=&quot;http://http://columba.sourceforge.net/phpBB2/viewtopic.php?t=399&quot;&gt;http://columba.sourceforge.net/phpBB2/viewtopic.php?t=399&lt;/a&gt;Download at:&lt;a href=&quot;http://columba.sourceforge.net/index.php?page=download_unstable&quot;&gt;http://columba.sourceforge.net/index.php?page=download_unstable&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>better win32 mimetype handling, plugin fixes</title>
   <link href="http://fdietz.github.com/2004/06/11/better-win32-mimetype-handling-plugin-fixes.html"/>
   <updated>2004-06-11T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/06/11/better-win32-mimetype-handling-plugin-fixes</id>
   <content type="html">&lt;p&gt;Hana commited a patch which uses the win32 registry to determine mimetypes based on file extensions. New code can be found in package org.columba.nativ.mimetype.I’ve gone through the plugins and fixed compile errors. The python plugins were updated, too.The About Dialog, now also features an Acknowledgement page, listing all third-party libraries we use in Columba.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>online/offline support, more bugfixes</title>
   <link href="http://fdietz.github.com/2004/06/07/onlineoffline-support-more-bugfixes.html"/>
   <updated>2004-06-07T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/06/07/onlineoffline-support-more-bugfixes</id>
   <content type="html">&lt;p&gt;I’ve started making use of the new online/offline connection status.When downloading or sending messages, Columba automatically switches to online state. If in offline status, Columba won’t automatically check for new messages.Fixed bugs:-  #966413: mimetype viewer doesn’t remember apps-  fixed classcast exception, actions are enabled/disabled correctly again in addressbook-  group dialog didn’t show up in addressbook-  #968740, can’t choose folder in filter dialog, if treemodel is not sorted&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>profile management in CVS</title>
   <link href="http://fdietz.github.com/2004/06/06/profile-management-in-cvs.html"/>
   <updated>2004-06-06T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/06/06/profile-management-in-cvs</id>
   <content type="html">&lt;p&gt;The new profile management code is now in CVS. A sort overview can be found in our &lt;a href=&quot;http://columba.sourceforge.net/phpwiki/index.php/Profile%20Management&quot;&gt;wiki&lt;/a&gt;.Hope you like it!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>better error handling</title>
   <link href="http://fdietz.github.com/2004/06/06/better-error-handling.html"/>
   <updated>2004-06-06T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/06/06/better-error-handling</id>
   <content type="html">&lt;p&gt;I’ve added a new error dialog, called ErrorDialog. It contains a “show details” button. This is already used as general error dialog for all bugs happening in Commands, if not already catched in commands.Additionally, you can see better error messages, for things like HostNotFoundException.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Profile Management in Columba</title>
   <link href="http://fdietz.github.com/2004/06/04/profile-management-in-columba.html"/>
   <updated>2004-06-04T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/06/04/profile-management-in-columba</id>
   <content type="html">&lt;p&gt;Many users ask how to start Columba using a different configuration folder.Why not add a profile selection Dialog?This can be achieved pretty easily:- add a “profiles.xml” to the default configuration directory- if Columba is started an no profiles are specified in this file, it will just use the default location- if profiles are specified, a dialog prompts the user for a profile- if Columba is started with the –path option, the user can do this selection  automatically, without the need of the dialog.Example of the profiles.xml:The Profile Management Dialog is simply a list showing all available profiles and buttons to manage them.This way people can easily start Columba with their different configurations including usbsticks, etc.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>bugfixes and better handling of header-cache files</title>
   <link href="http://fdietz.github.com/2004/06/04/bugfixes-and-better-handling-of-header-cache-files.html"/>
   <updated>2004-06-04T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/06/04/bugfixes-and-better-handling-of-header-cache-files</id>
   <content type="html">&lt;p&gt;I never get bored of fixing bugs. Also, the header-cache should be more failsafe now.-  fixed incoming spam filter bug, using less threads leads to increased performance-  #964416 and #964415: both selection handling bugs- replace filter/filteractions combobox with menu, showing the user all available items without the need to scroll- fixed tablemodel update notification in updateGUI() from MarkFolderAsRead command&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>RC1-test3 expected new week</title>
   <link href="http://fdietz.github.com/2004/06/03/rc1-test3-expected-new-week.html"/>
   <updated>2004-06-03T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/06/03/rc1-test3-expected-new-week</id>
   <content type="html">&lt;p&gt;I’m currently planning on releasing a new development snapshot next week. Still working on a couple of bugs, ui issues.This will hopefully be the last development snapshot. This version is currently much more stable than Milestone M2 for me and I’m eager to make users upgrade. People still report the same M2 bugs over and over again, which is a waste of time for both sides.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Columba is preselected for cât magazin cd</title>
   <link href="http://fdietz.github.com/2004/06/03/columba-is-preselected-for-ct-magazin-cd.html"/>
   <updated>2004-06-03T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/06/03/columba-is-preselected-for-ct-magazin-cd</id>
   <content type="html">&lt;p&gt;Columba has been preselected by the german c’t magazin (&lt;a href=&quot;http://www.heise.de&quot;&gt;www.heise.de&lt;/a&gt;). If it gets finally selected, we’ll end up on their shareware cdrom shipped with the magazin, which includes an article about Columba.I have been trying to get their attention for one year now, but they refused to write about Columba or post news. Always made me feel silly, because we even got articles from Brasilian magazins, so why not german magazins - at last, both Timo and me are from Germany!As a c’t magazin reader/subscriber for almost 12 years, I’d love to read about my own stuff ;-)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>A more-failsafe approach of handling configuration and headercache loading/saving</title>
   <link href="http://fdietz.github.com/2004/06/03/a-more-failsafe-approach-of-handling-configuration-and-headercache-loadingsaving.html"/>
   <updated>2004-06-03T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/06/03/a-more-failsafe-approach-of-handling-configuration-and-headercache-loadingsaving</id>
   <content type="html">&lt;p&gt;We’ve had some interesting problems with corrupt configuration or headercache files, which is always annoying for users.Following the proposal to fix this particular issue. The proposed behaviour can be found in other applications pretty often, too.Saving files:- save the configuration/headercache file to “blabla.new”- if success:  - rename the old file to “blabla.old”  - rename “blabla.new” to “blabla”Loading files:- try to load “blabla”- if the file is corrupt:  - delete “blabla”  - open “blabla.old” instead (fall-back to the last working configuration)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Finally - new features</title>
   <link href="http://fdietz.github.com/2004/06/02/finally-new-features.html"/>
   <updated>2004-06-02T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/06/02/finally-new-features</id>
   <content type="html">&lt;p&gt;I’ve finally added a new feature;-)The guys from MIIK Ltd. provided us with a free version of their &lt;a href=&quot;http://www.jniwrapper.com&quot;&gt;jniwrapper library&lt;/a&gt;. This library makes it very easy for Java programs to access win32 functionality.I’ve started with adding trayicon support. So, you can see Columba’s program icon in the traybar on Windows. A context-menu giving you some options. I’m planning to add message notification and all this useful stuff later.Hopefully, we will see more use of this library. Things on my mind are for example, better usage of the windows mimetypes (Giat Hana showed interest here), access to the windows registry to automatically detect external tools, import for Outlook messages and contacts, etc.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>I hate those bugs!</title>
   <link href="http://fdietz.github.com/2004/06/01/i-hate-those-bugs.html"/>
   <updated>2004-06-01T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/06/01/i-hate-those-bugs</id>
   <content type="html">&lt;ul&gt;
  &lt;li&gt;fixed dialog parent frame reference&lt;/li&gt;
  &lt;li&gt;#952176, Folder tree should be sorted in the same way everywher&lt;/li&gt;
  &lt;li&gt;#956286, Date/time is not displayed correctly for my date settings&lt;/li&gt;
  &lt;li&gt;#926690, Foreward Message with Attachement failes&lt;/li&gt;
  &lt;li&gt;moved independent classes to core, deleted independent directory&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Again Bugfixing</title>
   <link href="http://fdietz.github.com/2004/05/27/again-bugfixing.html"/>
   <updated>2004-05-27T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/05/27/again-bugfixing</id>
   <content type="html">&lt;ul&gt;
  &lt;li&gt;#956288, recent mailfolderinfo wasn’t updated when deleting message&lt;/li&gt;
  &lt;li&gt;#958066 character encoding when editing mails is lost&lt;/li&gt;
  &lt;li&gt;#956280 Create filter based on subject throws an NPE&lt;/li&gt;
  &lt;li&gt;#958078 POP3 header-cache is saved too often&lt;/li&gt;
  &lt;li&gt;#933636 make message visible after changin sorting order&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Columba 1.0 RC1-test2 released</title>
   <link href="http://fdietz.github.com/2004/05/18/columba-10-rc1-test2-released.html"/>
   <updated>2004-05-18T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/05/18/columba-10-rc1-test2-released</id>
   <content type="html">&lt;p&gt;A new development snapshot of the upcoming 1.0 Release Candidate RC1 is now available.Forum announcement:&lt;a href=&quot;http://columba.sourceforge.net/phpBB2/viewtopic.php?t=380&quot;&gt;http://columba.sourceforge.net/phpBB2/viewtopic.php?t=380&lt;/a&gt;Download at:&lt;a href=&quot;http://columba.sourceforge.net/index.php?page=download_unstable&quot;&gt;http://columba.sourceforge.net/index.php?page=download_unstable&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>bugfixes</title>
   <link href="http://fdietz.github.com/2004/05/15/bugfixes.html"/>
   <updated>2004-05-15T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/05/15/bugfixes</id>
   <content type="html">&lt;p&gt;Erik did post a couple of interesting bugs or ui issues. Following have been fixed until now:-  #952189, added dialog to prompt user to save his work in composer, using windowClosing event here&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;#952173 changed default column width.&lt;/li&gt;
  &lt;li&gt;#951531, added decoding of headerfield&lt;/li&gt;
  &lt;li&gt;#951518, use dialog data, instead of config data to checkout supported authentication mechanism&lt;/li&gt;
  &lt;li&gt;#951522 fixed initial selection of folder selection dialog&lt;/li&gt;
  &lt;li&gt;#951528, newly created folders are now selected as expected&lt;/li&gt;
  &lt;li&gt;#952164 signature file defaults to signature.txt which should be more familiar for windows users&lt;/li&gt;
  &lt;li&gt;#952184, creating virtual folder sets parent correctly now. additionally the search dialog is opened immediately&lt;/li&gt;
  &lt;li&gt;#953239 fixed nullpointer exception when searching IMAP folders
Nevertheless, there are still a couple of more critical bugs open. So, I guess the next testing release will be a few days later than expected.&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Columba 1.0 RC1-test1 released</title>
   <link href="http://fdietz.github.com/2004/05/08/columba-10-rc1-test1-released.html"/>
   <updated>2004-05-08T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/05/08/columba-10-rc1-test1-released</id>
   <content type="html">&lt;p&gt;As promised here’s the new development snapshot. Read all the details &lt;a href=&quot;http://columba.sourceforge.net/phpBB2/viewtopic.php?t=370&quot;&gt;here.&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>JUnit tests, minor bugfixes and improved docs</title>
   <link href="http://fdietz.github.com/2004/05/07/junit-tests-minor-bugfixes-and-improved-docs.html"/>
   <updated>2004-05-07T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/05/07/junit-tests-minor-bugfixes-and-improved-docs</id>
   <content type="html">&lt;p&gt;I’ve gone through all &lt;a href=&quot;http://junit.org&quot;&gt;JUnit&lt;/a&gt; tests making sure that they compile cleanly. Also, changed the ant &amp;lt;pre&amp;gt;build.xml&amp;lt;/pre&amp;gt; script, to stop creating release packages if any tests fail. So, this is the first hurdle for releasing Columba.I’ve got Timo to fix an annoying SMTP open connection bug, caused by to strict assumptions of &lt;a href=&quot;http://columba.sourceforge.net/subprojects_ristretto.php&quot;&gt;Ristretto.&lt;/a&gt; Should now work much better with servers which aren’t strictly RFC-compliant.Forwarding messages works correctly again, too. An inputstream was accidently closed too early.Also gone through the README, COMPILE and CHANGES docs and brought them up-to-date.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Still alive and happy hacking on Columba again</title>
   <link href="http://fdietz.github.com/2004/05/06/still-alive-and-happy-hacking-on-columba-again.html"/>
   <updated>2004-05-06T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/05/06/still-alive-and-happy-hacking-on-columba-again</id>
   <content type="html">&lt;p&gt;I’ve finally finished my exams and thesis paper. So, starting with todayI’m back developing on Columba againFirst of all the roadmap at &lt;a href=&quot;http://columba.sourceforge.net/phpwiki/index.php/Roadmap&quot;&gt;http://columba.sourceforge.net/phpwiki/index.php/Roadmap&lt;/a&gt;is slightly outdated. I’m going to update the items list this week. The M3 releaseis going to happen at Mai the 30th. Furthermore, I’m planning to dotesting releases on Mai the 8th and Mai the 16th.This is the last Milestone release, which should be much more stable andpolished as compared to M2, which sadly contained a couple of veryannoying bugs. The testing releases, the new testcases and a soon to beupdated Smoketest (&lt;a href=&quot;http://columba.sourceforge.net/phpwiki/index.php/Smoketest&quot;&gt;http://columba.sourceforge.net/phpwiki/index.php/Smoketest&lt;/a&gt;)will ensure this.Last Milestone also means, last version with new major features. This isthe reason why I would like to call it v1.0 Release Candidate 1 (RC1), insteadof Milestone M3. Afterwards only RC will be released until Columba is stableenough for a final 1.0 version. This also includes user/developer documentation.My feeling is that this will happen around 2 months later.I know that many people would like to see much more new features in Columba,including changing it into a complete Groupware solution comparable to MS Outlookand other apps.Timo and me concluded a while ago that the best for Columba will be to get astable release out of the door as fast as possible. With such a stable version,it will be very easy to add additional features or even concentrate more ona complete collaboration tool. Users will most likely do without a missing feature,but they won’t use beta software.Considering the latest discussions (&lt;a href=&quot;http://www.catb.org/~esr/writings/cups-horror.html&quot;&gt;http://www.catb.org/~esr/writings/cups-horror.html)&lt;/a&gt;)about creating open-source software with good user interfaces, robustness andcomplete documentation my feeling is that this is a very reasonable plan.So, stay tuned.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Starting smallâ¦</title>
   <link href="http://fdietz.github.com/2004/05/06/starting-small.html"/>
   <updated>2004-05-06T00:00:00+02:00</updated>
   <id>http://fdietz.github.com/2004/05/06/starting-small</id>
   <content type="html">&lt;p&gt;Its raining outside, a good day to fix some smaller issues in Columba.First of all I externalized all pending strings in the Account Dialog most notably the Spam Filter Options Panel, where I also fixed the layout.Afterwards I’ve assigned every modal JDialog a correct parent JFrame, instead of just passing null. I hope this fixes the focus/window handling users noticed, as reported in the &lt;a href=&quot;http://sourceforge.net/tracker/index.php?func=detail&amp;amp;aid=866186&amp;amp;group_id=21217&amp;amp;atid=121217&quot;&gt;bugtracker&lt;/a&gt;.Additionally, all plugins now compile cleanly. Use and the buid.xml script in the plugins directory to build all plugins. This script stops execution if a build fails. The buildall.sh shell script skips compile errors, so you can make sure that all working plugins compile.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Spam fine tuning</title>
   <link href="http://fdietz.github.com/2004/03/19/spam-fine-tuning.html"/>
   <updated>2004-03-19T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/03/19/spam-fine-tuning</id>
   <content type="html">&lt;p&gt;Waking up this morning I recognized that I’ve forgotten something really important for the token database.I’m using MD5 sums to detect already learned messages. These shouldn’t be added to the token database twice or more times - just once. When marking messages as spam, which are non spam, Columba should use this MD5 sum to correct the value, if the user marks the message as non spam.You can imagine that this MD5 message list is getting hugh over time. So, I’ve added a timestamp for every MD5 sum. This way, cleaning up the token database is very easy because I can just remove old messages.Sadly, this means that the spam.db file format has changed a bit.Another new thing are handcrafted rules. This is pretty new, I’ve got it from a paper “A bayesian approach to filtering junk email” from Sahami et. al.In Columba I’ve basically eliminated the need for something like a training mode with these rules. The idea is pretty easy. The bayesian classifier enables us to add handcrafted rules, which are handled equally to other tokens. So, a rule just adds another probability additionally to the word probabilities.When starting from scratch you don’t have any words in your token database. The spam engine can’t detect spam messages until you trained it for some time. But the handcrafted rules are in place, giving you a good start to determine spam messages, until you have collected enough tokens using the message contents.One such rule would be for example checking if the Subject is of capital letters only, or if the Subject contains many whitespaces. You can think if many more rules. Spamassassin has a very big list of rules which can be found &lt;a href=&quot;http://www.spamassassin.org/tests.html&quot;&gt;here&lt;/a&gt;.   Adding new rules is very easy. Just subclass AbstractRule in org.columba.mail.spam.rules.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Silently added more filters</title>
   <link href="http://fdietz.github.com/2004/03/19/silently-added-more-filters.html"/>
   <updated>2004-03-19T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/03/19/silently-added-more-filters</id>
   <content type="html">&lt;p&gt;I’ve added two more filters. The first one is a “match all” filter, which just matches all messages. Very handy if you want to apply filters on all messages to cleanup your inbox or doing other repeating stuff.This will become even more useful, when the “automatically apply filter on new messages” option is added on a per-folder basis. This way, you can apply filters on newly added messages. This is something many people want. Just drop a message into a folder, execute the filter and process the message data.The other filter checks if the sender already exists in your addressbook. This is currently used in the spam filter anyway, to achieve an automatic whitelisting.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Spam filter integrated in Columba</title>
   <link href="http://fdietz.github.com/2004/03/16/spam-filter-integrated-in-columba.html"/>
   <updated>2004-03-16T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/03/16/spam-filter-integrated-in-columba</id>
   <content type="html">&lt;p&gt;Checking the latest CVS sources from &lt;a href=&quot;http://columba.sf.net&quot;&gt;Columba&lt;/a&gt; you will notice the new integrated spam solution. This work is based on my bachelor dissertation. An introduction can be read at &lt;a href=&quot;http://frederikdietz.de/jbayesian.php&quot;&gt;http://frederikdietz.de&lt;/a&gt;. The thesis paper can be downloaded as &lt;a href=&quot;http://frederikdietz.de/files/thesis.pdf&quot;&gt;pdf file&lt;/a&gt;.The spam filter can be enabled in the account configuration. Note, that it takes some time to train this filter. This is done in marking messages as spam or not spam.In the first few days its recommended to just mark the messages as spam. Do not make them move to trash automatically, as its high likely that you will get some false-positives. Also, use the addressbook checking option, which prevents marking messages as spam from people which are already in your addressbook.Its recommended to delete:&amp;lt;pre&amp;gt;[your-config-folder]/mail/main_toolbar.xml&amp;lt;/pre&amp;gt;This will create a new toolbar for you, with a mark message as spam button added.In my personal experience, learning around 1000 messages should be enough to make it perform well.There’s going to be some more fine-tuning needed, especially to make it perform better in the beginning - you have been warned!So, please help me test this beast ;-)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>IM Project Codename âAlturaâ</title>
   <link href="http://fdietz.github.com/2004/03/08/im-project-codename-altura.html"/>
   <updated>2004-03-08T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/03/08/im-project-codename-altura</id>
   <content type="html">&lt;p&gt;I’ve silently starting on hacking together a prototype for a jabber-based IM client. This is a pretty interesting technology I would love to see integrated in Columba in the future - meaning right after the 1.0 release this summer.Think about receiving a message by your friend. An icon would immediately show his current online/offline/busy state and you can chat right away with him.I’m still thinking about releasing this client as open-source in the future as stand-alone, but this dependents on user requests.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Folder and Filter TestSuite complete</title>
   <link href="http://fdietz.github.com/2004/03/08/folder-and-filter-testsuite-complete.html"/>
   <updated>2004-03-08T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/03/08/folder-and-filter-testsuite-complete</id>
   <content type="html">&lt;p&gt;My exams currently keep me pretty busy until next week. Right now, I’m totally into DB2 - the second lecture on database, not IBM’s database - focusing on Object-Oriented and XML databases. Not very exciting, though…So, finally some news on Columba development. After starting a bigger refactoring of the folder packages in the mail module, I’ve finished with a testsuite for all types of folders. You can add every foldertype you want and the testcases run over it showing you problems. This should become pretty handy when adding new folders, including new local mailbox formats or even database backed folder implementations.The Filter testsuite covers all plugin-based filters which are shipped by default with Columba. This is more important than you would actually think because these are also the default fallbacks, used in case a search-engine doesn’t implement all operations. So, implementors of search-engines can just start hacking on their search-engine adding more optimized operations, and falling back to the default engine in case.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>css Zen Garden: The Beauty in CSS Design</title>
   <link href="http://fdietz.github.com/2004/03/08/css-zen-garden-the-beauty-in-css-design.html"/>
   <updated>2004-03-08T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/03/08/css-zen-garden-the-beauty-in-css-design</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://www.csszengarden.com/?cssfile=/080/080.css&amp;amp;page=0&quot;&gt;css Zen Garden: The Beauty in CSS Design&lt;/a&gt;If you are interested in web design you should definitly see this page. Its a very simple page, using just CSS to totally change its look. Great. I wish more people would start using CSS more creativly.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Luxury of Ignorance: An Open-Source Horror Story</title>
   <link href="http://fdietz.github.com/2004/02/27/the-luxury-of-ignorance-an-open-source-horror-story.html"/>
   <updated>2004-02-27T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/27/the-luxury-of-ignorance-an-open-source-horror-story</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://www.catb.org/~esr/writings/cups-horror.html&quot;&gt;The Luxury of Ignorance: An Open-Source Horror Story&lt;/a&gt;This is dedicated to everyone who tried to get cups running… and failed ;-)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>NewsForge | IBM, Sun meeting to discuss open source Java</title>
   <link href="http://fdietz.github.com/2004/02/27/newsforge-ibm-sun-meeting-to-discuss-open-source-java.html"/>
   <updated>2004-02-27T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/27/newsforge-ibm-sun-meeting-to-discuss-open-source-java</id>
   <content type="html">&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;[NewsForge&lt;/td&gt;
      &lt;td&gt;IBM, Sun meeting to discuss open source Java](http://www.newsforge.com/programming/04/02/26/2253251.shtml)Meeting time.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
</content>
 </entry>
 
 <entry>
   <title>IBM urges Sun to make Java open source | CNET News.com</title>
   <link href="http://fdietz.github.com/2004/02/26/ibm-urges-sun-to-make-java-open-source-cnet-newscom.html"/>
   <updated>2004-02-26T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/26/ibm-urges-sun-to-make-java-open-source-cnet-newscom</id>
   <content type="html">&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;[IBM urges Sun to make Java open source&lt;/td&gt;
      &lt;td&gt;CNET News.com](http://news.com.com/2100-1007_3-5165427.html?tag=nefd_top)IBM is now in it, too.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
</content>
 </entry>
 
 <entry>
   <title>Linux Today - Community: Beyond an Open Source Java</title>
   <link href="http://fdietz.github.com/2004/02/25/linux-today-community-beyond-an-open-source-java.html"/>
   <updated>2004-02-25T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/25/linux-today-community-beyond-an-open-source-java</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://linuxtoday.com/developer/2004022402326OPCYDV&quot;&gt;Linux Today - Community: Beyond an Open Source Java&lt;/a&gt;This is another very interesting opinion about Java and Sun.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Columba 1.0 M2 available</title>
   <link href="http://fdietz.github.com/2004/02/24/columba-10-m2-available.html"/>
   <updated>2004-02-24T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/24/columba-10-m2-available</id>
   <content type="html">&lt;p&gt;Human-readable summary:&lt;a href=&quot;http://columba.sourceforge.net/milestone2.php&quot;&gt;New and noteworthy features in Milestone M2&lt;/a&gt;Download at:&lt;a href=&quot;http://columba.sourceforge.net/downloads_stable.php&quot;&gt;http://columba.sourceforge.net/downloads_stable.php&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Let Java Go (ESR)</title>
   <link href="http://fdietz.github.com/2004/02/17/let-java-go-esr.html"/>
   <updated>2004-02-17T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/17/let-java-go-esr</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://www.catb.org/~esr/writings/let-java-go.html&quot;&gt;Let Java Go&lt;/a&gt;Yes, please!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>J2SE 1.5 in a Nutshell</title>
   <link href="http://fdietz.github.com/2004/02/15/j2se-15-in-a-nutshell.html"/>
   <updated>2004-02-15T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/15/j2se-15-in-a-nutshell</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://java.sun.com/developer/technicalArticles/releases/j2se15/&quot;&gt;J2SE 1.5 in a Nutshell&lt;/a&gt;Very nice summary of new language features.Did you know that Columba is used by Sun’s swing team to create real-life benchmarks of JDK1.5 performance?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Fatten Up Your Java UIs with JGoodies</title>
   <link href="http://fdietz.github.com/2004/02/15/fatten-up-your-java-uis-with-jgoodies.html"/>
   <updated>2004-02-15T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/15/fatten-up-your-java-uis-with-jgoodies</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://www.devx.com/Java/Article/19934/&quot;&gt;Fatten Up Your Java UIs with JGoodies&lt;/a&gt;First article I’ve seen covering JGoodies, a layout package. Karsten Lenz, author of JGoodies actually called me and asked to look into it a while ago, suggesting to use it in Columba.Seems like its getting some more attention now. As for me, I can’t live without it anymore.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>RDF and OWL Are W3C Recommendations</title>
   <link href="http://fdietz.github.com/2004/02/12/rdf-and-owl-are-w3c-recommendations.html"/>
   <updated>2004-02-12T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/12/rdf-and-owl-are-w3c-recommendations</id>
   <content type="html">&lt;p&gt;The World Wide Web Consortium released the Resource Description Framework (RDF) and the OWL Web Ontology Language (OWL) as W3C Recommendations. RDF is used to represent information and to exchange knowledge in the Web. OWL is used to publish and share sets of terms called ontologies, supporting advanced Web search, software agents and knowledge management.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>You think Gnome is ugly?</title>
   <link href="http://fdietz.github.com/2004/02/09/you-think-gnome-is-ugly.html"/>
   <updated>2004-02-09T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/09/you-think-gnome-is-ugly</id>
   <content type="html">&lt;p&gt;After testing KDE3.2 for some days now, I’ve to admit that its getting better with every release. But, there are still too many options spreaded everywhere. KDE insists on destroying my font settings when used with Gnome apps. The overall thing looks nice, but the details really need some polishing. Anyway, heads up for a nice release. Hope they concentrate more on usability and user interface polishing.Regarding ui polishing:&lt;a href=&quot;http://actsofvolition.com/archives/2004/february/gettingtoknow/#replies&quot;&gt;http://actsofvolition.com/archives/2004/february/gettingtoknow/#replies&lt;/a&gt;&lt;a href=&quot;http://www.actsofvolition.com/archives/2001/december/windowsxprough&quot;&gt;http://www.actsofvolition.com/archives/2001/december/windowsxprough&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Mozilla Firefox 0.8 released</title>
   <link href="http://fdietz.github.com/2004/02/09/mozilla-firefox-08-released.html"/>
   <updated>2004-02-09T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/09/mozilla-firefox-08-released</id>
   <content type="html">&lt;p&gt;The standalone Mozilla Firebird browser has been renamed to Firefox and received an upgrade to version 0.8. This latest release features a new download manager, bookmarks enhancements, better support for extensions and several thousand other improvements.Release notes:&lt;a href=&quot;http://www.mozilla.org/products/firefox/releases/&quot;&gt;http://www.mozilla.org/products/firefox/releases/&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Why Sun should join Eclipse</title>
   <link href="http://fdietz.github.com/2004/02/05/why-sun-should-join-eclipse.html"/>
   <updated>2004-02-05T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/05/why-sun-should-join-eclipse</id>
   <content type="html">&lt;p&gt;Read a javalobby’s guest’s opinion:&lt;a href=&quot;http://www.javalobby.org/nl/archive/jlnews_20040203o.html&quot;&gt;http://www.javalobby.org/nl/archive/jlnews_20040203o.html&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>JDK1.5 Tiger beta released</title>
   <link href="http://fdietz.github.com/2004/02/05/jdk15-tiger-beta-released.html"/>
   <updated>2004-02-05T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/05/jdk15-tiger-beta-released</id>
   <content type="html">&lt;p&gt;You didn’t start downloading tiger, yet?&lt;a href=&quot;http://java.sun.com/j2se/1.5.0/download.jsp&quot;&gt;http://java.sun.com/j2se/1.5.0/download.jsp&lt;/a&gt;Read what’s new here:&lt;a href=&quot;http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html&quot;&gt;http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html&lt;/a&gt;Hmm… Did I mention that Columba is assisting Sun’s swing team in performance benchmarking?&lt;a href=&quot;http://columba.sourceforge.net/phpBB2/viewtopic.php?t=183&quot;&gt;http://columba.sourceforge.net/phpBB2/viewtopic.php?t=183&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Geek Code</title>
   <link href="http://fdietz.github.com/2004/02/05/geek-code.html"/>
   <updated>2004-02-05T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/05/geek-code</id>
   <content type="html">&lt;p&gt;Felix send me the complete guide to “The Code of the Geeks v3.12”:&lt;a href=&quot;http://www.geekcode.com/geek.html&quot;&gt;http://www.geekcode.com/geek.html&lt;/a&gt;From their site:So you think you are a geek, eh? The first step is to admit to yourself your geekiness. No matter what anyone says, geeks are people too; geeks have rights. So take a deep breath and announce to the world that you are a geek. Your courage will give you strength that will last you forever.How to tell the world you are a geek, you ask? Use the universal Geek code! Using this special code will allow you to let other un-closeted geeks know who you are in a simple, codified statement.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Columba M2 Release Candidate available</title>
   <link href="http://fdietz.github.com/2004/02/05/columba-m2-release-candidate-available.html"/>
   <updated>2004-02-05T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/02/05/columba-m2-release-candidate-available</id>
   <content type="html">&lt;p&gt;Please, read the full announcement here:http://columba.sourceforge.net/phpBB2/viewtopic.php?t=296This is the release candidate, before the final M2 release scheduled for next week.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Sun urges Eclipse to unify Java world</title>
   <link href="http://fdietz.github.com/2004/01/31/sun-urges-eclipse-to-unify-java-world.html"/>
   <updated>2004-01-31T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/01/31/sun-urges-eclipse-to-unify-java-world</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://news.com.com/2100-7344_3-5150868.html&quot;&gt;http://news.com.com/2100-7344_3-5150868.html&lt;/a&gt;Sounds like Eclipse is already ahead of Sun in this context and SUN is loosing ground here. Why did Sun regret to join the Eclipse Consortium? This way they could start to influence this Consortium, instead of just blaming Eclipse to divide the Java tools world.  Or they could probably think about making Netbeans use the Eclipse plugins and vice versa.&lt;strong&gt;Update:&lt;/strong&gt;Did you know that they have James Gosling again as head of their development tools divison?&lt;a href=&quot;http://news.com.com/2008-7345-5148588.html?tag=nefd_gutspro&quot;&gt;http://news.com.com/2008-7345-5148588.html?tag=nefd_gutspro&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>MikeRoweSoft settles for an Xbox</title>
   <link href="http://fdietz.github.com/2004/01/31/mikerowesoft-settles-for-an-xbox.html"/>
   <updated>2004-01-31T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/01/31/mikerowesoft-settles-for-an-xbox</id>
   <content type="html">&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;[MikeRoweSoft settles for an Xbox&lt;/td&gt;
      &lt;td&gt;CNET News.com](http://news.com.com/2100-1014_3-5147374.html?tag=st_pop)I’m currently searching through german domains, which sound like microsoft. Maybe, I can get my hands on a XBox, too!&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
</content>
 </entry>
 
 <entry>
   <title>BitlBee: IRC vs. Instant Messengers</title>
   <link href="http://fdietz.github.com/2004/01/31/bitlbee-irc-vs-instant-messengers.html"/>
   <updated>2004-01-31T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/01/31/bitlbee-irc-vs-instant-messengers</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://freshmeat.net/articles/view/1088/&quot;&gt;freshmeat.net: Project Reviews - BitlBee: IRC vs. Instant Messengers&lt;/a&gt;BitlBee apparently lets you talk with all your ICQ, Yahoo, etc. friends using you favourite IRC client. This is made possible by emulating an IRC server.Very cool idea, although it seems a bit complex to start with. Now, I’m probably able to use Jabber only for IM and IRC for all the people who still use some old proprietary IM protocol.Do you yahoo?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Mute - third generation anonymous filesharing tool</title>
   <link href="http://fdietz.github.com/2004/01/30/mute-third-generation-anonymous-filesharing-tool.html"/>
   <updated>2004-01-30T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/01/30/mute-third-generation-anonymous-filesharing-tool</id>
   <content type="html">&lt;p&gt;Found this on &lt;a href=&quot;http://www.freshmeat.net&quot;&gt;freshmeat&lt;/a&gt;:&lt;a href=&quot;http://mute-net.sourceforge.net/&quot;&gt;http://mute-net.sourceforge.net/&lt;/a&gt;MUTE File Sharing is an anonymous, decentralized search-and-download file sharing system. Several people have described MUTE as the “third generation file sharing network” (From Napster to Gnutella to MUTE, with each generation getting less centralized and more anonymous). MUTE uses algorithms inspired by ant behavior to route all messages, include file transfers, through a mesh network of neighbor connections.Does anyone actually use this? Sounds interesting though…&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Microsoft is on it again</title>
   <link href="http://fdietz.github.com/2004/01/30/microsoft-is-on-it-again.html"/>
   <updated>2004-01-30T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/01/30/microsoft-is-on-it-again</id>
   <content type="html">&lt;p&gt;Seems like Microsoft is finally doing something against the latest URL spoofing bugs in its IE browser: &lt;a href=&quot;http://support.microsoft.com/default.aspx?scid=kb;%5Bln%5D;833786&quot;&gt;http://support.microsoft.com/default.aspx?scid=kb;%5Bln%5D;833786&lt;/a&gt;.Ok, I have to admit that typing in every URL in the addressbar, instead of clicking links, firing up JScript commands to identify website spoofing and always using SSL/TLS doesn’t sound very user friendly. But hey, Microsoft was always very good in making things easy and transparent for users. So, my feeling is that we just have to trust them here…Of course, instead you can also just stop using IE and download &lt;a href=&quot;http://www.mozilla.org&quot;&gt;Mozilla&lt;/a&gt; instead. In fact, I’m writing this entry in &lt;a href=&quot;http://www.mozilla.org/products/firebird/&quot;&gt;Mozilla Firebird&lt;/a&gt;. It just took me too long to fire up my JScript to check if my blog is not spoofing me in any way.Don’t forget to send Microsoft a message making them switch their website to a secure SSL/TLS thingy. This would at least provide us with a secure connection to their knowledge-base ;-)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Madonna wannabe</title>
   <link href="http://fdietz.github.com/2004/01/30/madonna-wannabe.html"/>
   <updated>2004-01-30T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/01/30/madonna-wannabe</id>
   <content type="html">&lt;p&gt;Got this from sharereactor &lt;a href=&quot;http://movies.flabber.nl/Madonna.wannabe/&quot;&gt;Madonna wannabe&lt;/a&gt;.If this is not enough look at this girl:&lt;a href=&quot;http://http.dvlabs.com/adcritic/t/o/y/toyota-tacoma-girlfriend.mov&quot;&gt;http://http.dvlabs.com/adcritic/t/o/y/toyota-tacoma-girlfriend.mov&lt;/a&gt;Or the new britney, pink, beyonce pepsi commercial? Can’t get any more stupid&lt;img src=&quot;http://213.248.114.91/pepsi/music2004hi.asx&quot; alt=&quot;http://213.248.114.91/pepsi/music2004hi.asx&quot; /&gt;Still some time left to kill with stupid movies?&lt;a href=&quot;http://www.strenge.be/cartoons/movies/movies.htm&quot;&gt;http://www.strenge.be/cartoons/movies/movies.htm&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>IBM reinventing email</title>
   <link href="http://fdietz.github.com/2004/01/30/ibm-reinventing-email.html"/>
   <updated>2004-01-30T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/01/30/ibm-reinventing-email</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://domino.research.ibm.com/cambridge/research.nsf/pages/projects.html&quot;&gt;http://domino.research.ibm.com/cambridge/research.nsf/pages/projects.html&lt;/a&gt;Sounds like a great project. Now I only need to convince them to offer me an internship as part of this group…&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Spamming techniques</title>
   <link href="http://fdietz.github.com/2004/01/29/spamming-techniques.html"/>
   <updated>2004-01-29T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/01/29/spamming-techniques</id>
   <content type="html">&lt;p&gt;As I’m currently working on finishing my dissertation, I stumpled upon some very interesting spam message recently.I’m writing about macchiato, a spam filter library, written in Java, where I’m using a naive bayesian filter to detect spam. Its an adaptive filter which gets trained by the user’s messages. As I’m close to finish this thing, I had to draw a line where I won’t go further optimizing the library - at least as part of my dissertation. Development will of course continue - Milestone M3 of &lt;a href=&quot;http://columba.sourceforge.net&quot;&gt;Columba&lt;/a&gt; will have this integrated.Now to my recent discoveries in the faszinating world of penis enlargements, horny women and nigerian millionars…Most spam message tend to be written using HTML. Now take a look at the word Free in html:&lt;code&gt;Fr&amp;amp;lt;font size=0&amp;amp;gt;&amp;amp;amp;#38nbsp;&amp;amp;lt;/font&amp;amp;gt;ee&lt;/code&gt;Did you see the trick? &lt;strong&gt;&amp;amp;#38nbsp;&lt;/strong&gt; is actually just a space, but it has a zero font size, so it looks correct to the user, but my text tokenizer won’t recognize this word. It will recognize &lt;strong&gt;Fr&lt;/strong&gt; and &lt;strong&gt;ee&lt;/strong&gt; as independent tokens, though. Which makes no sense :-(I’ll have to further improve the message tokenizer to be more aware of html than it is currently.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Please SF, remove my stale locks!</title>
   <link href="http://fdietz.github.com/2004/01/28/please-sf-remove-my-stale-locks.html"/>
   <updated>2004-01-28T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/01/28/please-sf-remove-my-stale-locks</id>
   <content type="html">&lt;p&gt;Ok, development on Columba is non-functional for more than 2 weeks now. This is due ongoing problems with Sourceforge’s CVS servers. I surely see that they had to do some updating and I don’t want to complain about a free service, either. But they should at least try to do better on communication. I’m really starting to feel kind a dump, getting asked for a dozen times now, what OS, what CVS client, which SSH version, etc. I’m running. I really tried to help them track down the problem but they just seem to be too busy fixing their problems.I’ve proposed a move to another host, most probably to &lt;a href=&quot;http://java.net&quot;&gt;java.net&lt;/a&gt;. Note, that I’m talking about CVS only. Everything else will stay on sourceforge. We’ll see what others have to say.My feeling is that sf is just not scaling anymore that easily, given that they host about 70.000 projects - an incredible number. So, maybe its about time to change our host. Many people rely on our sources including business people. This downtime is just not acceptable for me.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Hit the penguin game</title>
   <link href="http://fdietz.github.com/2004/01/28/hit-the-penguin-game.html"/>
   <updated>2004-01-28T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/01/28/hit-the-penguin-game</id>
   <content type="html">&lt;p&gt;Salvatore pointed me to this flash game at &lt;a href=&quot;http://smallbrainer.de/media/pingbase.swf&quot;&gt;http://smallbrainer.de/media/pingbase.swf&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Dragân'drop of a JTree</title>
   <link href="http://fdietz.github.com/2004/01/28/dragndrop-of-a-jtree.html"/>
   <updated>2004-01-28T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/01/28/dragndrop-of-a-jtree</id>
   <content type="html">&lt;p&gt;Did you ever read this &lt;a href=&quot;http://www.javaworld.com/javaworld/javatips/jw-javatip114.html?&quot;&gt;article&lt;/a&gt; at &lt;a href=&quot;http://javaworld.com&quot;&gt;JavaWorld&lt;/a&gt;?Its an insanely complex thing it seems to implement drag and drop with Swing. Note, that the behaviour used in this article is the default one used in almost all Windows apps. This article is actually using the old-school DND code, using the awt package.The new jdk1.4 DND code, guess what, doesn’t support dropping of folders &lt;em&gt;between&lt;/em&gt; other folders. It just supports dropping folders &lt;em&gt;into&lt;/em&gt; other folders.Any suggestions here?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Hello world!</title>
   <link href="http://fdietz.github.com/2004/01/26/hello-world-2.html"/>
   <updated>2004-01-26T00:00:00+01:00</updated>
   <id>http://fdietz.github.com/2004/01/26/hello-world-2</id>
   <content type="html">&lt;p&gt;Welcome to WordPress. This is the first post. Edit or delete it, then start blogging!&lt;/p&gt;
</content>
 </entry>
 

</feed>