Med fokus på din virksomheds forretningsgange watermark with eaktion circles

How (not) to write (Drupal) documentation

April 30th, 2012

I was going to write a very angry and very long post about documentation, about how documentation is provided generally and why it doesn’t work. About the kind of mentality that drives programmers to again and again write documentation that drives other developers crazy. I wanted to give a couple of examples taken from the 2 open source projects that I have easy at hand: Drupal and YAHOO! YUI.  And I was getting more and more angry as I ploughed my way through my current Drupal project. Then I realized that it would not have done much good to pour out my wrath onto the waves of the net just to add frustration to more frustration. So I decided to do something more constructive and possibly to enhance the net with a piece of documentation as I would have liked it.

I hope though that someone will also get the point of why documentation should be done differently.

How (not) to write documentation

In brief, I’ve come to the conclusion that there are two major reasons why documentation generally sucks:

  1. Wrong assumption about who is using it
  2. A bottom up approach

Often the 2 reasons are both present

1. Wrong assumptions

It is understandable that it is difficult to guess who the reader might be, the reader on internet might be anyone and in many cases she or he will belong to the ”wrong” target. However, statistically that should leave me with a great amount of docs that are all too easy to use, as I’m no longer a novice, I’m no longer an intermediate, well yes I’m pretty seasoned and been through a lot. How come then that it still happens to me to use way too much time to find what it appears to me as the sheer basics in order to be able to use a piece of software.
Often there are just no assumptions at all about who the user is, the authors just spit out all what they have in their mind in the hope that the more the better (no it is not like that, I know, but it feels like that).

2. Bottom up

Bottom up approach is given naturally by the use of documentation systems (javadoc, doxygen, phpdoc you name it). It’s fine and swell, all your functions and methods are there on the web, all class relationships are documented. That’s great, you didn’t forget any field and neglect any method or class, then it is complete.

What are you complaining about?

What am I complaining about? The contributors have also written lots of examples from where you can monkey code all the way, “cause you are a monkey aren’t you?”

Actually I am a control freak, I want to know why I’m doing what I’m doing, I want to know that what I’m doing cannot be done another way and, if it can be done differently, that there is a reason why I’m doing it this way and not the other.
Also, I want only to do what is absolutely necessary, not one line more, no more complexity than it is required by my goals. To be able to do this I don’t need to be told how to do this and that (although  that also comes in handy).

Where are stairs, elevators and ramps?

What I need, is to have an overview of the whole system; I need to know the architecture.
When I know that the building has both elevators and staircases, I can decide by myself whether or not I need to know the staircase dimensions or the elevator’s capacity to choose the one or the other. Telling me every single detail about, say, the elevator, won’t do any good, if you don’t let me know that there is also a staircase, and maybe even a ramp all around the building. Still less useful will be to describe the bricks the building is made of, or the wonderful new material the whole thing is built with.

When I have this knowledge (elevator/staircases), only then it will be interesting to know the elevator door orientation or whether the staircase is straight or spiral and all the other details. And one thing is for sure, what I need to know will always proceed from general to particular aspects. Top down, not bottom up. Following a hierarchy, not a sequence of topics, however systematic it may be.

I find the building metaphor pretty good to use as a double check to see whether your documentation project is living up to my (or many’s?) expectations.

Now, what triggered my anger  this time was the need to write a Drupal module. There are gazillions of pages on the Drupal site that document Drupal, and yet I’m not satisfied.

And it seems I’m not alone (some examples here):

“…and the documentation was sparse at best, so it took me quite a bit of digging to find that it was really this simple to do…”

“…Its sad to say that I seem to learn more from people’s blogs like this than from the official docs / handbook…”

“…After 2 hours of digging around, sorting through posts with no replies, and getting quite frustrated, I found out what I wanted could be done in just a few lines of code very easily….”

Here is how I would have expected to find some documentation about: How To Write And Manage A Drupal Module (link to new article to come in a very near future).

Pure CSS Folded Corners

March 5th, 2012

A few days ago I stumbled upon this post by Nicolas Gallagher about making folded corners with css only. I love the result and the pure css approach.

Only, I noticed a problem in Chrome (mine says: Chrome 17.0.963.56 m, I’ve seen it also in 17.0.963.65 m) where for rounded corners the folded corner does not work (the triangle, that is supposed to be background color, is foreground color instead).

Here I show a quick, not-so-perfect fix that does the job.

I noticed that the flaw happens when the radius is equal or smaller than the border thickness. My solution is therefore, only for webkit browsers, to use a border radius that is 1 px wider than the border. In this way the folded corner has a different shape than the others, however it is still better than a flawed effect. And in the end, the folded corner is naturally worn out by folding it, isn’t it,  so I don’t see anything strange about it having a bit “flossy” edges.

To see the whole css code for the folded corners please read the original post by the author. You’ll see the flaw in the demo, not in the explanation post, because the latter shows a picture of the note.

Below, an excerpt of the css code as in the original version (comments are mine)

.note.rounded:before {
    border-width:8px;
    border-color:#fff #fff transparent transparent;
    -webkit-border-bottom-left-radius:5px;/* Chrome flaw */
    -moz-border-radius:0 0 0 5px;
    border-radius:0 0 0 5px;
}

And here, the css code as in the fixed version (change the radius and move the web-kit version only, below the others)

.note.rounded:before {
    border-width:8px;
    border-color:#fff #fff transparent transparent;
    -moz-border-radius:0 0 0 5px;
    border-radius:0 0 0 5px;
    -webkit-border-bottom-left-radius:9px;
/*
    in Chrome, radius must be 1
    px wider than border-width
    otherwise the bg colour is not shown
*/
}

YUI3ROB forum

February 29th, 2012

On February 24th I’ve published version 0.5 of the rollout file builder for JavaScript files, written for and with YUI 3. This version is a nice enhancement to this tool, among others:

  • it  allows now to build several components at once and store their configuration into the browser.
  • It has a CLI script that allows to rebuild the component after each change to the source code

Use this blog post to add your comments, request for help  or enhancement to the YUI3ROB.

To avoid spam the blog is moderated. Your comment is added after approval.

Connecting Access to MySQL through a SSH tunnel using Putty and port forwarding

December 25th, 2011

I’m publishing today this article that is some years old and was just collecting dust in my drawer. I believe it can still be useful to many. In particular the problem I’m going to solve is about the MySql error:

Connection failed: [08S1][MySQL][ODBC 5.1] Lost connection to MySQL server at ’reading initial communication packet’

Just paste the title of the post in a Google search box and you’ll get plenty of tutorials for how to set up Putty to do this.

The reason why I add something to the argument, is that after having used tunneling to connect to a MySQL RDBMS for some years, the day came when my settings didn’t work any longer. I used a fair amount of hours to find a solution to the problem and Google was only helpful to exclude other solutions. There’s no reason why you should do the same.

The error I got when testing the connection from the Connector configuration window was:

Connection failed: [08S1][MySQL][ODBC 5.1] Lost connection to MySQL server at ’reading initial communication packet’, system error: 2

If you google the Internet to find a solution to this error, you will probably come to the conclusion that something is wrong with your firewall settings or your network connectivity. Many times the solution given to solve problems that lead to the same error message, is to correct the server connect_timeout from the once default 5 (seconds) to a higher time span.

However this was definitely not the culprit in my case.

My setup

Now, before we go on to read about the mistake I made and the solution, I’d better add some details about the setup I’m working with. In a different setup you might have to use somewhat different settings.

I’m connecting to a MySQL server on a Linux box (Debian etch), from Windows XP / Vista.
The tunnel (port forwarding over SSH) is done using Putty.

What is important to notice for this text to be valid is the fact that MySQL runs on Linux and not on Windows.

The wrong tunnel configuration

The mistake is shown in this picture showing Putty tunnel configuration.

I had set the tunnel in such a way, to forward my local port to remote Linux box, port 3306 – writing the domain name, it could also have been the remote IP address. Now, this is not wrong in general and among the tutorials you’ll find on the Internet many recommend this setting. On the other hand the tunnel had been working fine for some years, and it would have gone on for more years if I hadn’t switched to a different server.

DSN configuration

Before we come to why this setting in fact is a mistake we’ll also have a look at another of the settings needed for the Access-MySQL connection to work, the DSN settings.

As you might know, here we set the data source as being the

local port (2306 in my case, different from MySQL default port 3306 to avoid conflicts with a possible MySQL for Windows installed on my PC) that we want to forward to the remote MySQL server. The setting under “Server” must be 127.0.0.1 in most of the cases. The reason is that your /etc/mysql/my.cnf file will have a line:

bind-address            = 127.0.0.1

This tells the server to only allow connection from the localhost, that is from users of the same Linux box, not connecting from outside. This line is default in a Debian distribution, and I believe it’s default in many other distros too. It avoids to expose the server to all possible connection attempts from black hat guys on the Internet. This is actually one of the reasons why we do SSH tunneling in the first place.

When you have logged into your server through Putty, your server is no longer remote, and that’s why 127.0.0.1 here doesn’t prevent the connection, and at the same time you comply with what is written in the option file (bind-address   = 127.0.0.1).  What happens is that all what you send to your local port will be transferred by Putty to the corresponding port on what “was” the remote server. MS Access or any other application using that port will never know.

This setting is shown correctly in all the tutorials, I have seen on the Internet.

Why the Tunnel configuration was wrong

However one could ask, whether or not we need to write the remote address or the localhost address in the tunnel configuration, not all the tutorials agree on this point. And in fact the answer is that we don’t need to write the remote address, or rather that we should avoid this: When Putty is establishing the port forwarding, it is already connected to your remote server, the connection happens between the two ports on the local and the remote server no matter if we write the local or the remote address in the tunnel settings, as long as it is a valid way of specifying it.

Putty doesn’t care, SSH doesn’t care, but MySQL does apparently care: as we have seen,

it will toss a: Connection failed: [08S1][MySQL][ODBC 5.1] Lost connection to MySQL server at ’reading initial communication packet’, system error: 2

To sum up

Summing up:

write the loopback address in the tunnel settings,

write the loopback address in the DSN setting

One last detail

Yes, one last thing remains to be explained and this is why on earth the “wrong” settings did work on my first server, and did no longer work when I used them on a new server?

Now, my explanation here is a fair amount more than plain guesswork, but still guesswork, however it makes sense to me and it is enough to let me sleep at night. It might satisfy you as well: I believe the reason is that on the first box (where the remote address didn’t hinder the connection) I had only one IP address on one network card. The OS was probably making its own translation of the remote address into the loopback address before MySQL received it. On the second box (where this setting stopped working) I had several IP addresses, and probably for this reason the remote address was no longer just translated by the OS into the loopback address for MySQL, and this triggered the connection error.

At least this will give you one more chance to find a solution to the problem, before blaming your firewall settings or network connectivity.

WordPress Plugin Shortcode Generator Not Saving Shortcodes

November 28th, 2011

Recently I needed the WordPress plugin “Shortcode Generator” for one of my customers. Unfortunately I experienced the same as others: the plugin seems to work but when you go back and see your newly created shortcode, all you get is: “There are no generated shortcodes defined”.

With this post I publish a fix for the problem. I’ll do the same on some of the posts that report the problem on the WordPress website.

Why the plugin does not save codes

The reason is that the shortcode table in the database is not created when the plugin is activated. The table is not created because the table schema triggers an error due to one of the indexes being too large. You don’t see the error as WordPress suppresses it, however the table is not there.

To solve the problem you have to repeat the following steps, briefly put:

  • add code to properly deactivate the plugin
  • fix the database schema
  • deactivate the plugin
  • reactivate the plugin
I assume here that you have already tried and activated the plugin.

Detailed step-by-step description

These four steps are easy to accomplish even for non programmers, just follow the  description below:

Open the plugin main file in a text editor. The file is located inside the folder wp-content/plugins/shortcode-generator/ and the name is shortcode-generator.php.

Inside your WordPress admin section, you can edit it from

plugins>editor>Select plugin to edit >Shortcode Generator >shortcode-generator/shortcode-generator.php

Find the “uninstall” function at around line 65

function uninstall(){

}

And change it into this:

function uninstall(){

    delete_option('scg_version');

}

Find the “install” function at line 43:

function install(){
    global $wpdb;
    require(ABSPATH.'/wp-admin/includes/upgrade.php');
    $installed_version = get_option('scg_version');
    if($installed_version == '' || $installed_version < SCG_VERSION){
        $create_table = "
        CREATE TABLE {$wpdb->shortcodes} (
        `ID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
        `shortcode` VARCHAR( 255 ) NOT NULL ,
        `value` LONGTEXT NOT NULL ,
        `type` VARCHAR( 255 ) NOT NULL ,
        UNIQUE (`shortcode`, `type`) ,
        FULLTEXT (
        `value`
        )
        )
        ";
        dbDelta($create_table);
    }
    add_option('scg_version',SCG_VERSION,'','no');
}

and change the definition of the “type” column to be 8 instead of 255. In this way Mysql will also have a better performance and since the types are only “wysiwyg” and “html”, both shorter than 8 chars, 8 is all you need.
The new “install” function looks like below:

function install(){
    global $wpdb;
    require(ABSPATH.'/wp-admin/includes/upgrade.php');
    $installed_version = get_option('scg_version');
    if($installed_version == '' || $installed_version < SCG_VERSION){
        $create_table = "
        CREATE TABLE {$wpdb->shortcodes} (
        `ID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
        `shortcode` VARCHAR( 255 ) NOT NULL ,
        `value` LONGTEXT NOT NULL ,
        `type` VARCHAR( 8 ) NOT NULL ,
        UNIQUE (`shortcode`, `type`) ,
        FULLTEXT (
        `value`
        )
        )
        ";
        dbDelta($create_table);
    }
    add_option('scg_version',SCG_VERSION,'','no');
}

Then deactivate the plugin:

From your WordPress admin section

>plugins>installed plugins > Active

Click on “Deactivate”

Then reactivate

>plugins>installed plugins > Inactive

That’s it! The table should have been created and with it the ability to save your shortcodes.