August 30th, 2009

Howto Auto Deploy Rails Apps After Git Push

For my most recent project, I had to share a git repository with another Rails developer. He also had to make deploys on my server. As my server has many projects, I though about having another way than giving him access via SSH for cap deploy.

I remembered Heroku automatically deploys Rails apps after commits. So here’s how you can have the same functionality with pure Git.

Configuration of SSH And Users

I’m assuming the following configuration:

# Git repository:
/home/git/awesome-rails-app.git
# Deploy path:
/var/www/awesome-rails-app
# Git user: 
git
# Deploy user:
deploy
# Authentication with SSH keys

First, create a SSH key for the user git (unless you already did so) and add it for for the deploy user and vice versa:

# log in as git:
ssh-keygen -t rsa
# log in as deploy:
cat /home/git/.ssh/id_rsa.pub >> /home/deploy/authorized_keys
ssh-keygen -t rsa
# log in as git:
cat /home/deploy/.ssh/id_rsa.pub >> /home/git/authorized_keys

Installing the Git Hook

Git offers some hooks, where you can add your own code. The most interestion hook for having a deploy is “post-receive”. Just add the deploy command:

# File: /home/git/awesome-rails-app.git/hooks/post-receive
#!/bin/sh
 
cd /var/www/awesome-rails-app/current && cap deploy:migrations
 
## If Git isn’t on the same server as the application:
# ssh deploy@deploy-server.com \
#   'cd /var/www/awesome-rails-app/current && cap deploy:migrations'
## Don’t forget to add the SSH keys.

Make this file executable:

chmod +x /home/git/awesome-rails-app.git/hooks/post-receive

Finish

Now it should work:

# on your local mashine:
git push origin master

You’ll see all commands of the cap deploy:migrations process in your console.

This post was inspired by this post. After you finished the automatical deploy, there is some other interesting homework: auto test before commits, integration your bug tracker, …

August 10th, 2009

How to Use GMail With WordPress

WordPress uses the PHP function mail() as default for sending e-mails such as comment notifications. However sendmail isn’t configured on my server. So I used the WordPress plugin WP Mail SMTP till now. Unfortunately it won’t work with Google’s GMail—which is a problem for me, after I switched to GMail.

There’s another WordPress plugin out there: It’s called “Cimy Swift SMTP” and works well with GMAIL, TLS and SSL connections. Give it a try!

WordPress plugin for GMail mail and TLS/SSL connections

June 3rd, 2009

Designing Twitter Profiles (German)

For Gemany’s monthly corporate twitter event Twittwoch I made a presentation about designing twitter profiles. Currently it’s available in German only.

Follow @twittwoch for more updates :)

May 16th, 2009

4 Useful HTML5 Browser Support Overviews

HTML5 gives us many advantages. You can use the basic HTML5 elements like header, nav and footer in all browser at the moment. But there are more cool things like canvas, SVG or client side JavaScript databases.

While surfing I’ve found four different great overviews about XHTML5 / HTML5 browser support of all features. I’ve tweeted some of them already on my Twitter account @Hagenburger —just follow me :)

1. “When Can I Use …?”

html5-overview-when-can-i-use-html5-browser-support

Alexis Deveria answers the question “When can I use …?” for HTML5 and made a great overview for “Compatibility tables for features in HTML5, CSS3, SVG and other upcoming web technologies”. You can even filter the table:

html5-overview-when-can-i-use-html5-browser-support-filter

Go to: a.deveria.com / caniuse / 

2. HTML5 Comparison of Layout Engines by Wikipedia

html5-overview-wikipedia-layout-engines-browser-support

The English version of Wikipedia contains a comparison by layout engine—the render engines for each browser. The table shows Trident, Gecko, WebKit and Presto, the engines of Internet Explorer, Firefox / Mozilla, Safari / Chrome and Opera. They are grouped by Web Forms 2.0 and Web Applications 1.0 (elements, attributes, …).

Go to: en.wikipedia.org / wiki / Comparison_of_layout_engines_(HTML_5)

3. WHATWG’s “List of Known Implementations of HTML 5 in Web Browsers”

html5-overview-whatwg-browser-support

Just an unordered list. No table. But with all links to the specifications.

Go to: wiki.whatwg.org / wiki / Implementations_in_Web_browsers

4. WHATWG’s Sections

html5-overview-rgaucher-browser-support

Romain Gaucher made an overview with all sections by WHATWG. But at the moment it’s a bit incomplete.

Go to: rgaucher.info / pub / whatwg_html5_implementations.html

May 14th, 2009

New Twitter Avatar

Just changed my Twitter avatar this morning to make it a little bit more personal than showing just my h logo. Now it contains a photo of me (made from the top of my kitchen) and a small logo. Hope you like it. Just follow @Hagenburger to see it in action.

Twitter Avatar of Hagenburger

May 13th, 2009

Twittwoch: Tweetup & Logo

Today Berlin’s first Twittwoch will take place at Coffee Karma. The name “Twittwoch” is a German combination of “Twitter” and “Mittwoch” (= Wednesday). The event is organized by Stefan and me and promoted by Alexander. The hash tag is #twb.

Here’s the logo I designed for the Twittwoch:

twittwoch logo

April 16th, 2009

CSS Snipplets for TextMate

I’m a fan of TextMate and how easy it is to extend the functionality. You can write TextMate plugins in ruby or any other language. But today I want to show you two simple snipplets I use in my everyday life.

TextMate snipplets have a great feature: the repeater—each time you type, TextMate retypes the character at another place. You can set them up like:

  I have 2 red $1 and 5 green $1.

When you add a tab trigger (p. e. “ihave” + TAB) TextMate inserts the text and places the cursor at $1. While you’re typing “apples” the same text (“apples”) will appear at the second $1 position.

For those who are not familiar with snipplets yet: You can add an snipplet just as easy as:

  1. Go to Bundles > Bundle Editor > Show Bundle Editor

  2. Choose the language (“CSS” in our case)

  3. Click at the plus button in the lower left and choose New Snipplet

  4. Choose Activation: “Tab Trigger” and type in “ihave” in the field at the right side

  1. Be sure to click anywhere else in the list on the left side—TextMate saves your changes when you leave the new snipplet

    So here’s the first example:

    1. Border Radius for Safari and Firefox

    If you want to use the CSS 3.0 feature border-radius you have to do this several times to tell all the browsers—OK, currently only Safari and Firefox will support it:

    .radius-test
    {
      -moz-border-radius: 12px;
      -webkit-border-radius: 12px;
      -khtml-border-radius: 12px;
      border-radius: 12px;
    }

    Insteat of typing all this you can use a snipplet:

    -moz-border-radius: $1px;
    -webkit-border-radius: $1px;
    -khtml-border-radius: $1px;
    border-radius: $1px;

    By the way: TextMate will choose the right indentation automatically. Your bundle editor should like this:

    TextMate’s bundle editor for a CSS snipplet with tab trigger

    2. Clearfix

    This clearfix will expand a box without float to the height of all children—even if the have floats.

    /* For all browsers except IE6 */
    .clearfix:after
    {
      clear: both;
      content: ".";
      display: block;
      height: 0;
      visibility: hidden;
    }
     
    /* For IE6 */
    .clearfix
    {
      _height: 1%;
    }

    My snipplet contains everything in one line because I wouldn’t change anything. As a tab trigger name I chose “:after”.

    $1:after{clear:both;content:".";display:block;height:0;visibility:hidden}$1{_height:1%}

    Whatever class or element you type at the beginning, it will be repeated for the IE6 block.

    I hope this was usefull and inspires you for your own snipplets.

April 6th, 2009

How to Get to Baku? (And How to Get Back?)

Baku. Capital of Azerbaijan. Home of Barcamp Caspian.

When I first heard of the barcamp, I didn’t hesitate to decide: I must go there. For me another unknown country—I try to explore at least one new country every year. For the last year it was Latvia, this year it should be Azerbaijan. Hopefully.

Barcamp Caspian logo/Baku Azerbaijan

How to get to Baku?

It was Tuesday. Three days to the opening party of Barcamp Caspian. I finally decided to go there. A few hours later my passport proved not to be valid any more. OK. What could be done? For Azerbaijan you need a visa, for a visa you need a passport.

Let’s try Google. I found out: there’s a “temporary passport” and a “quick passport”. You’ll get the “quick passport” within some days (“some” maybe more than three—too long for me). The “temporary passport” will take less than an hour. Nice :) But you need “some reason” to get it. A valid flight ticket and an official invitation are “some reasons”.

But will the Azeris accept a temporary passport? I inquired about it at (the German) ministry of foreign affairs. “Don’t know.” I phoned the Azeri embassy. “What? Don’t know.” Finally I recieved an e-mail from the German embassy in Baku. “We know some some guys. Yes, it will work.” Yeah. Let’s go.

To get a temporary passport (DE: “vorläufiger Reisepass”), you need to buy the ticket first und must have an invitation. OK. The 1st website to book the flight had internal server errors. The 2nd one worked as expected. So I hurried to the town hall and one hour later I got all the documents! The flight was easy, Moscow airport smoky and the Azeri police friendly when issuing the visa.

Barcamp Caspian

When I left the airport, the great service of the Barcamp Caspian organization team started: they picked me up. Later we walked through the old city of Baku—OK, they talked a little bit too much russian, so I kept my eyes open and enjoyed the town. In the evening, we had an awesome opening party. Everyone was dancing, talking and open-minded to new people. The party climaxed when they played Moscow never sleeps and the Caucasian song Lezginka

The next day we went to Qafqaz Universiteti where the sessions took place. Most of the presentations are linked on the official Barcamp Caspian blog. I’ve reported about it on the German blog of 13. Stock Online Relations

attendees of the Barcamp Caspian in Baku/Azerbaijan

We learned a lot about Delta Telecom, Google and Opera the next day. And a lot more about people and foreign countries while making small talk. I’ve pleasure to welcome all new friends from Azerbaijan, Russia, Ukraine, Belarus, Turkey, Spain, Estonia, Kazakhstan and Kyrgyzstan—in real life as well as on Facebook.

And how to get back?

My return was difficult. Two ladies at the airport were hacking the computer for half an hour to get my boarding pass. I didn’t know the problem. They didn’t inform me. So time ran by and they were talking in unknown languages and all my friends had already passed the passport control. I was allowed to pass about 20 minutes later. Without a boarding pass.

Next stop Moscow. Same procedure as before. “Your boarding pass?”—“They did’t gave me.”—“Please look in your bag.”—“They did’t gave me.”—“Please look in your bag.”—“They did’t gave me.”—“My computer tells me they printed it at 2 pm.”—“They did’t gave me.”—“OK, have you got a luggage pass?”—“Here you are.”

15 minutes later, after several Russian phone calls, she was so kind to me and printed out my boarding pass to Berlin.

I really had a cool time in Baku—thanks to the perfect organization and thanks to Aeroflot for the entertainment :)

March 14th, 2009

New Facebook Logo Announced

Facebook recently redesigned it’s homepage. For most of us, it looks quite familiar—it looks just a small tiny little bit like twitter. So isn’t it time for facebook to think about a logo redesign? My suggestion for the new facebook logo is:

New facebook logo looks like twitter logo

Just kidding ;)

Do you like this logo? Maybe you’ll also like the bracamp logo

March 9th, 2009

HTML5 / XHTML5 with CSS for Safari, Firefox, Opera & IE

As I started a new WordPress theme, the time was right to do this in XHTML5.

1. The XHTML5 header / head

The doctype is much easier now. And it’s the first time for me to write it by hand and not via copy ’n’ paste. The doctype is as simple as:

<!DOCTYPE html>

2. Structuring the content with “header”, “nav”, “article” and “footer”

Most of the (X)HTML pages have a header, a navigation and a footer. In between there’s the content. We used to classify them by giving them IDs:

<div id="head">
  <ul id="nav">[...]</ul>
</div>
<div id="content">
  [...]
</div>
<ul id="footer>[...]</ul>

XHTML5 introduced special tags for this areas—so they will be more accessible for people and search engines:

<header>
  <nav>[...]</nav>
</header>
<article>
  [...]
</article>
<footer>[...]</footer>

Looks cooler. But what about the browsers? Peter Kröner did some tests: Safari, Firefox 3.0 and Opera don’t have any problems. Firefox 2.0 has some but most people already use 3.0 and up. But styling in Internet Explorer isn’t possible because IE handle those tags as inline elements—they can’t have children.

One solution is to use the XHTML5 semantic elements and some DIV overhead to make them work in IE:

<div id="header"><header>
  <div id="nav"><nav>[...]</nav></div>
</header></div>
<div id="article"><article>
  [...]
</article></div>
<div id="footer"><footer>[...]</footer></div>

That’s semi cool. After searching the web, I found a tricky solution for IE. If you create those elements via JavaScript, they’ll also work in Internet Explorer. But who want’s to create a whole website in JavaScript? But there’s an IE bug, no let’s call it “feature”. If you create only one @

@ element via JavaScript, all others will work fine with CSS. Even if you don’t add it to the DOM tree. Even in IE6. Just call:

document.createElement('header');

3. Putting it all together

The prototype XHTML5 which will work in Safari, Firefox 3.0 and up, Opera and even Internet Explorer would look like this:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <title>My first XHTML5 website</title>
     <script type="text/javascript">
       document.createElement('header');
       document.createElement('nav');
       document.createElement('article');
       document.createElement('section');
       document.createElement('footer');
     </script>
  </head>
  <body>
    <header>
      <a href="/">Welcome to my XHTML5 test page</a>
      <nav>
         <a href="/>Home</a>
         <a href="/about>About</a>
      </nav>
    </header>
    <article>
       <section>
          <h2>XHTML5 section 1</h2>
          <p>[...]</p>
       </section>
       <section>
          <h2>XHTML5 section 2</h2>
          <p>[...]</p>
       </section>
    </article>
    <footer>
       This XHTML5 test page has been created by Nico Hagenburger
    </footer>
  </body>
</html>

Some remarks:

  • I’ve used both @lang@ and @xml:lang@ because I had some problems with Google, when I used @xml:lang@ only.
  • You could use conditional comments for MSIE

    4. CSS styling of HTML5 elements

    Just do it the way you would expect it—after calling @document.createElement@ you can use this CSS even in IE 6.0 and IE 7.0.

    header
    {
      background: yellow;
      display: block; /* inline is the default */
    }
    header a
    {
      color: red;
    }

    Summary

    HTML5 / XHTML5 works quite well, makes your code more readable, accessible and your website is made as state of the art. The code will work in most browsers:

    Browser Does is work?
    Safari 3.1 yes
    Firefox 2.0 yes with HTTP header “Content-type: application / xhtml+xml” 
    Firefox 3.0 yes
    Opera 9.0+ yes
    MSIE 6.0 yes with JavaScript only
    MSIE 7.0 yes with JavaScript only

    Update: Firefox 2.0 (April 3rd, 2009)

    I found a solution to solve it in Firefox 2.0 (I think it is working for Firefox 1.0 and 1.5, too). You need to set the HTTP header to “Content-type: application / xhtml+xml”. But be careful. IE will not work with this solution and the document must be valid. Here’s a simple PHP code for doing this:

    if (strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox/')) {
      header("Content-type: application/xhtml+xml");
    }

    Update (April 9th, 2009)

    I’ve added the “content-type” meta tag as suggested by “blabberstar.com” (see comments).

 Page 1 of 3 123»