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

  <title><![CDATA[Mario Behrendt]]></title>
  <link href="http://www.mario-behrendt.de/atom.xml" rel="self"/>
  <link href="http://www.mario-behrendt.de/"/>
  <updated>2013-05-13T11:31:22+02:00</updated>
  <id>http://www.mario-behrendt.de/</id>
  <author>
    <name><![CDATA[Mario Behrendt]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Heroku versus EC2]]></title>
    <link href="http://www.mario-behrendt.de/2013/05/13/heroku-versus-ec2/"/>
    <updated>2013-05-13T11:17:00+02:00</updated>
    <id>http://www.mario-behrendt.de/2013/05/13/heroku-versus-ec2</id>
    <content type="html"><![CDATA[<p>During the last few weeks I rewrote an existing PHP application with rails 4.
Since basically everything changed (including DB schema and even DB type) a new
hosting provider was also interesting.</p>

<p>After some research <a href="http://heroku.com">Heroku</a> and <a href="http://aws.amazon.com">Amazon
EC2</a> seemed to be the best fit. During development the
app was hosted on Heroku using it&#8217;s free tier for one dyno. As always, setup was
very easy and all external services, like the database, memcached,
<a href="http://blitz.io">Blitz.io</a> and <a href="http://papertrailapp.com">Papertrail</a> were
connected in no time.</p>

<p>But there are two &#8220;problems&#8221; with heroku:</p>

<ol>
<li><p>I don&#8217;t have complete control over the server(s). This is a questionable
point since Heroku provides a platform rather than just an infrastructure, so
one might argue that not caring about the server(s) is actually a good thing.
But I rather have full control over everything.</p></li>
<li><p>The price. Heroku&#8217;s free dyno is awesome, especially for development to get
the app up and running very quickly. But once you actually need to scale, it
becomes really expensive really fast.</p></li>
</ol>


<!-- more -->


<p>The second argument is probably the most interesting one for most business
owners and quite a few people already wrote about it in the past. So it&#8217;s clear
that Heroku is more expensive than EC2, which makes sense since Heroku runs on
top of EC2. But is Heroku actually worth the money?</p>

<p>Well, if you don&#8217;t have any experience with server administration it might be.
But usually at least one team member has some knowledge. You could also hire a
dev op.</p>

<p>I did some testing and used Blitz.io to get some traffic on the servers and it
became clear very quickly that Heroku can&#8217;t cope with EC2. Even one micro
instance (free for the first year!) was faster and could cope with
more traffic than a Heroku dyno (using specific settings for nginx and
unicorn, which aren&#8217;t changable for Heroku of course). Even two dynos were still
performing worse than one micro instance in some cases, because of Heroku&#8217;s queuing, and yes
the app used <a href="http://unicorn.bogomips.org/">Unicorn</a> to have a higher
concurrency for each dyno. The EC2 instance didn&#8217;t had that issue.</p>

<p>There&#8217;s also another trap: Most people only calculate the cost of the dynos.
But all the other things you might need, like database, memcached, logging,
redis, mail and so on are pretty expensive as well! Compare Heroku&#8217;s database pricing
with <a href="http://aws.amazon.com/de/rds/">Amazon RDS</a> and make sure you compare the
storage size as well. Amazon really cuts it here!</p>

<p>Bottom line: Heroku is great for all sorts of websites, if money doesn&#8217;t matter.
Otherwise, invest the extra time for a self-made deployment (leveraging existing
tools like <a href="http://capistranorb.com/">Capistrano</a> of course), safe the money and
get a better performance. Scaling EC2 is not as easy as moving a slider like it
is for Heroku, but advanced dev ops/developers should have no problem adding a
few servers to their load balancer in a reasonable amount of time.</p>

<p>Also consider using Heroku if you have a small app that probably won&#8217;t become
huge in the far future to leverage the free hosting.</p>

<p><em>Tip</em>: Blitz.io offers free rushing tests with a concurrency of up to 250 for
Heroku apps (which isn&#8217;t free if you create a normal account there). But the
tests aren&#8217;t restricted to your actual Heroku app. So you can create a free
Heroku app, add the free Blitz.io addon and benchmark other websites as well (as
long as they&#8217;re actually your websites of course).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Alphabetical vendor list in Shopify]]></title>
    <link href="http://www.mario-behrendt.de/2013/05/13/alphabetical-vendor-list-in-shopify/"/>
    <updated>2013-05-13T10:18:00+02:00</updated>
    <id>http://www.mario-behrendt.de/2013/05/13/alphabetical-vendor-list-in-shopify</id>
    <content type="html"><![CDATA[<p>While migrating an existing a Magento shop to <a href="http://shopify.com">Shopify</a>, my
client faced me with a task: Implement a list of all vendors, grouped by their
first character.</p>

<p>Since Shopify doesn&#8217;t give you as much flexibility as Magento or other
non-hosted systems do, I had to try around a bit to come up with some working
code. It contains several things that <a href="http://wiki.shopify.com/Liquid">Liquid</a>
provides, so it might be a good starting point for other problems as well.
Here&#8217;s what I came up with in a compressed and simplified version:</p>

<!-- more -->


<h2>Short answer</h2>

<p>Code:</p>

<pre><code>{% assign chars = '' %}
{% for vendor in shop.vendors %}
    {% capture first_char %}{{ vendor | truncate: 1, '' }}{% endcapture %}

    {% if forloop.first %}
        &lt;div&gt;
            &lt;ul id="vendorlist"&gt;
    {% endif %}

    {% unless chars contains first_char %}
        {% unless forloop.first %}
               &lt;/ul&gt;
            &lt;/div&gt;
        {% endunless %}

        &lt;div class="collectionitem one-third column vendor-container"&gt;
            &lt;h2&gt;{{ first_char }}&lt;/h2&gt;
               &lt;ul&gt;

        {% capture temp %}{{ chars }}{{ first_char }}{% endcapture %}
        {% assign chars = temp %}
    {% endunless %}

    &lt;li&gt;{{ vendor | link_to_vendor }}&lt;/li&gt;
{% endfor %}
</code></pre>

<p>Result:</p>

<p><img class="center" src="http://www.mario-behrendt.de/images/posts/shopify-vendor-list.png" title="&#34;Shopify vendor list&#34;" alt="&#34;Shopify vendor list&#34;"></p>

<h2>Long version</h2>

<p>There are quite a few things going on in here, so let&#8217;s check them out. In the
first line the <code>chars</code> variable is preset which holds the used characters as a
string, nothing fancy here. On the second line the variable <code>shop.vendors</code> is used to
access an array of vendors. This was introduced lately. Not long ago you had to
create this list on your own, which was quite a pain.</p>

<p>Next we capture the first char of the current vendor&#8217;s name, which is done using
a small hack: using <code>truncate</code> to cut the word after the first char.
<em>Important</em>: Make sure to use the second parameter as well, otherwise you&#8217;ll end
up with three dots at the end, since that&#8217;s the standard setting for <code>truncate</code>.</p>

<p><code>forloop.first</code> is used to determine if the current item is the very first
vendor, which requires some additional markup. <em>Hint</em>: <code>forloop.first</code>,
<code>forloop.last</code> and <code>forloop.length</code> only work <strong>within</strong> a loop.</p>

<p>If the <code>chars</code> variable doesn&#8217;t contain the current vendor&#8217;s first char yet, a new column is
used for displaying the character in a headline. Then the char is added to the
list of used chars to look them up during the next run. Note that the character
is appended to the existing variable using a temporary variable.</p>

<p>Finally the vendor&#8217;s list item tag is displayed.</p>

<p>Even though the above code might look a bit strange if you&#8217;re used to developing
the same stuff with actual programming languages, it&#8217;s still quite readable and
understandable. Not bad for a hosted solution.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to use Trello to tackle your goals]]></title>
    <link href="http://www.mario-behrendt.de/2013/05/07/how-to-use-trello-to-tackle-your-goals/"/>
    <updated>2013-05-07T08:12:00+02:00</updated>
    <id>http://www.mario-behrendt.de/2013/05/07/how-to-use-trello-to-tackle-your-goals</id>
    <content type="html"><![CDATA[<p>We all want to tackle our goals. Regardless if it&#8217;s a new year&#8217;s resolution or
just the summer sixpack. But most of our goals aren&#8217;t met. There are several
reasons for that, but more often than not, it&#8217;s because we don&#8217;t define our
goals. Tracking goals and their progress has also a huge impact.</p>

<p>One way to do this is <a href="http://www.trello.com">Trello</a>. Trello is mostly a
project management tool, which I use in a number of client projects. But since
it&#8217;s so easy to set up a new board with an individual layout, it can be used for all
sorts of things. Tracking goals is one of them. Here&#8217;s a standard layout I use
to define my goals and keep track of my progress:</p>

<!-- more -->


<p><img class="center" src="http://www.mario-behrendt.de/images/posts/trello_goals.png" title="&#34;Trello goals layout&#34;" alt="&#34;Trello goals layout&#34;"></p>

<p>If my mind comes up with a new goal, I enter it in the very left column for the
current year. If it&#8217;s a really long term goal, I might add another column for
the upcoming year to the left. Once I accomplished something, I move it to the
current month&#8217;s column. That way I have the &#8220;good feeling&#8221; of moving a card to
done plus the progress is clearly visible, even for the last few months.</p>

<p>I use the same process for project management and other things like blogging. My
blogging setup looks like this:</p>

<p><img class="center" src="http://www.mario-behrendt.de/images/posts/trello_blog.png" title="&#34;Trello blogging layout&#34;" alt="&#34;Trello blogging layout&#34;"></p>

<p>Again, new ideas go into the <em>Ideas</em> column. Once I have the time and the muse
to write a blog post, I grab one of the cards and move it into <em>Draft</em>. The
card stays there until I&#8217;m okay with the post and actually published it. Then
it&#8217;s time to move the card into the current month&#8217;s column. Same rules apply
here. With one quick look I can see how many posts I wrote during the last few months
and if I might want to write another one (no pressure here, but I do have a
growing list of cards in the <em>Ideas</em> column).</p>

<p>After trying a lot of different bug tracking/project management/todo list
applications, Trello finally convinced me because of it&#8217;s
<a href="http://en.wikipedia.org/wiki/Kanban">Kanban</a>-Style layout bundled with the
easiness of creating boards and cards. I tried <a href="http://www.asana.com">Asana</a> for
quite some time as well, but missed the possibility to see current progress and
past progress that clearly. Bonus tip: Trello cards support
<a href="http://daringfireball.net/projects/markdown/">Markdown</a> which I use to write my
blog posts as well. So cards are actually a nice way to get an initial draft out
of your head very quickly.</p>

<p>To wrap this up, here&#8217;s another small hint: Use specific, if possible, timed
goals. Don&#8217;t create a card that says &#8220;Lose weight&#8221; without a due date. Chances
are you won&#8217;t met it. Try something like &#8220;Get down to X kg&#8221; with a due date that
is not too far in the future but still possible (rather sooner than later). If
you need two days more than the due date says, screw it, you managed it anyway!
Giving yourself too much time is just counter productive (<a href="http://en.wikipedia.org/wiki/Parkinson's_law">Parkinson&#8217;s
law</a>).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Makefile ?= syntax]]></title>
    <link href="http://www.mario-behrendt.de/2013/04/18/makefile-equals-syntax/"/>
    <updated>2013-04-18T08:35:00+02:00</updated>
    <id>http://www.mario-behrendt.de/2013/04/18/makefile-equals-syntax</id>
    <content type="html"><![CDATA[<p>Quick tip: Lately I worked with a bunch of developers who didn&#8217;t know about the
<code>?=</code> syntax in Makefiles. Let&#8217;s say you have a <code>make deploy</code> target which, by
default, deploys to staging. In order to deploy to production you could add
another target like <code>make deploy-production</code> or you use the mentioned syntax:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># Makefile</span>
</span><span class='line'>
</span><span class='line'>ENV ?<span class="o">=</span> staging
</span><span class='line'>
</span><span class='line'>deploy:
</span><span class='line'>    my_deploy_script <span class="k">$(</span>ENV<span class="k">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>So the deployment can be done like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>make deploy <span class="c"># Deploys to staging since it&#39;s the default value</span>
</span><span class='line'><span class="nv">$ ENV</span><span class="o">=</span>production make deploy <span class="c"># Deploys to production</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is useful in a variety of cases, like tests, generating docs and so on.
Maybe you can find a use case for it in your workflow. It&#8217;s not a big deal, but can
be nifty quite often.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Meetings]]></title>
    <link href="http://www.mario-behrendt.de/2013/04/16/meetings/"/>
    <updated>2013-04-16T09:36:00+02:00</updated>
    <id>http://www.mario-behrendt.de/2013/04/16/meetings</id>
    <content type="html"><![CDATA[<p>I&#8217;m trying to keep this one short but I had to write it down, cause it&#8217;s bugging
me since a long time:</p>

<p>Meetings are usually the worst thing you can do with your time! And I don&#8217;t mean
3 developers sitting around one screen to debug something. I mean those kinds of
meetings which are scheduled by project managers and CEOs.</p>

<p>Employees getting pissed and sitting around a table for x hours
doesn&#8217;t help anyone. The only definitive result is a headache. Meetings <em>can</em> be
productive and useful but almost every time there are too many people invited,
there&#8217;s no clear agenda (or there is and nobody cares), no clear time frame and
so on.  Watch Jason Fried&#8217;s talk on
<a href="http://www.ted.com/talks/jason_fried_why_work_doesn_t_happen_at_work.html">TED</a>
and you&#8217;ll know what I mean. He&#8217;s completely right. But especially project
managers and CEOs either don&#8217;t know they&#8217;re wasting time and money or they don&#8217;t
care because they think the meeting is &#8220;important&#8221;. Usually it&#8217;s not.</p>

<!-- more -->


<p>I know, a bunch of people already talked and wrote about this topic, but the
thing is: nothing changed! Still too many meetings, too much bullshit, too much
headache, too few features implemented.</p>

<p>Stupid, too long meetings have a huge impact on the company, especially on small
ones. So if you&#8217;re working in one of them and you see this pattern, try to break
it. Talk to your boss/project manager and try to solve the problem. Seriously.
If they keep setting up meetings with 10 people for 8 hours to discuss something
that actually takes 10 minutes for two of them and the remaining time is filled
with unnecessary crap - leave. I mean it. I saw so many people being pissed
sometimes the whole week, just because of this crap. It&#8217;s just no worth it.</p>

<p>If you&#8217;re a meeting scheduler, please, please think twice the next time. If it&#8217;s
really necessary, fine, everyone will notice and appreciate it. But if it&#8217;s
another worthless meeting and everyone knows about it beforehand, you&#8217;ll have a
bunch of distracted people not giving a shit about what&#8217;s said in that meeting.
Which means if you&#8217;re just skipping it, you have the same result (nothing
changed in terms of the project), but with happier, more productive team
members. Plus you probably saved your company a lot of time (e.g. 5 people having
a meeting for 4 hours: <em>20 hours of productivity gone</em>).</p>

<p>Thanks!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using a WYSIWYG editor in a Magento widget]]></title>
    <link href="http://www.mario-behrendt.de/2013/04/12/using-a-wysiwyg-editor-in-a-magento-widget/"/>
    <updated>2013-04-12T17:46:00+02:00</updated>
    <id>http://www.mario-behrendt.de/2013/04/12/using-a-wysiwyg-editor-in-a-magento-widget</id>
    <content type="html"><![CDATA[<p>The other day a client of mine faced me with an interesting request: A widget
with a WYSIWYG editor. Since we all know those tinyMCE editors from the Magento
backend (for instance when changing cms pages) it sounded pretty easy to
accomplish. As it turns out, it wasn&#8217;t. But here&#8217;s how to do
it.</p>

<!-- more -->


<h2>Initial setup</h2>

<p>Let&#8217;s see how the initial <code>widget.xml</code> file (I had to integrate this feature into
an existing extension which had a few widgets in it) was built:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;widgets&gt;</span>
</span><span class='line'>  <span class="nt">&lt;Namespace_Module_Html</span> <span class="na">type=</span><span class="s">&quot;module/widget_html&quot;</span> <span class="na">translate=</span><span class="s">&quot;name description&quot;</span> <span class="na">module=</span><span class="s">&quot;module&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;name&gt;</span>Widget name<span class="nt">&lt;/name&gt;</span>
</span><span class='line'>    <span class="nt">&lt;description&gt;</span>Widget description<span class="nt">&lt;/description&gt;</span>
</span><span class='line'>    <span class="nt">&lt;parameters&gt;</span>
</span><span class='line'>      <span class="nt">&lt;html</span> <span class="na">translate=</span><span class="s">&quot;label&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>        <span class="nt">&lt;visible&gt;</span>1<span class="nt">&lt;/visible&gt;</span>
</span><span class='line'>        <span class="nt">&lt;label&gt;</span>Input label<span class="nt">&lt;/label&gt;</span>
</span><span class='line'>        <span class="nt">&lt;description&gt;</span>Input description<span class="nt">&lt;/description&gt;</span>
</span><span class='line'>        <span class="nt">&lt;type&gt;</span>textarea<span class="nt">&lt;/type&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/html&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/parameters&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/Namespace_Module&gt;</span>
</span><span class='line'><span class="nt">&lt;/widgets&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>So far so good. As I discovered after a while, Magento loads classes from <code>lib/Varien/Data/Form/Element</code>
based on the given <code>type</code> value. A quick look into the directory reveals a file
called <code>Editor.php</code>. Job done!</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="c">&lt;!-- ... --&gt;</span>
</span><span class='line'><span class="nt">&lt;type&gt;</span>editor<span class="nt">&lt;/type&gt;</span>
</span><span class='line'><span class="c">&lt;!-- ... --&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>No errors. Good. No WYSIWYG. Bad. What happened? Unless you set the appropriate
configuration values, the tinyMCE specific parts aren&#8217;t loaded, so a plain old textarea
is rendered:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">if</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">isEnabled</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>    <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setType</span><span class="p">(</span><span class="s1">&#39;wysiwyg&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setExtType</span><span class="p">(</span><span class="s1">&#39;wysiwyg&#39;</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>    <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setType</span><span class="p">(</span><span class="s1">&#39;textarea&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setExtType</span><span class="p">(</span><span class="s1">&#39;textarea&#39;</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Okay. Fine. Let&#8217;s set the config value in the XML file and we&#8217;re good to go,
right? Nope. Unfortunately Magento doesn&#8217;t bypass all values you set in the XML
file, only a few specific ones. So not helping. After quite some digging and
searching on the web I found out that Magento doesn&#8217;t support any &#8216;complex&#8217;
field types for widgets, but it accepts a block instead of a <code>type</code> string.</p>

<p>Since there&#8217;s no documentation which block to extend or which interface to
implement I had to spent some quality time debugging the crap out of Magento
until I came up with this class:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">class</span> <span class="nc">Namespace_Module_Block_Widget_Wysiwyg</span> <span class="k">extends</span> <span class="nx">Mage_Adminhtml_Block_Widget_Form_Renderer_Fieldset_Element</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">render</span><span class="p">(</span><span class="nx">Varien_Data_Form_Element_Abstract</span> <span class="nv">$element</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="nv">$editor</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Varien_Data_Form_Element_Editor</span><span class="p">(</span><span class="nv">$element</span><span class="o">-&gt;</span><span class="na">getData</span><span class="p">());</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Prevent foreach error</span>
</span><span class='line'>        <span class="nv">$editor</span><span class="o">-&gt;</span><span class="na">getConfig</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">setPlugins</span><span class="p">(</span><span class="k">array</span><span class="p">());</span>
</span><span class='line'>
</span><span class='line'>        <span class="nv">$editor</span><span class="o">-&gt;</span><span class="na">setId</span><span class="p">(</span><span class="nv">$element</span><span class="o">-&gt;</span><span class="na">getId</span><span class="p">());</span>
</span><span class='line'>        <span class="nv">$editor</span><span class="o">-&gt;</span><span class="na">setForm</span><span class="p">(</span><span class="nv">$element</span><span class="o">-&gt;</span><span class="na">getForm</span><span class="p">());</span>
</span><span class='line'>        <span class="nv">$editor</span><span class="o">-&gt;</span><span class="na">setWysiwyg</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
</span><span class='line'>        <span class="nv">$editor</span><span class="o">-&gt;</span><span class="na">setForceLoad</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="k">parent</span><span class="o">::</span><span class="na">render</span><span class="p">(</span><span class="nv">$editor</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>To actually load this block, change the <code>type</code> node in your xml to</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;type&gt;</span>module/widget_htmleditor<span class="nt">&lt;/type&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>This should render your widget with a tinyMCE editor instance right there. Best
case it looks something like this:</p>

<p><img class="left" src="http://www.mario-behrendt.de/images/posts/magento_wysiwyg_widget.png" title="&#34;Mageno WYSIWYG widget&#34;" alt="&#34;Mageno WYSIWYG widget&#34;"></p>

<h2>Bugfixing</h2>

<p>As you already guessed as a long time Magento developer, this isn&#8217;t bug free.
Main issue was the fact that Magento is using the contents of a textarea in the
actual CMS page textarea to &#8216;render&#8217; the widget, like this:</p>

<pre><code>{{widget type="module/widget_html" text="Entered textarea content" template="module/htmlwidget.phtml" unique_id="someid"}}
</code></pre>

<p>The reason for this is that Magento&#8217;s using those parameters to reopen the
widget popup with a pre populated form when clicking the widget image twice.
Which is not a problem until you have html in your <code>text</code> parameter. Since it&#8217;s
displayed inline, the widget image is broken and you see the HTML you
entered. Plus the double click doesn&#8217;t work anymore of course.</p>

<p>My solution was to override
<code>Mage_Widget_Adminhtml_WidgetController::buildWidgetAction</code> to save the contents
as <code>base64</code> and decode it when needed. Here&#8217;s the whole solution, feel free to
save yourself a day of work and use it ;)</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">require_once</span> <span class="s1">&#39;Mage/Widget/controllers/Adminhtml/WidgetController.php&#39;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">Namespace_Module_Adminhtml_WidgetController</span> <span class="k">extends</span> <span class="nx">Mage_Widget_Adminhtml_WidgetController</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">buildWidgetAction</span><span class="p">()</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="nv">$type</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getRequest</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getPost</span><span class="p">(</span><span class="s1">&#39;widget_type&#39;</span><span class="p">);</span>
</span><span class='line'>        <span class="nv">$params</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getRequest</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getPost</span><span class="p">(</span><span class="s1">&#39;parameters&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">());</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="s1">&#39;module/widget_html&#39;</span> <span class="o">==</span> <span class="nv">$type</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="nv">$params</span><span class="p">[</span><span class="s1">&#39;text&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">base64_encode</span><span class="p">(</span><span class="nv">$params</span><span class="p">[</span><span class="s1">&#39;text&#39;</span><span class="p">]);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="nv">$asIs</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getRequest</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getPost</span><span class="p">(</span><span class="s1">&#39;as_is&#39;</span><span class="p">);</span>
</span><span class='line'>        <span class="nv">$html</span> <span class="o">=</span> <span class="nx">Mage</span><span class="o">::</span><span class="na">getSingleton</span><span class="p">(</span><span class="s1">&#39;widget/widget&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">getWidgetDeclaration</span><span class="p">(</span><span class="nv">$type</span><span class="p">,</span> <span class="nv">$params</span><span class="p">,</span> <span class="nv">$asIs</span><span class="p">);</span>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getResponse</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">setBody</span><span class="p">(</span><span class="nv">$html</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="cm">/*</span>
</span><span class='line'><span class="cm"> * This is the widgets block, so &quot;Widget_Html&quot; maps to this line in widget.xml:</span>
</span><span class='line'><span class="cm"> * &lt;Namespace_Module_Html type=&quot;module/widget_html&quot; translate=&quot;name description&quot; module=&quot;module&quot;&gt;</span>
</span><span class='line'><span class="cm"> */</span>
</span><span class='line'><span class="k">class</span> <span class="nc">Namespace_Module_Block_Widget_Html</span> <span class="k">extends</span> <span class="nx">Mage_Core_Block_Template</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">getText</span><span class="p">()</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="nb">base64_decode</span><span class="p">(</span><span class="k">parent</span><span class="o">::</span><span class="na">getText</span><span class="p">());</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>And the updated widget block</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">class</span> <span class="nc">Namespace_Module_Block_Widget_Wysiwyg</span> <span class="k">extends</span> <span class="nx">Mage_Adminhtml_Block_Widget_Form_Renderer_Fieldset_Element</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">render</span><span class="p">(</span><span class="nx">Varien_Data_Form_Element_Abstract</span> <span class="nv">$element</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="nv">$editor</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Varien_Data_Form_Element_Editor</span><span class="p">(</span><span class="nv">$element</span><span class="o">-&gt;</span><span class="na">getData</span><span class="p">());</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Prevent foreach error</span>
</span><span class='line'>        <span class="nv">$editor</span><span class="o">-&gt;</span><span class="na">getConfig</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">setPlugins</span><span class="p">(</span><span class="k">array</span><span class="p">());</span>
</span><span class='line'>
</span><span class='line'>        <span class="nv">$editor</span><span class="o">-&gt;</span><span class="na">setId</span><span class="p">(</span><span class="nv">$element</span><span class="o">-&gt;</span><span class="na">getId</span><span class="p">());</span>
</span><span class='line'>        <span class="nv">$editor</span><span class="o">-&gt;</span><span class="na">setForm</span><span class="p">(</span><span class="nv">$element</span><span class="o">-&gt;</span><span class="na">getForm</span><span class="p">());</span>
</span><span class='line'>        <span class="nv">$editor</span><span class="o">-&gt;</span><span class="na">setValue</span><span class="p">(</span><span class="nb">base64_decode</span><span class="p">(</span><span class="nv">$editor</span><span class="o">-&gt;</span><span class="na">getValue</span><span class="p">()));</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="k">parent</span><span class="o">::</span><span class="na">render</span><span class="p">(</span><span class="nv">$editor</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2>But&#8230;</h2>

<p>This only works for plain HTML. If you&#8217;re planning to enter CSS in your editor
you&#8217;ll quickly notice that tineMCE is stripping it out, though it wouldn&#8217;t break
anything because of the <code>base64</code> encode. So you either switch back to use a
plain textarea and only add the <code>base64</code> part or you find a way to override the
editors configuration to let him know to keep styles. Since I didn&#8217;t need it, I
stopped digging deeper, especially because I already spent too much time on the
lines above. I hope it helps somebody.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The myth of 'No time']]></title>
    <link href="http://www.mario-behrendt.de/2013/04/04/the-myth-of-no-time/"/>
    <updated>2013-04-04T21:15:00+02:00</updated>
    <id>http://www.mario-behrendt.de/2013/04/04/the-myth-of-no-time</id>
    <content type="html"><![CDATA[<p>Lately I heard &#8220;I just don&#8217;t have the time&#8221; quite often. And it pisses me off. Why? Because most of those people
<em>actually have the time</em> but use &#8220;no time&#8221; as an <strong>excuse</strong> for not getting things done. You see, if you have the time to
watch 2 hours TV every evening, you have the time. If you&#8217;re sitting in a bar three times a week, you have the time. If
you listening to music while checking Facebook for 30 minutes a day, you have the time. You got the idea.</p>

<p>Take 30 minutes of Facebook from Monday to Friday. That&#8217;s 2,5 hours a week or 10 hours a month. 10 hours. More than a
whole work day one could spent on Open Source, own projects, family time, learning a language, teaching something,
working out and a thousand other things that actually have a value. The value of checking your Facebook timeline 5 times
a day: Right&#8230;</p>

<!-- more -->


<p>Here&#8217;s the thing: People just don&#8217;t value their time and waste it, even though it&#8217;s the only thing we can&#8217;t buy, build,
steal or get otherwise. And yet they pretend that they don&#8217;t have &#8220;enough time&#8221;. Ever &#8220;relaxed&#8221; the whole weekend even
though you had a few things to take care of and felt really bad Sunday evening? Same thing.</p>

<p>You see I hear people telling me they want to learn X or build Y or finish Z. The most efficient way of actually make it
happen is: <strong>make it happen</strong>. I know, easier said than done, but that&#8217;s how it is. No fancy project management tool or
todo list app will help you, if you can&#8217;t get your ass off the couch. Those apps and tools can <em>improve</em> your
productivity, but for that you actually have to be productive in the first place.</p>

<p>If you have a task that&#8217;s pretty small (&lt; 1h), just do it right away. Don&#8217;t procrastinate. Just don&#8217;t. If you&#8217;re
planning a big project (multiple weeks or months) and you&#8217;re one of those people who struggle to start things, here&#8217;s
another advice: <em>make it public</em>. Tell everyone about your project and your deadline. In 9 out of 10 cases, this will
boost your will and your productivity. For instance: After my publisher announced my first book, I spent twice as much
time writing it than before because I felt the preasure and it was a good type of preasure. Try it. Make it happen.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Starting a company in Germany]]></title>
    <link href="http://www.mario-behrendt.de/2013/04/03/starting-a-company-in-germany/"/>
    <updated>2013-04-03T15:21:00+02:00</updated>
    <id>http://www.mario-behrendt.de/2013/04/03/starting-a-company-in-germany</id>
    <content type="html"><![CDATA[<p>So I started my own company during the last two months and I wanted to share my experience with you. Besides that I want
to compare the founding process in Germany with the one in the US (at least a bit).</p>

<p>If you think about starting a business in Germany, here are the steps for an UG (GmbH is basically the same) to get
it done:</p>

<!-- more -->


<ol>
<li>Ask the IHK if your desired name is actually allowed and free (email is fine)</li>
<li>Make an appointment with the notary and bring the completed form he (hopefully) gave you beforehand</li>
<li>Make an appointment with your bank of choice (I chose Deutsche Bank since they&#8217;re pretty cheap), if possible directly after
the notary appointment. Make sure to bring the stuff the notary gave you</li>
<li>Go to the appointments</li>
<li>Transfer the capital to your newly created bank account, once you got the account number</li>
<li>Pay the notary from your private account and tell him you transfered the capital</li>
<li>The notary will do his job now and send everything to the right places</li>
<li>Wait for a letter from the district court about your entry</li>
<li>Go to the Office of Trade and register your company there (bring the notary stuff, the letter and your passport)</li>
<li>Take the stuff they gave you and the rest and make an another appointment with the bank to change the account holder</li>
<li>Wait for a letter from the tax office, fill out the form and send it back</li>
<li>Wait for the response so you get your tax number</li>
<li>Done, make some money!</li>
</ol>


<p>Appendix: Don&#8217;t forget to get a health insurance! This can be done any time during the above process, the earlier the
better.</p>

<h2>Explanation</h2>

<p>Now let&#8217;s explain this in more detail. Steps 1-8 should be pretty straight forward. For step 1 find an email address on
the IHK&#8217;s website and your mail will find the right employee. Of course you should stop the process with step 1 if they
tell you the name isn&#8217;t available for whatever reason. Step 9 is pretty easy as well, since the only thing you have to do
is to wait for the letter, but besides the official letter you&#8217;ll receive quite a few invoices from different companies
who are charging you for the court entry. <em>Do not pay them</em>. There&#8217;s only one official invoice and it&#8217;s from the actual
court and usualy way cheaper than the others (I&#8217;ll talk about the costs later).</p>

<p>Step 10 might seem strange to you because of the phrase &#8220;change the account holder&#8221;. What that actually means is this:
When the notary registered your company (in this case the UG), he actually <em>requested</em> a registration. Until that is
done (step 8) your company isn&#8217;t a UG, it has the appendix &#8220;i.G.&#8221; which stand for &#8220;in Gründung&#8221; (basically &#8220;in the
process of founding&#8221;). So your bank account&#8217;s holder isn&#8217;t AwesomeCo UG, it&#8217;s actually AwesomeCo i.G. You might think
that&#8217;s not a big deal, but be aware: Until your company is actually a UG or GmbH, you&#8217;re <strong>liable as a private person</strong>!
So even though you <em>could</em> use the company as of step 8 for business, you shouldn&#8217;t!</p>

<p>Steps 11 to 13 should be straight forward again. The tax office form isn&#8217;t that hard, if you really need to, get
yourself a tax consultant. Btw: I did the whole founding process without a tax consultant and I still don&#8217;t have one.</p>

<h2>Costs</h2>

<p>This was pretty hard to figure out beforehand since I found wide ranges of numbers on the web. So here&#8217;s what I paid,
notice that the costs differ slightly from state to state in Germany:</p>

<ul>
<li>Notary: 104,13 €</li>
<li>Court: 151,00 €</li>
<li>Office of Trade: 26,00 €</li>
</ul>


<p>So overall I spent around 280 € for founding my company.</p>

<h2>Time</h2>

<p>This is what actually pissed me off. If you follow Hackernews or tweets/feeds in the business sector, it seems like it
takes almost no time to start a business in the US. Well, not in Germany. The above mentioned process took me almost
3 months to actually get everything together (full disclosure: Actually a bit more than 2 months to file invoices in
Germany only and almost 3 months to be able to file invoices outside Germany as well). And I&#8217;m talking about the UG
here, which can be compared to the &#8220;Inc.&#8221; in the US.</p>

<h2>Capital</h2>

<p>As mentioned above, UG is basically like the Germany version of &#8220;Inc.&#8221;, so you <em>could</em> start your business with 1 €.
Since that doesn&#8217;t make sense (you can&#8217;t even pay the notary), you should invest at least 1.000 €, otherwise you have to
file insolvency right away. If you&#8217;re willing to invest 12.500 € (with a liability of 25.000 €), you can start a GmbH.
Same process but the costs for the notary are way higher.</p>

<h2>The name</h2>

<p>Well well&#8230; Let&#8217;s say you want to call your company Awesomly and the IHK is fine with that. If you actually want to use
your company&#8217;s name somewhere (imprint, mail footer, etc.) it&#8217;s not just &#8220;Awesomly&#8221;. This is against the law. In Germany
you have to use the full name, or at least an official shortcut. Now if you&#8217;re from the US and used to &#8220;Awesomly Inc.&#8221;,
here you go, this is the shortest possible version:</p>

<p><strong>Awesomly UG (haftungsbeschränkt)</strong></p>

<p>Neat huh? If you&#8217;re willing to invest the mentioned 12.500 €, you can use &#8220;Awesomly GmbH&#8221; but the downside of that is
that you have a liability of 25.000 €. So if something bad happens, you have to pay the remaining 12.500 € as well. Not
so for the UG. If you have 2.000 € in your account, that&#8217;s it. Furthermore you actually have your money sitting on the
company&#8217;s account. Since my company is 80% agency and 20% own projects it doesn&#8217;t make sense to have a lot of money on
the account sitting there, almost unreachable and earning between 0 and 0.x% interest. I rather have my money on my
private account, freely available, with a lot more interest. That&#8217;s the main reason I chose UG over GmbH.</p>

<h2>Wrap up</h2>

<p>It&#8217;s actually not that hard to start a business in Germany but you need to know how. I spent quite some time before I
started the whole process to get everything straight. And since the information on the web was distributed across a lot of
websites, it wasn&#8217;t really easy to get the whole picture. Hopefully I made that with this post.</p>

<p>If you&#8217;re planning to start a business or already in the process of doing so, I wish you all the best, good luck and happy
customers!</p>

<p>If you have questions, suggestions or want to share your experience, get in touch on <a href="http://www.twitter.com/MarioBehrendt">Twitter</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A note on how to write good Magento extensions]]></title>
    <link href="http://www.mario-behrendt.de/2013/03/14/a-note-on-how-to-write-good-magento-extensions/"/>
    <updated>2013-03-14T11:53:00+01:00</updated>
    <id>http://www.mario-behrendt.de/2013/03/14/a-note-on-how-to-write-good-magento-extensions</id>
    <content type="html"><![CDATA[<p>During the last two years I came across quite a lot of Magento extensions. I saw good ones, bad ones and ones I don&#8217;t
want to talk about anymore. Don&#8217;t get me wrong - this is not a post about bad developers or something like that. No.
I just want to list a few things you should double check the next time you release Magento extensions or create
extensions within a shop.</p>

<h2>Do not, I repeat, do not introduce core hacks</h2>

<p>This might seem like a clear matter, but in fact there are still too many core hacks out there (usually in whole shop
projects, not extensions). Even though include hacks are not the same as core hacks, I kinda hate them both. Magento
gives you a huge interface to override and extend classes, methods, layouts and templates. Use it.</p>

<h2>Consistent style</h2>

<p>Again, a completely obvious point, right? Yet, I saw extensions from well known Magento agencies which looked like 5
people who never spoke to each other and don&#8217;t like each other worked on it. Of course, sometimes you have to add a
quick fix and you might not double check the style. But having camelCase and snake_case methods in the same class just
doesn&#8217;t look good. Especially since Magento uses the Zend standard, which you should do too. Also commented methods,
sometimes more than 100 lines long are a no go. Speaking of 100 lines of code. Try to shrink your methods down to 50 lines
tops, rather less than 25. I know, this is pretty hard in PHP and Magento sometimes, but try.</p>

<!-- more -->


<h2>Do not comment out child block</h2>

<p>One thing I found pretty annoying when taking over projects with template overrides was stuff like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span> <span class="c1">// echo $this-&gt;getChildHtml(&#39;child_name&#39;); ?&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is a really bad idea. If you don&#8217;t want to have certain blocks in a template, remove the code from the template
<em>and</em> the layout xml file. Everything else is just confusing and time wasting.</p>

<h2>Document your code and/or offer a PDF documentation</h2>

<p>I&#8217;m not a big fan of doc blocks per se, since most people just add them because they have to but then fill them with barely
useful information. Yet, feel free to add them to your methods to explain what they&#8217;re doing. But the actual power
lies in inline comments. Especially <code>if</code> conditions tend to be introduced without further explanation. As a extension
user I then try to figure out why the heck the developer added this if and how I should handle it. It&#8217;s just one
line and makes your code more maintainable for both yourself and your customers.</p>

<p>Sometimes extensions become too big to just rely on code documentation. I&#8217;m not talking about customer documentation
here (which should always be available either on your homepage or via PDF) - I&#8217;m talking about a documentation on how
to extend your extension. To give you a concrete example: A few days ago I was working on a shop and had to extend a
rather huge extension. After digging into the code for hours, me and my colleague still had no clue at all how this
thing worked, where to start and what to do. This was actually the first time in my developer life I had such a
moment. Then I went out to check for some information on Google. Nothing. You got the point&#8230;</p>

<h2>Good architecture and API</h2>

<p>If you&#8217;re building one of the bigger extensions, think about the extension&#8217;s structure and API. Unfortunately most big
extensions lack this. It&#8217;s hard to determine what&#8217;s going on because of the weird structure and it&#8217;s hard (read:
complicated) to actually interfere with the extension because method calls accept/require strange parameters or methods
consist of 300 lines and do 10 things at once.</p>

<h2>Test your code</h2>

<p>This one is pretty hard since unit testing in Magento is a pain. But it&#8217;s still better the go through that pain and
have a well tested code base than releasing untested extensions (maybe even paid ones?). Testing is not something
fancy you can use if you&#8217;re one of those early adaptors. No. It&#8217;s mandatory, improves stability and maintainability
and also helps you with a few of the above mentions points like structure and API. The worse your API the harder
it&#8217;ll be for you to test it.</p>

<h2>Wrap up</h2>

<p>I&#8217;m sure not everyone/every agency has the time/the customers to keep all those things in mind, even though they should.
So at least pick one for your next project and try hard to make it happen. Seriously. Everyone will benefit from it,
there a no losers!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The power of one exclamation mark]]></title>
    <link href="http://www.mario-behrendt.de/2013/03/14/the-power-of-one-exclamation-mark/"/>
    <updated>2013-03-14T11:35:00+01:00</updated>
    <id>http://www.mario-behrendt.de/2013/03/14/the-power-of-one-exclamation-mark</id>
    <content type="html"><![CDATA[<p>Today I want to introduce you to an effect I call &#8220;the HTML whitespace/exclamation mark principle&#8221;. A lot of people
tend to use two or more exclamation marks in their sentences. So let me explain the mentioned principle:</p>

<p>Assume you write HTML code. If you enter a single whitespace what will your browser render? Right, a single
whitespace. Now write a second whitespace, right behind the first one and reload. Aha! Still one. Even if you <em>could</em>
write two exclamation marks and the browser would render two, the bottom line is the same: <strong>It doesn&#8217;t make a
difference</strong>.</p>

<p>You got the point write? So stop writing two, three or even more exclamation marks in a row. Whoever will read your
text will not tread it more serious just because you feel like you need to add more than one to express yourself.
Actually
sometimes it&#8217;s the opposite. In my experience nearly 50% of the people receiving orders from their bosses via text
react rather pissed when the order comes with multiple exclamation marks. By the way: I&#8217;m one of them ;)</p>

<p>PS: Same goes for question marks and three dots in every sentence.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Mongoose Snippets]]></title>
    <link href="http://www.mario-behrendt.de/2012/11/27/mongoose-snippets/"/>
    <updated>2012-11-27T13:54:00+01:00</updated>
    <id>http://www.mario-behrendt.de/2012/11/27/mongoose-snippets</id>
    <content type="html"><![CDATA[<p>Ich arbeite nun schon seit einiger Zeit in mehreren Projekten mit dem ODM <a href="http://mongoosejs.com">Mongoose</a> und habe mitterweile eine
kleine Snippet-Liste mit undokumentierten oder schwer auffindbaren Codestücken angelegt. In diesem Post möchte ich
diese nun zusammenfassen, falls jemand anderes ähnliche Anforderungen oder Probleme hat :)</p>

<h2>Direkt auf natives Collection-Objekt zugreifen</h2>

<p>Möchte man z.B. ein Dokument via Mongoose in die <a href="http://www.mongodb.org">MongoDB</a> speichern, aber sämtliche Hooks und Validierungen umgehen,
kann man direkt auf die Collection zufreifen. Dies ist logischerweise bedeutend schneller als der &#8220;offizielle&#8221; Weg
und somit interessant für Bulk-Inserts.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">Entry</span><span class="p">.</span><span class="nx">collection</span><span class="p">.</span><span class="nx">insert</span><span class="p">({</span> <span class="nx">title</span><span class="o">:</span> <span class="s1">&#39;Foo&#39;</span> <span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Das Gleiche gilt natürlich auch, wenn man z.B. eine komplette Collection löschen will (anstatt sie zu leeren):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">Entry</span><span class="p">.</span><span class="nx">collection</span><span class="p">.</span><span class="nx">drop</span><span class="p">();</span>
</span></code></pre></td></tr></table></div></figure>




<!-- more -->


<h2>Eine Liste von Spalten/Pfaden erhalten</h2>

<p>Es kommt des öfteren vor, dass man durch die möglichen Pfade gehen muss um z.B. auf Vorhandensein oder ähnliches zu
prüfen. Es gibt viele mögliche und unmögliche Anwendungsbeispiele. Um dies zu erreichen kann man sich eine Liste der
Pfade aus dem Schema des Models holen.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">Entry</span><span class="p">.</span><span class="nx">schema</span><span class="p">.</span><span class="nx">paths</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Einzelne Pfade mit definierter Validierung validieren</h2>

<p>Es kann vorkommen, dass man nur einen einzigen Pfad eines Model validieren will, da der User z.B. nur diesen einen
Pfad im UI eingeben kann und man nicht das komplette Model befüllen will. Hierfür wäre es natürlich schön, wenn man
ein Model mit dem einzelnen Parameter instanziiert und nur diesen validiert (andernfalls könnte z.B. eine andere
Validierung fehlschlagen, da Parameter fehlen und der eigentlich interessante Parameter würde garnicht erst getestet
werden). Glücklicherweise kann dies wie folgt umgesetzt werden, sogar ohne ein Model effektiv zu instanziieren.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">Entry</span><span class="p">.</span><span class="nx">schema</span><span class="p">.</span><span class="nx">paths</span><span class="p">.</span><span class="nx">title</span><span class="p">.</span><span class="nx">doValidate</span><span class="p">(</span><span class="s1">&#39;zu kurz&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">err</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Oder</span>
</span><span class='line'>
</span><span class='line'><span class="nx">Entry</span><span class="p">.</span><span class="nx">schema</span><span class="p">.</span><span class="nx">path</span><span class="p">(</span><span class="s1">&#39;title&#39;</span><span class="p">).</span><span class="nx">doValidate</span><span class="p">(</span><span class="s1">&#39;zu kurz&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">err</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Änderungen am aktuellen Objekt einsehen</h2>

<p>Manchmal möchte man z.B. innerhalb eines Pre-Save-Hooks bestimmte Funktionen ausführen, falls bestimmte Pfade
verändert wurden. Vor allem beim Ändern von Sub-Dokumenten ein interessanter Fall. Hierfür benötigt man die Liste von
geänderten Pfaden, auf welche man über folgende Funktion zugreifen kann.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">entry</span><span class="p">.</span><span class="nx">_dirty</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Oder um das Delta zu sehen</span>
</span><span class='line'>
</span><span class='line'><span class="nx">entry</span><span class="p">.</span><span class="nx">_delta</span><span class="p">();</span>
</span></code></pre></td></tr></table></div></figure>


<h2>&#8216;createdAt&#8217; und &#8216;updatedAt&#8217; als Plugin</h2>

<p>In der Rails-Welt ist es gang und gebe, dass jedes Model einen <code>created_at</code> und einen <code>updated_at</code> Timestamp hat. Für
Mongoose gibt es bereits einige Module die Plugins mit entsprechenden Funktionalitäten anbieten, allerdings kann man dies auch schnell selbst implementieren.</p>

<p>In der Plugin-Datei, z.B. <code>timestampable.js</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">schema</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="c1">// createdAt</span>
</span><span class='line'>  <span class="nx">schema</span><span class="p">.</span><span class="nx">add</span><span class="p">({</span> <span class="nx">createdAt</span> <span class="o">:</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">type</span><span class="o">:</span> <span class="nb">Date</span><span class="p">,</span>
</span><span class='line'>    <span class="k">default</span><span class="o">:</span> <span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">required</span><span class="o">:</span> <span class="kc">true</span>
</span><span class='line'>  <span class="p">}});</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// updatedAt</span>
</span><span class='line'>  <span class="nx">schema</span><span class="p">.</span><span class="nx">add</span><span class="p">({</span> <span class="nx">updatedAt</span> <span class="o">:</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">type</span><span class="o">:</span> <span class="nb">Date</span>
</span><span class='line'>  <span class="p">}});</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// updateAt aktualisieren falls Dokument nicht neu ist</span>
</span><span class='line'>  <span class="nx">schema</span><span class="p">.</span><span class="nx">pre</span><span class="p">(</span><span class="s1">&#39;save&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">next</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">isNew</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">this</span><span class="p">.</span><span class="nx">updatedAt</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">next</span><span class="p">()</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Im jeweiligen Model:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">timestampable</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./pfad/zum/plugin/timestampable&#39;</span><span class="p">)</span>
</span><span class='line'>  <span class="p">,</span> <span class="nx">mongoose</span>      <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;mongoose&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">Schema</span> <span class="o">=</span> <span class="nx">mongoose</span><span class="p">.</span><span class="nx">Schema</span><span class="p">({</span>
</span><span class='line'><span class="cm">/**</span>
</span><span class='line'><span class="cm"> * Schema Definition...</span>
</span><span class='line'><span class="cm"> */</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Plugin einbinden</span>
</span><span class='line'><span class="nx">Schema</span><span class="p">.</span><span class="nx">plugin</span><span class="p">(</span><span class="nx">timestampable</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Problem: Mongoose-Skript endet nicht</h2>

<p>Sollte man Mongoose in einem separaten Skript einsetzen, zum Beispiel in einer Migration, kann es passieren das
Mongoose seine Arbeit getan hat, man allerdings dennoch keinen Prompt auf der Kommandozeile erhält. Dies liegt daran,
dass Mongoose die Verbindung zur MongoDB offen hält und das Skript somit nicht endet. Einfachster Weg ist hier
natürlich die Verbindung zu trennen.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">mongoose</span><span class="p">.</span><span class="nx">disconnect</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Ggf. noch:</span>
</span><span class='line'><span class="nx">process</span><span class="p">.</span><span class="nx">exit</span><span class="p">();</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Debugging-Ausgabe</h2>

<p>Wer gerne jede Query auf der Kommandozeile einsehen will, der kann innerhalb von Mongoose die Debugging-Ausgabe
aktivieren, welche für alle Models und Queries global verwendet wird (solange die gleiche Mongoose-Instanz verwendet
wird natürlich). Dies trifft übrigens auch zu, wenn man den oben genannten Shortcut über <code>Model.collection</code> nutzt.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">mongoose</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;debug&#39;</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Abschluss</h2>

<p>Wer weitere Vorschläge für die Liste hat, möchte diese bitte in den Kommentaren hinterlassen. Das Gleiche gilt für
Fragen, die in diesem Post nicht beantwortet wurden. Vielleicht hatte ich schon mit dem einen oder anderen Problem
zu tun und habe es bisher nur nicht in die Liste aufgenommen. :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Node.js vs PHP]]></title>
    <link href="http://www.mario-behrendt.de/2012/08/05/node-dot-js-vs-php/"/>
    <updated>2012-08-05T11:03:00+02:00</updated>
    <id>http://www.mario-behrendt.de/2012/08/05/node-dot-js-vs-php</id>
    <content type="html"><![CDATA[<p>Nachdem ich in letzter Zeit immer mehr Blogeinträge und Tweets über &#8220;Node.js vs PHP&#8221; oder ähnliches lese und auch selbst immer mehr in <a href="http://nodejs.org">Node.js</a> entwickle, dachte ich mir, ich teile auch meine Meinung und Erfahrung der Öffentlichkeit mit.</p>

<p>Zu allererst muss ich sagen, dass ich seit knapp 8 Jahren <a href="http://php.net">PHP</a> entwickle, seit 5 Jahren hauptberuflich. Letztes Jahr habe ich zudem das <a href="http://www.zend.com/yellow-pages#show-ClientCandidateID=ZEND017367">Zend Certified Engineer</a>-Zertifikat erhalten. Node verfolge ich seit ungefähr einem Jahr, verstärkt eingesetzt wird es von mir seit einigen Monaten. Kommen wir zu den groben Eckpunkten: Sprache, Dependencies, Community, Frameworks und Module, Testing, Performance, Einsatzzwecke und persönliches Empfinden.</p>

<!-- more -->


<h2>Spache</h2>

<p>Node.js selbst ist keine Sprache, sondern ein <a href="http://de.wikipedia.org/wiki/Node.js">serverseitiges Framework</a>, das <a href="http://de.wikipedia.org/wiki/Javascript">Javascript</a> ausführt. Daher muss hier eher Javascript mit PHP verglichen werden. Hierbei gibt es meines Erachtens nicht wirklich viele Unterschiede. Sicher ist das OOP-Verhalten nicht das gleiche und sicher hat jede Sprache ihre Vor- und Nachteile, dennoch nehmen sich beide in meinen Augen nicht viel. Beide sind extrem verbreitet und der größte Teil der Entwickler kann mindestens eine von beiden (mehr oder weniger gut). Vor diesem Gesichtspunkt ein Unentschieden.</p>

<h2>Dependencies</h2>

<p>Hier punktet Node ganz klar mit <a href="https://npmjs.org">npm</a>. Sicher gibt es für PHP <a href="http://pear.php.net">PEAR</a>, doch Hand aufs Herz, niemand mag es, es ist buggy, langsam und grauenvoll zu bedienen. Leider wurde hier von der PHP-Community nie nachgebessert, denn das Problem ist nicht das npm soo gut ist - nein, PEAR ist einfach so schlecht. Das Auflösen von Abhängigkeiten ist in anderen (Web-)Sprachen wie <a href="http://www.ruby-lang.org/de">Ruby</a> und <a href="http://www.python.org">Python</a> genauso einfach und simpel. Node:1, PHP: 0.</p>

<h2>Community</h2>

<p>Das ist ein ganz heißes Eisen. Hier muss man fast mit zweierlei Maß messen. PHP hat mit Abstand die größere Community, allein schon durch die enorme Verbreitung, vor allem in Europa. Gerade Deutschland ist PHP-Land und wird es auch noch lange bleiben, da Innovationen aus den USA und Asien immer erst sehr spät oder gar nicht bei uns einen Fuß in die Tür bekommen (siehe die immer noch geringe Verbreitung von <a href="https://www.djangoproject.com">Django</a> und <a href="http://rubyonrails.org">Rails</a>). Allerdings ist in Punkto Quantität die Node-Community wohl jetzt schon eine Liga über PHP. Es werden extrem viele Module und Tools veröffentlicht, ein Großteil sowohl OpenSource, als auch mit extrem hoher Code-Qualität. Das Tempo der Node-Community ist astronomisch, hier ist nur noch das Rails-Ökosystem vergleichbar, das ähnlich agil arbeitet. Unterm Strich muss die schiere Größe der PHP-Community allerdings auch einberechnet werden, daher erneut ein Unentschieden.</p>

<h2>Frameworks und Module</h2>

<p>Hier trennt sich die Spreu vom Weizen. PHP geht hierbei <em>in meinen Augen</em> einen schlechten Weg, indem Frameworks wie <a href="http://symfony.com">Symfony2</a> (hat mich nicht umgehauen, aber ok) und <a href="http://flow3.typo3.org">Flow3</a> (ohne Worte) veröffentlicht und angepriesen werden. Nachdem ich mit vielen davon arbeiten konnte/musste, scheint mir <a href="http://framework.zend.com">Zend Framework</a> <strong>Version 1</strong> nach wie vor das beste PHP-Framework zu sein. Leider gibt es auf PHP-Seite keine Innovation, sondern nur Revolution bzw. gefühlten Rückschritt (Stichwort Annotations in PHP, imho inakzeptabel, sowie z.B. gängige Template-Engines). Node hat hier den Vorteil, dass einfach vor einigen Monaten nur sehr wenig existierte und die Entwickler sich ihre Sachen neu bauen bzw. portieren mussten. Und wenn dies der Fall ist, werden natürlich die besten Sachen aus allen Sprachen/Frameworks einbezogen. Zum Beispiel:</p>

<ul>
<li>Template-Engine <a href="http://jade-lang.com">jade</a>: Port von <a href="http://haml.info">Haml</a> inklusive einigen Verbesserungen</li>
<li>Routing-Framework <a href="http://expressjs.com">express</a>: Port von <a href="http://www.sinatrarb.com">Sinatra</a> inklusive Verbesserungen und Erweiterungen</li>
<li>CSS-Generator <a href="http://learnboost.github.com/stylus">stylus</a>: Innovation mit Einflüssen aus <a href="http://lesscss.org">less</a> und <a href="http://sass-lang.com">SASS</a></li>
<li>Test-Framework <a href="http://visionmedia.github.com/mocha">mocha</a>: <a href="http://rspec.info">Rspec</a> ähnliches Framework</li>
<li>CSS3-Extensions mit <a href="http://visionmedia.github.com/nib">nib</a>: Vergleichbar mit <a href="http://compass-style.org">compass</a></li>
<li>usw.</li>
</ul>


<p>Beim aktuellen Stand der Dinge ein klares 2:0.</p>

<h2>Testing</h2>

<p>Das leidige Thema mit den Unit-Tests in PHP. Nachdem man in Node, Ruby oder Python getestet hat und zurück zu PHP kommt, denkt man der Rechner komprimiert im Hintergrund 10 Filme auf insgesamt 10MB. Natürlich ist es möglich mit PHP-Applikationen komplett zu testen und auch Test-driven zu entwickeln, allerdings ist die Geschwindigkeit nicht gerade berauschend und vor allem die Auswahl an möglichen Tools ist so klein, dass es einfach nur demotiviert. Hier fehlen ganz klar Pendants zu Rspec, <a href="http://cukes.info">Cucumber</a>, Mocha, <a href="http://vowsjs.org">Vows</a>, <a href="http://test-unit.rubyforge.org">Test::Unit</a> und wie sie alle heißen. 3:0</p>

<h2>Performance</h2>

<p>Auch das ist ein zweischneidiges Schwert, da auch PHP in Kombination mit z.B. <a href="http://memcached.org">Memcached</a> durchaus schnell sein kann - und wenn ohnehin alles aus dem Cache kommt, kann auch Node mit seinem asynchronen Verhalten (außer beim Unit-Testing) nicht punkten. Technisch gesehen ist Node sicher schneller, schon allein durch den asynchronen Aufbau, aber da bei heutigen Webseiten ohnehin 90%+ aus dem Cache kommen sollten: Unentschieden.</p>

<h2>Einsatzzwecke</h2>

<p>Nun, in Punkto Einsatzwecke ist PHP Node wohl einige Schritte voraus. Durch die extrem hohe Akzeptanz in Europa bietet jeder noch so kleine Shared-Hoster mindestens irgendeine PHP5-Version, zusammen mit einem <a href="http://httpd.apache.org">Apache</a> an. Somit kann man für sehr wenig Geld seine eigene Applikation hosten und warten. Für den Einsatz von Node.js bedarf es in den meisten Fällen eines Servers, oder man nutzt die Angebote entsprechender Cloud-Dienste (hervorzuheben ist hier <a href="http://www.heroku.com">Heroku</a>, die es unglaublich einfach machen <em>kostenlos</em> und sexy zu deployen).</p>

<p>Weiterhin ist Node aber auch nicht für jede Applikation geeignet. Gerade CPU-intensive und IO-lastige Aufgaben nehmen Node den Wind aus den Segeln (sicher, das kann man vorbeugen, aber dennoch). Ich teile die Meinung von einigen Leuten nicht, die sagen &#8220;wenn man eine Content-Webseite erstellen will, muss es PHP sein, Realtime mit Node&#8221;. Das ist zu einfach formuliert und imho auch falsch. Ich sehe das eher so:</p>

<ul>
<li>Realtime/Asynchron: Node</li>
<li>Anfänger im Bereich Development: Erst Node ansehen, dann PHP</li>
<li>APIs: Node</li>
<li>Sehr schnelle Entwicklung mit enger Deadline: Ruby oder Python</li>
<li>Nur Shared Hoster: PHP</li>
<li>Du findest Flow3 gut: PHP</li>
<li>Du testet gerne und viel: Node, Ruby, Python, Java</li>
<li>Du hast PHP-Erfahrung und schreibst eine MySQL-basierte App: PHP</li>
<li>Du hast ein schlechtes Feeling bei einem der beiden: Das Andere</li>
</ul>


<p>Am Ende ist PHP wohl einfacher und schneller einzusetzen. Da es auch bei so gut wie jedem Applikations-Typ eingesetzt werden <em>kann</em>, steht es 3:1.</p>

<h2>Persönliches Empfinden</h2>

<p>Wie gesagt habe ich relativ viel Erfahrung mit PHP und Node sammeln können und bin zu folgendem Ergebnis gekommen: Node liegt mir einfach bedeutend mehr (genau wie Ruby). Die Community ist unglaublich und die Entwicklung ist wirklich einfach und der Code platzsparend. Unit-Testing macht noch mal 50% mehr Spaß als bei Ruby (durch die Geschwindigkeit, sorry Rails…) und die zur Verfügung stehenden Frameworks/Module sind einfach gut. Außerdem gefällt mir der sehr kleine Stack:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>git clone
</span><span class='line'><span class="nv">$ </span>npm install
</span><span class='line'><span class="nv">$ </span>node app.js
</span></code></pre></td></tr></table></div></figure>


<p>Und schon läuft die App. Da es sich um einen komplett persönlichen &#8220;Gefühlseindruck&#8221; handelt, vergebe ich in dieser Kategorie keinen Punkte.</p>

<h2>Abschluss</h2>

<p>Ich will mit diesem Artikel auf keinen Fall eine der beiden Optionen haten oder liken. Es geht nur um das was ich in letzter Zeit wahrgenommen und gesehen habe. PHP hat seine Vorteile und so auch Node, allerdings hat Node mit 3:1 immerhin <em>in den von mir angesprochenen Kategorien</em> gewonnen.</p>

<p>Jeder muss für sich selbst und von Projekt zu Projekt entscheiden, was das richtige ist. Mein Tipp: <strong>Bitte einfach beim nächsten Projekt genau recherchieren, was das Richtige ist und was am meisten Sinn macht - sowohl kurzfristig als auch langfristig.</strong> Sätze wie &#8220;Wir schreiben es mit PHP und Framework X, weil das unsere Kernkompetenz ist&#8221; sind schlichtweg Blödsinn. Entwickler müssen neues entdecken und sehen, um auch bei den bereits bekannten Sachen besser zu werden. Man erkennt zum Beispiel am PHP-Code eines <em>guten</em> Entwicklers, wenn er schon einmal mit Rails gearbeitet hat ;)</p>

<p>Also: Immer schön recherchieren und ruhig mal 1 Woche oder mehr zum testen der Tools und Sprachen Zeit nehmen. Das Lesen der Dokumentation alleine reicht nicht aus!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Continuous Integration mit Travis]]></title>
    <link href="http://www.mario-behrendt.de/2012/04/02/continuous-integration-mit-travis/"/>
    <updated>2012-04-02T08:11:00+02:00</updated>
    <id>http://www.mario-behrendt.de/2012/04/02/continuous-integration-mit-travis</id>
    <content type="html"><![CDATA[<p>In Anschluss an meinen <a href="http://www.mario-behrendt.de/2012/04/01/ein-npm-paket-fur-node-dot-js-erstellen">letzen Artikel</a> zum Bau eines <a href="http://nodejs.org">Node.js</a>-Moduls, möchte ich noch kurz mein Vorgehen bei der
Verwendung von <a href="http://travis-ci.org">Travis CI</a> erklären. Auch wenn ich als Autor von <a href="http://www.amazon.de/dp/3868991271">Jenkins Kurz &amp; Gut</a> natürlich bevorzugt
<a href="http://jenkins-ci.org">Jenkins</a> für kontinuierliche Integration verwende, kann es doch ganz nett und sinnvoll sein einen Dienst wie Travis
CI zu nutzen. Gerade Open Source-Projekte sind hier bestens geeignet, vor allem wenn sie auf <a href="http://github.com">Github</a> liegen!</p>

<!-- more -->


<p>Kernstück und <em>fast</em> einzige nötige Konfiguration ist die Datei <code>.travis.yml</code> im Root-Ordner des jeweiligen Projektes. Diese
könnte wie folgt aussehen:</p>

<figure class='code'><figcaption><span>Travis Konfiguration</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">language</span><span class="o">:</span> <span class="nx">node_js</span>
</span><span class='line'><span class="nx">node_js</span><span class="o">:</span>
</span><span class='line'>    <span class="o">-</span> <span class="mf">0.6</span>
</span></code></pre></td></tr></table></div></figure>


<p>Jaaaaa, mehr nicht :) Wie unschwer zu erkennen, handelt es sich dabei, wie oben bereits angesprochen, um ein
Node.js-Projekt. <code>language</code> legt somit einfach die verwendete Sprache fest, <code>node_js</code> die zu testenden Versionen.
Weitere Informationen zu den möglichen Optionen finden sich in der ausgezeichneten <a href="http://about.travis-ci.org/docs">Dokumentation</a>.</p>

<p>Im Falle von Node.js führt Travis automatisch das Kommando <code>npm test</code> aus. Damit NPM auch weiß, was dabei zu tun ist,
bedarf es ein paar Zeilen in der entsprechenden <code>package.json</code>-Datei:</p>

<figure class='code'><figcaption><span>NPM Konfiguration</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="s2">&quot;scripts&quot;</span><span class="o">:</span> <span class="p">{</span>
</span><span class='line'>    <span class="s2">&quot;test&quot;</span><span class="o">:</span> <span class="s2">&quot;make test&quot;</span>
</span><span class='line'><span class="p">},</span>
</span></code></pre></td></tr></table></div></figure>


<p>Das Kommando sollte natürlich auch vorhanden und ausführbar sein (ich verwende Makefiles in Verbindung mit dem Testing
Framework <a href="http://visionmedia.github.com/mocha">Mocha</a>). Danach muss man nur noch auf die Webseite von Travis gehen, sich via Github einloggen und das
Repository aktivieren. Schon führt Travis bei jedem Push die Tests aus und verschickt im Fehlerfall E-Mails. Ein
<a href="http://travis-ci.org/#!/MarioBehrendt/Leipzig.js">schickes Frontend</a> gibt es dazu natürlich auch. Alles kostenlos, hosted und unkompliziert - <strong>sehr nett</strong>!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ein NPM Paket für Node.js erstellen]]></title>
    <link href="http://www.mario-behrendt.de/2012/04/01/ein-npm-paket-fur-node-dot-js-erstellen/"/>
    <updated>2012-04-01T13:47:00+02:00</updated>
    <id>http://www.mario-behrendt.de/2012/04/01/ein-npm-paket-fur-node-dot-js-erstellen</id>
    <content type="html"><![CDATA[<p>Vor einigen Tagen habe ich mein erstes <a href="http://npmjs.org">NPM</a>-Paket für <a href="http://nodejs.org">Node.js</a> erstellt: <a href="http://github.com/MarioBehrendt/Leipzig.js">Leipzig.js</a>. Es handelt sich dabei um
einen <strong>sehr</strong> rudimentären Client für die <a href="http://www.apileipzig.de">API Leipzig</a>. Neben dem offensichtlichen Zweck des Moduls wollte ich
endlich auch mal in die Node.js Modulentwicklung einsteigen und mir ansehen, wie NPM funktioniert.</p>

<!-- more -->


<h2>Package.json</h2>

<p>Kernstück des Moduls ist die Daten <code>package.json</code>, die NPM über Name, Version und Abhängigkeiten informiert. Das
folgende Beispiel enthält die notwendigen Mindestanforderungen plus das Testing-Framework <a href="http://visionmedia.github.com/mocha">Mocha</a> als Dev-Dependency:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="s2">&quot;testapp&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="s2">&quot;description&quot;</span><span class="o">:</span> <span class="s2">&quot;Mein Testapp&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="s2">&quot;version&quot;</span><span class="o">:</span> <span class="s2">&quot;0.0.1&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="s2">&quot;author&quot;</span><span class="o">:</span> <span class="s2">&quot;Mario Behrendt &lt;info@mario-behrendt.de&gt;&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="s2">&quot;devDependencies&quot;</span><span class="o">:</span> <span class="p">{</span>
</span><span class='line'>    <span class="s2">&quot;mocha&quot;</span><span class="o">:</span> <span class="s2">&quot;*&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="s2">&quot;main&quot;</span><span class="o">:</span> <span class="s2">&quot;index&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="s2">&quot;engines&quot;</span><span class="o">:</span> <span class="p">{</span> <span class="s2">&quot;node&quot;</span><span class="o">:</span><span class="s2">&quot;&gt;= 0.5.0 &lt; 0.7.0&quot;</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Die ersten Einträge sind wohl selbserklärend. Mit <code>main</code> legt man den Einstiegspunkt des Moduls fest, in diesem Fall die
Datei <code>index.js</code>. Unter <code>engines</code> können die kompatiblen Node.js-Versionen eingepflegt werden. NPM prüft diese bei der
Installation und weißt den Nutzer bei Inkompatibilität mit einer entsprechenden Fehlermeldung darauf hin.</p>

<h2>Publishing</h2>

<p>Angenommen das Modul enthält an dieser Stelle auch schon verwendbaren Code und der Name ist noch nicht belegt, kann die
Veröffentlichung direkt beginnen. Hierfür muss, falls nicht bereits vorhanden, ein NPM-Account erstellt werden:</p>

<figure class='code'><figcaption><span>Account erstellen</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>npm adduser
</span></code></pre></td></tr></table></div></figure>


<p>Danach wechselt man in den Überordner des Moduls und führt das Publishing durch.</p>

<figure class='code'><figcaption><span>Modul veröffentlichen</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>npm publish <span class="nv">$ordername</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>That&#8217;s it!</strong> Nun sollte das Package auch schon in der <a href="http://search.npmjs.org">NPM-Suche</a> aufzufinden und installierbar sein:</p>

<figure class='code'><figcaption><span>Installation des Moduls via NPM</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>npm install testapp
</span></code></pre></td></tr></table></div></figure>


<p>Wenn man später neue Versionen des Moduls hochladen will, muss lediglich die Version in der <code>package.json</code> angehoben,
sowie der <code>publish</code> Task erneut ausgeführt werden - NPM kümmert sich um den Rest.</p>

<p>Insgesamt empfand ich das arbeiten mit NPM als Modulentwickler <em>sehr angenehm</em> und <em>unglaublich schnell</em>. Teilweise
dachte ich es kam zu Problemen und Fehlern, doch NPM war einfach schon nach extrem kurzer Zeit fertig. Ein gelunger
Ausgleich zu &#8220;Package-Managern&#8221; anderer Sprachen, die hier ungenannt bleiben möchten.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[ActiveAdmin Teil 3: Quick Filter]]></title>
    <link href="http://www.mario-behrendt.de/2012/03/18/activeadmin-teil-3-quick-filter/"/>
    <updated>2012-03-18T18:07:00+01:00</updated>
    <id>http://www.mario-behrendt.de/2012/03/18/activeadmin-teil-3-quick-filter</id>
    <content type="html"><![CDATA[<p>Um <a href="http://www.mario-behrendt.de/2012/02/09/admininterface-mit-activeadmin">Teil 1</a> und <a href="http://www.mario-behrendt.de/2012/02/13/activeadmin-teil-2-menus-anpassen">Teil 2</a> der Reihe zu ergänzen nun der dritte Teil zum Thema <a href="http://activeadmin.info">ActiveAdmin</a>. Um genau zu sein
möchte ich heute auf Quick Filter eingehen. Dabei handelt es sich um vordefinierte Suchanfragen die direkt über den
Grids gerendert werden. Klassisches Beispiel für einen solchen Filter ist etwa die Anzeige aller veröffentlichten
Seiten innerhalb eines CMS.</p>

<p>In meinem Beispiel soll es ein User-Model geben, dass über die boolesche Eigenschaft <code>active</code> ausdrückt, ob ein
Nutzer-Account durch einen Admin freigegeben wurde oder nicht. Um alle nicht aktivierten Accounts schnell aufzulisten
und somit den Workflow für die Suche nach &#8220;zu prüfenden Nutzern&#8221; zu verbessern, bietet sich ein Quick Filter an.</p>

<!-- more -->


<p>Um einen Quick Filter zu definieren bedarf es lediglich eines <a href="http://guides.rubyonrails.org/active_record_querying.html#scopes">Named Scopes</a>. ActiveAdmin liest diesen nach einer kleinen
Anpassung direkt aus und zeigt ihn im Frontend als Filter an. Basierend auf meinem Beispiel könnte das User-Model wie
folgt aussehen.</p>

<figure class='code'><figcaption><span>Basis User-Model mit ActiveRecord</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">User</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="n">scope</span> <span class="ss">:inactive</span><span class="p">,</span> <span class="n">where</span><span class="p">(</span><span class="ss">:active</span> <span class="o">=&gt;</span> <span class="kp">false</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Um den Scope innerhalb von ActiveAdmin zu registrieren muss der anzuzeigende Titel und der Scope-Name im entsprechenden
Admin-Model definiert werden.</p>

<figure class='code'><figcaption><span>Admin-User-Model</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">ActiveAdmin</span><span class="o">.</span><span class="n">register</span> <span class="no">User</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">scope</span> <span class="s2">&quot;Inaktiv&quot;</span><span class="p">,</span> <span class="ss">:inactive</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Das Ergebnis sieht im Frontend schließlich wie folgt aus:</p>

<p><img class="center" src="http://www.mario-behrendt.de/images/posts/activeadmin-quick-filter.png" title="&#34;ActiveAdmin Quick Filter&#34;" alt="&#34;ActiveAdmin Quick Filter&#34;"></p>

<p>Indem man <code>default</code> auf <code>true</code> setzt, kann ein Filter außerdem als Standard markiert werden. Somit wird beim Aufruf des
Grids immer direkt nach dessen Kriterien aussortiert:</p>

<figure class='code'><figcaption><span>Scope als Standardfilter</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">ActiveAdmin</span><span class="o">.</span><span class="n">register</span> <span class="no">User</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">scope</span> <span class="s2">&quot;Inaktiv&quot;</span><span class="p">,</span> <span class="ss">:inactive</span><span class="p">,</span> <span class="ss">:default</span> <span class="o">=&gt;</span> <span class="kp">true</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[ActiveAdmin Teil 2: Menues anpassen]]></title>
    <link href="http://www.mario-behrendt.de/2012/02/13/activeadmin-teil-2-menus-anpassen/"/>
    <updated>2012-02-13T16:10:00+01:00</updated>
    <id>http://www.mario-behrendt.de/2012/02/13/activeadmin-teil-2-menus-anpassen</id>
    <content type="html"><![CDATA[<p>Nachdem ich im <a href="http://www.mario-behrendt.de/2012/02/09/admininterface-mit-activeadmin">ersten Teil</a> meiner <a href="http://activeadmin.info">ActiveAdmin</a>-Reihe auf die Installation und die grundlegende Verwendung
eingegangen bin, möchte ich mich heute kurz den Menüs widmen.</p>

<p>Wenn man via <code>rake</code> eine neue Admin-Resource erstellt, legt ActiveAdmin automatisch einen neuen Menü-Punkt, mit dem Namen
der Entität als Label, an. Wenn man allerdings viele Entitäten/Models hat, wird dieses Menü recht schnell sehr breit und
unübersichtlich. ActiveAdmin bietet hierfür die Möglichkeit an, Menüpunkte ineinander zu verschachteln - automatisch generierte
Dropdowns inklusive. Und so geht&#8217;s:</p>

<p>Angenommen es gibt die beiden Models <em>Interviews</em> und <em>Interview_Questions</em>. Jedes Interview kann also beliebig viele
Fragen zugewiesen bekommen. Da diese beiden Entitäten doch sehr stark voneinander abhängen, sollen sie einen gemeinsamen
Menüpunkt bekommen.</p>

<figure class='code'><figcaption><span>app/admin/interviews.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">ActiveAdmin</span><span class="o">.</span><span class="n">register</span> <span class="no">Interview</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">menu</span> <span class="ss">:parent</span> <span class="o">=&gt;</span> <span class="s2">&quot;Interviews&quot;</span><span class="p">,</span> <span class="ss">:priority</span> <span class="o">=&gt;</span> <span class="mi">1</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>app/admin/interview_questions.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">ActiveAdmin</span><span class="o">.</span><span class="n">register</span> <span class="no">InterviewQuestion</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">menu</span> <span class="ss">:parent</span> <span class="o">=&gt;</span> <span class="s2">&quot;Interviews&quot;</span><span class="p">,</span> <span class="ss">:priority</span> <span class="o">=&gt;</span> <span class="mi">2</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>




<!-- more -->


<p>Auch ohne viel ActiveAdmin-Erfahrung lässt sich hier recht schnell ausmachen was geschieht. In beiden Fällen wird der
Eintrag innerhalb des Elternpunktes <strong>Interviews</strong> hinterlegt, wobei die Priorität über die Reihenfolge innerhalb des
Dropdowns entscheidet (1 == ganz oben). Und so sieht es dann im Frontend aus:</p>

<p><img class="center" src="http://www.mario-behrendt.de/images/posts/activeadmin-menu.png" title="&#34;ActiveAdmin-Menues&#34;" alt="&#34;ActiveAdmin-Menues&#34;"></p>

<p>Neben <code>priority</code> und <code>parent</code> stehen außerdem noch zwei weitere Optionen für Menüeinträge bereit: <code>label</code> und <code>if</code>. Mit
dem ersteren kann, wie nicht schwer zu erraten, der Anzeigestring im Menü angepasst werden. Wer also statt den englischen
Namen des Models <em>Interviews</em> lieber <em>Gespräche</em> verwenden will, kann dies via <code>label</code> tun.</p>

<figure class='code'><figcaption><span>app/admin/interviews.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">ActiveAdmin</span><span class="o">.</span><span class="n">register</span> <span class="no">Interview</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">menu</span> <span class="ss">:label</span> <span class="o">=&gt;</span> <span class="s2">&quot;Gespräche&quot;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Mit <code>if</code> kann ein Eintrag aufgrund einer Prüfung ein- oder ausgeblendet werden. Bestes Beispiel: Sollte der aktuelle
Benutzer nicht berechtigt sein eine bestimmte Entität zu editieren, ist es auch nicht nötig ihm den entsprechenden
Menüpunkt anzuzeigen.</p>

<figure class='code'><figcaption><span>app/admin/interviews.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">ActiveAdmin</span><span class="o">.</span><span class="n">register</span> <span class="no">Interview</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">menu</span> <span class="ss">:if</span> <span class="o">=&gt;</span> <span class="nb">proc</span><span class="p">{</span> <span class="n">current_admin_user</span><span class="o">.</span><span class="n">can_edit_interviews?</span> <span class="p">}</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Zum Schluss noch ein kleiner Hinweis zum <code>if</code>. <code>proc</code> wird im Kontext eines Views ausgeführt - es ist somit also der
Zugriff auf alle Variablen und Methoden möglich, die auch in einem &#8220;normalen&#8221; View zur Verfügung stehen würden.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Admininterface mit ActiveAdmin]]></title>
    <link href="http://www.mario-behrendt.de/2012/02/09/admininterface-mit-activeadmin/"/>
    <updated>2012-02-09T16:20:00+01:00</updated>
    <id>http://www.mario-behrendt.de/2012/02/09/admininterface-mit-activeadmin</id>
    <content type="html"><![CDATA[<p><img class="left" src="http://www.mario-behrendt.de/images/posts/activeadmin.png" title="&#34;ActiveAdmin&#34;" alt="&#34;ActiveAdmin&#34;"></p>

<p>Wer bereits mit <a href="https://www.djangoproject.com">Django</a> entwickelt hat, für den sind schnell aufgesetzte, hochfunktionale und schicke Admininterfaces
nichts neues. Doch auch in der Ruby-Welt gibt es das ein oder andere ernstzunehmende Gem, das ähnliche Features
bereitstellt. Nebenbei bemerkt finde ich diese Trennung von den einzelnen Gems in Ruby besser gelöst als das
Out-of-the-Box-Adminterface von Django. Auch wenn es schön ist, direkt nach der Einrichtung eines Projektes Zugriff auf
diese Möglichkeiten zu haben, scheint mir die Auslagerung wesentlich sauberer und schicker.</p>

<p>Doch zurück zu den Kontrahenten. Aktuell scheinen zwei Gems um den Platz des besten Backends zu kämpfen: <a href="http://activeadmin.info">ActiveAdmin</a>
und <a href="https://github.com/sferik/rails_admin">RailsAdmin</a>. Nachdem ich mir beide etwas näher angeschaut hatte, fiel meine Entscheidung auf ActiveAdmin. Es
sieht nicht nur wesentlicher schicker aus - es ist auch noch super einfach zu bedienen. Auch komplexe Backends sind in
wenigen Stunden erledigt. Folgend werde ich kurz auf die Installation sowie einige Beispiele eingehen.</p>

<!-- more -->


<h2>Installation</h2>

<p>Da ich ActiveAdmin innerhalb einer <a href="http://www.rubyonrails.de">Rails</a>-Applikation getestet habe, werde ich meine Beispiele auch auf diese
beziehen. Da alle neueren Rails-Apps mit <a href="http://gembundler.com">Bundler</a> laufen sollten, gestaltig sich die Installation mehr als einfach.</p>

<figure class='code'><figcaption><span>Eintragen des Gems im Gemfile</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">gem</span> <span class="s1">&#39;activeadmin&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Falls Rails &gt;= 3.1 verwendet wird zusätzlich</span>
</span><span class='line'><span class="n">gem</span> <span class="s1">&#39;sass-rails&#39;</span>
</span><span class='line'><span class="n">gem</span> <span class="s2">&quot;meta_search&quot;</span><span class="p">,</span> <span class="s1">&#39;&gt;= 1.1.0.pre&#39;</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>Installation via Bundler und Installer laufen lassen</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>bundle install
</span><span class='line'><span class="nv">$ </span>rails g active_admin:install
</span></code></pre></td></tr></table></div></figure>


<p>Der Installer erstellt automatisch einen neuen Ordner <code>app/admin</code> und legt den entsprechenden Initializer an. Danach
sollte die Datenbank mit den neuen Tabellen (unter anderem Admin-Nutzer) befüllt werden:</p>

<figure class='code'><figcaption><span>Datenbank-Migration</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>rake db:migrate
</span></code></pre></td></tr></table></div></figure>


<p>Wenn man nun den Server startet (<code>rails s</code>) und <code>http://localhost:3000/admin</code> aufruft, kann man sich mit den folgenden
Zugangsdaten einloggen:</p>

<p>Username: <em>admin@example.com</em><br/>
Password: <em>password</em></p>

<h2>Verwendung</h2>

<p>Um nun die entsprechenden Admin-Models zu erstellen, bietet das Gem eigene Kommandos an - bestehende
ActiveRecord-Models vorausgesetzt.</p>

<figure class='code'><figcaption><span>Admin-Model erstellen</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>rails g active_admin:resource <span class="o">[</span>Modelname<span class="o">]</span>
</span><span class='line'><span class="c"># Beispiel</span>
</span><span class='line'><span class="nv">$ </span>rails g active_admin:resource news
</span></code></pre></td></tr></table></div></figure>


<p>Das neue Model ist nun in <code>app/admin</code>zu finden. ActiveAdmin löst Relationen zwischen ActiveRecord-Entitäten automatisch
selbst auf und konvertiert die jeweiligen Spaltentypen in sinnvolle HTML-Input-Felder. ID-Relationen werden somit zu
Dropdown-Selects, Strings zu Input-Text-Feldern, Booleans zu Checkboxen und Texte zu Textareas.</p>

<p><img class="center" src="http://www.mario-behrendt.de/images/posts/activeadmin-1.png" title="&#34;Backend-Ansicht&#34;" alt="&#34;Backend-Ansicht&#34;"></p>

<p>Wenn man nun im Browser die Rails-App aufruft erhält man bereits ein funktionsfähiges Backend, samt Menü und einer
Kommentarfunktion. In den nächsten Tagen werde ich weitere Artikel zur Konfiguration und Anpassung des Interfaces
veröffentlichen. Eins sei schon vorn weg gesagt:</p>

<p>Sowohl das Grid als auch Detailseite, Formulare, Menüs und Dashboard
lassen sich sehr einfach und flexibel anpassen. Scopes sind außerdem wunderbar als One-Klick-Filter einsetzbar.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[MongoDB Indizes]]></title>
    <link href="http://www.mario-behrendt.de/2012/01/12/mongodb-indizes/"/>
    <updated>2012-01-12T08:34:00+01:00</updated>
    <id>http://www.mario-behrendt.de/2012/01/12/mongodb-indizes</id>
    <content type="html"><![CDATA[<p>In diesem Post möchte ich kurz auf das Indizieren einer <a href="http://www.mongodb.org" title="MongoDB">MongoDB</a>-Collection eingehen und welche
Performanceauswirkungen dies haben kann. Zum Test habe ich 1 Mio. Datensätze nach dem Schema <code>{ _id: ..., value : i
}</code> durch eine <code>for</code>-Schleife (ja Mongo kann mit reinem Javascript bedient werden) angelegt.</p>

<figure class='code'><figcaption><span>Mongo in der Konsole öffnen</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>mongo performancetest
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>Testdaten anlegen</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="o">&gt;</span> <span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="mi">1000000</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="nx">db</span><span class="p">.</span><span class="nx">Example</span><span class="p">.</span><span class="nx">save</span><span class="p">({</span> <span class="nx">value</span><span class="o">:</span> <span class="nx">i</span> <span class="p">});</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Dieser Vorgang kann je nach Rechner einige Sekunden dauern. Danach kann man das Ergebnis mit einem Aufruf von <code>count</code>
überprüfen.</p>

<figure class='code'><figcaption><span>Testdaten prüfen</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="o">&gt;</span> <span class="nx">db</span><span class="p">.</span><span class="nx">Example</span><span class="p">.</span><span class="nx">count</span><span class="p">()</span>
</span><span class='line'><span class="mi">1000000</span>
</span></code></pre></td></tr></table></div></figure>


<p>Um jetzt die zeitlichen Unterschiede zwischen einer Query ohne Index und einer mit zu ermitteln, bietet sich der
Profiler an, welcher über folgende Methode gestartet werden kann.</p>

<!-- more -->




<figure class='code'><figcaption><span>Profiler aktivieren</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="o">&gt;</span> <span class="nx">db</span><span class="p">.</span><span class="nx">setProfilingLevel</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
</span><span class='line'><span class="p">{</span> <span class="s2">&quot;was&quot;</span> <span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&quot;slowms&quot;</span> <span class="o">:</span> <span class="mi">100</span><span class="p">,</span> <span class="s2">&quot;ok&quot;</span> <span class="o">:</span> <span class="mi">1</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Zu beachten gilt hierbei, dass im Loglevel 2 <strong>alle</strong> Queries geloggt werden. Wer nur langsame Queries loggen möchte,
kann dies mit dem Loglevel 1 und der Angabe einer Grenze bewerkstelligen.</p>

<figure class='code'><figcaption><span>Nur Slow-Queries loggen</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="o">&gt;</span> <span class="nx">db</span><span class="p">.</span><span class="nx">setProfilingLevel</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">20</span><span class="p">);</span>
</span><span class='line'><span class="p">{</span> <span class="s2">&quot;was&quot;</span> <span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&quot;slowms&quot;</span> <span class="o">:</span> <span class="mi">100</span><span class="p">,</span> <span class="s2">&quot;ok&quot;</span> <span class="o">:</span> <span class="mi">1</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Der obige Code weist den Profiler an nur Queries zu loggen, die länger als 20ms benötigt haben. Für meinen Test habe ich
Level 2 genutzt, um wirklich alle Vorgänge einsehen zu können. Wenn man nun eine Query auf einen bestimmten Eintrag abfeuert:</p>

<figure class='code'><figcaption><span>Query</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="o">&gt;</span> <span class="nx">db</span><span class="p">.</span><span class="nx">Example</span><span class="p">.</span><span class="nx">find</span><span class="p">({</span> <span class="nx">value</span><span class="o">:</span> <span class="mi">555</span> <span class="p">})</span>
</span><span class='line'><span class="p">{</span> <span class="s2">&quot;_id&quot;</span> <span class="o">:</span> <span class="nx">ObjectId</span><span class="p">(</span><span class="s2">&quot;4f0c85b6f449de5f6c4c365c&quot;</span><span class="p">),</span> <span class="s2">&quot;value&quot;</span> <span class="o">:</span> <span class="mi">555</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Kann man im Profiler sehr schön die entsprechenden Einträge beobachten (Ausgabe verkürzt auf die relevanten Inhalte).</p>

<figure class='code'><figcaption><span>Profiler-Ausgabe ohne Index</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="o">&gt;</span> <span class="nx">db</span><span class="p">.</span><span class="nx">system</span><span class="p">.</span><span class="nx">profile</span><span class="p">.</span><span class="nx">find</span><span class="p">({</span> <span class="s2">&quot;query.value&quot;</span> <span class="o">:</span> <span class="mi">555</span> <span class="p">})</span>
</span><span class='line'><span class="p">{</span> <span class="s2">&quot;query&quot;</span> <span class="o">:</span> <span class="p">{</span> <span class="s2">&quot;value&quot;</span> <span class="o">:</span> <span class="mi">555</span> <span class="p">},</span> <span class="s2">&quot;nscanned&quot;</span> <span class="o">:</span> <span class="mi">1000000</span><span class="p">,</span> <span class="s2">&quot;nreturned&quot;</span> <span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="s2">&quot;millis&quot;</span> <span class="o">:</span> <span class="mi">825</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Wichtig ist neben der Query selbst, um diese zu identifizieren, der Wert <code>nscanned</code>, der angibt wie viele Datensätze
gelesen werden mussten, um den gewünschten Eintrag zu finden. Unter <code>nreturned</code> versteht man die Anzahl von gefundenen
Einträgen, ganz wie zum Beispiel die von <a href="http://www.mysql.de" title="MySQL">MySQL</a> bekannten <em>Rows affected</em>. Für meinen Test am wichtigsten ist
allerdings der Wert <code>millis</code>, der - wie zu vermuten - die Dauer der Query in Millisekunden enthält (der Wert ist
übrigens gerundet). 825 Millisekunden für einen einfachen Find ist schon grenzwertig, also auf zum Indizieren!</p>

<figure class='code'><figcaption><span>Index hinzufügen</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">db</span><span class="p">.</span><span class="nx">Example</span><span class="p">.</span><span class="nx">ensureIndex</span><span class="p">({</span> <span class="nx">value</span><span class="o">:</span> <span class="mi">1</span> <span class="p">})</span>
</span></code></pre></td></tr></table></div></figure>


<p><code>ensureIndex()</code> prüft ob bereits ein Index auf der angegebenen Spalte liegt und erstellt diesen, falls keiner gefunden
wurde. Die 1 bedeutet einfach nur soviel wie &#8220;Ja, diese Spalte sollte einen Index haben&#8221;. Dieser Vorgang kann je nach
Größe der Collection ebenfalls einige Sekunden, bei sehr großen Datenmengen auch mehrere Stunden dauern.</p>

<p>Wenn man die oben genannte Query nun nochmals ausführt, zeigt sich einem ein vollkommen anderes Bild in den Profiler
Logs:</p>

<figure class='code'><figcaption><span>Profiler-Ausgabe mit Index</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="o">&gt;</span> <span class="nx">db</span><span class="p">.</span><span class="nx">system</span><span class="p">.</span><span class="nx">profile</span><span class="p">.</span><span class="nx">find</span><span class="p">({</span> <span class="s2">&quot;query.value&quot;</span> <span class="o">:</span> <span class="mi">555</span> <span class="p">})</span>
</span><span class='line'><span class="p">{</span> <span class="s2">&quot;query&quot;</span> <span class="o">:</span> <span class="p">{</span> <span class="s2">&quot;value&quot;</span> <span class="o">:</span> <span class="mi">555</span> <span class="p">},</span> <span class="s2">&quot;nscanned&quot;</span> <span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="s2">&quot;nreturned&quot;</span> <span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="s2">&quot;millis&quot;</span> <span class="o">:</span> <span class="mi">0</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Es wurde nur 1 Eintrag gescanned und die Query dauerte 0 Millisekunden. Die 0 ist natürlich ebenfalls gerundet, aber man
sieht sehr schön wie viel ein Index in einer MongoDB ausmachen kann. Sicher handelt es sich bei meinem Beispiel nicht um
Real World-Daten, doch unterm Strich kann man sagen:</p>

<p>Das Slow Query-Log sollte in regelmäßigen Abständen auf Bottlenecks geprüft werden. Durch gezieltes Indizieren und
Testen der Auswirkungen kann viel Rechenzeit auf dem Server und somit Zeit für den User gespart werden. MongoDB
reagiert mit extremen Performancesteigerungen durch wenige Änderungen an den Indizes - warum diese Möglichkeit also
nicht komplett ausreizen?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Fehler beim Upgrade von MySQL 5.0 auf 5.1]]></title>
    <link href="http://www.mario-behrendt.de/2012/01/05/fehler-beim-upgrade-von-mysql-5-dot-0-auf-5-dot-1/"/>
    <updated>2012-01-05T09:16:00+01:00</updated>
    <id>http://www.mario-behrendt.de/2012/01/05/fehler-beim-upgrade-von-mysql-5-dot-0-auf-5-dot-1</id>
    <content type="html"><![CDATA[<p>Als ich diese Woche ein neues Projekt deployt habe ist mir aufgefallen, dass mein guter alter Debian-Root-Server noch
auf <a href="http://www.mysql.de" title="MySQL">MySQL</a> 5.0 läuft - die Applikation allerdings 5.1 voraussetzt. Upgrade? Klar doch!</p>

<p>Leider lies sich der MySQL-Server nach dem Upgrade nicht mehr hochfahren, was zur Folge hatte das mehr als zehn meiner
Webseiten nicht mehr erreichbar waren:</p>

<figure class='code'><figcaption><span>Apt-Get Ausgabe</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>mysql-server-5.1 <span class="o">(</span>5.1.49-3<span class="o">)</span> wird eingerichtet ...
</span><span class='line'>Stopping MySQL database server: mysqld.
</span><span class='line'>Starting MySQL database server: mysqld . . . . . . . . . . . . . . failed!
</span><span class='line'>invoke-rc.d: initscript mysql, action <span class="s2">&quot;start&quot;</span> failed.
</span><span class='line'>dpkg: Fehler beim Bearbeiten von mysql-server-5.1 <span class="o">(</span>--configure<span class="o">)</span>:
</span><span class='line'>  Unterprozess installiertes post-installation-Skript gab den Fehlerwert 1 zurück
</span><span class='line'>dpkg: Abhängigkeitsprobleme verhindern Konfiguration von mysql-server:
</span><span class='line'>  mysql-server hängt ab von mysql-server-5.1; aber:
</span><span class='line'>  Paket mysql-server-5.1 ist noch nicht konfiguriert.
</span><span class='line'>dpkg: Fehler beim Bearbeiten von mysql-server <span class="o">(</span>--configure<span class="o">)</span>:
</span><span class='line'>  Abhängigkeitsprobleme - verbleibt unkonfiguriert
</span><span class='line'>Fehler traten auf beim Bearbeiten von:
</span><span class='line'>  mysql-server-5.1
</span><span class='line'>  mysql-server
</span></code></pre></td></tr></table></div></figure>


<p>Ein kurzer Blick in das <code>syslog</code> zeigte folgenden Eintrag:</p>

<!-- more -->




<figure class='code'><figcaption><span>Log</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>Can’t open the mysql.plugin table. Please run mysql_upgrade to create it.
</span></code></pre></td></tr></table></div></figure>


<p>Diese fehlende Tabelle könnte theoretisch via <code>mysql_upgrade</code> angelegt werden - dazu müsste aber der MySQL-Server
laufen. Die eigentliche Fehlerbehebung fand dann in der <code>my.cnf</code> statt, die offensichtlich veraltete Einträge enthielt.</p>

<figure class='code'><figcaption><span>Fehlerbehebung</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># Backup anlegen</span>
</span><span class='line'>cp /etc/mysql/my.cnf /etc/mysql/my.cnf.backup
</span><span class='line'>
</span><span class='line'><span class="c"># Alte Version mit neuer ersetzen</span>
</span><span class='line'>cp /etc/mysql/my.cnf.dpkg-dist /etc/mysql/my.cnf
</span><span class='line'>
</span><span class='line'><span class="c"># MySQL-Server starten</span>
</span><span class='line'>/etc/init.d/mysql start
</span></code></pre></td></tr></table></div></figure>


<p>Danach sollte der Server wieder korrekt hochfahren und ordnungsgemäß funktionieren. Alternativ kann man natürlich auch
ein <code>diff</code> machen - ich hatte aber keine wichtigen Anpassungen gemacht und war somit mit dem Überschreiben der
Konfiguration zufrieden.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Grafische Git Logs im Terminal]]></title>
    <link href="http://www.mario-behrendt.de/2012/01/04/grafische-git-logs-im-terminal/"/>
    <updated>2012-01-04T07:36:00+01:00</updated>
    <id>http://www.mario-behrendt.de/2012/01/04/grafische-git-logs-im-terminal</id>
    <content type="html"><![CDATA[<p><a href="http://git-scm.com" title="Git SCM">Git</a> ist schon lange zum Liebling der Entwicklergemeinde avanciert. Doch viele arbeiten nur mit den Git
Grundbefehlen oder nutzen nicht deren reichhaltigen Fundus an Flags und Attributen.</p>

<p>Ein schönes Beispiel dafür ist die Verwendung von <code>git log</code>. Die meisten werden es nur einsetzen um die letzten
Commits und deren Committish abzufragen. Doch man kann es auch einsetzen um eine mehr oder weniger grafische
Repräsentation der Historie zu erhalten. Für Freunde der Kommandozeile sicherlich ein interessantes Feature:</p>

<figure class='code'><figcaption><span>Grafisches Git Log</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>git log --pretty<span class="o">=</span>oneline --abbrev-commit --graph --decorate
</span></code></pre></td></tr></table></div></figure>


<p>Das Ergebnis könnte dann wie folgt aussehen.</p>

<!-- More -->


<p><img class="left" src="http://www.mario-behrendt.de/images/posts/gitlog-output.png" title="&#34;Git Log Output&#34;" alt="&#34;Git Log Output&#34;"></p>
]]></content>
  </entry>
  
</feed>
