Sunday, October 14, 2012

Blog layout

In my previous post I added a PS to create a theme.

The reason for this was i didn't have much control over it I thought.
I was wrong.

What I wanted

  • code highlighting
  • scrollbar if the code width is bigger than the content area

As this is a blog about code the examples should stand out.
I could use gists for every code example but for the examples in my previous article it seems like overkill.

What i did

Being lazy i changed my theme to a dynamic blogger theme. That kept my code in the content area, but it's an ugly theme.
And i didn't have syntax highlighting. So I changed back to my old theme.

Having a scrollbar isn't that hard in css. I just needed to know the content area width.

pre { overflow-x: auto; width: 700px; }

The side effect is that the gists all have a scrollbar or two, but scrollbars are fun.

Syntax highlighting isn't a big problem either because a lot of programmers blog, and they also want that.

When you search for syntax highlighting on blogger the first results are about SyntaxHighlighter.
My gripe with it is that it uses colons in classnames. I know from experience it causes troubles.

So I used shjs.
The installation requires you to add at least 3 files, two javascript files and a css file.

On the bog dashboard there is a template link and when you go there you find a button 'edit html'.
After a warning you see blogger xml code. I added following just before the ean head tag.

<link href='http://shjs.sourceforge.net/sh_style.css' rel='stylesheet' type='text/css'/>
<script src='http://shjs.sourceforge.net/sh_main.min.js'/>
<script src='http://shjs.sourceforge.net/lang/sh_php.min.js'/>

You may notice script is a self closing tag, this doesn't work in html.

the body tag needed the onload attribute to call the sh_highlightDocument function.
There are better ways to do this but I'm not using any other javascript that needs to be run on page load.

And now I have what i needed with the theme I like.

Friday, October 12, 2012

idiomatic php

It has been over a year since i blogged. It seems work is always taking over my free time. But I will never let my blog die.

Today i read an article about idiomatic python and I thought lets reproduce the code in php as an exercise. Working with .NET languages makes me rusty.
I will stay away from the style examples to avoid discussions that go nowhere.

I'm going to take the subtitles of the article and add the php code, enjoy!

Avoid using a temporary variable when swapping two variables

$a = 'a'; $b = 'b';
list($foo,$bar) = array($bar,$foo);

Use tuples to unpack data

There are no tuples in php, an array will do.

$list_from_comma_seperated_value_file = array('dog','Fido',10);
list($animal, $name, $age) = $list_from_comma_seperated_value_file;

Use ''.join when creating a single string for list elements

Join in php is an alias for implode. In php 5.4 square brackets can be used to create an array.

$result_list = ['True','False','File not found'];
$result_string = join('',$result_list);

Use the 'default' parameter of dict.get() to provide default values

The closest thing in php is the ternary operator.

$log_severity = isset($configuration['severity']) 
                    ? $configuration['severity'] : $loginfo;

Use Context Managers to ensure resources are properly cleaned up

It would be nice to have this in php.

Avoid repeating variable name in compound if Statement

if(array_search($name,['Tom', 'Dick', 'Harry']) !== false) {
    $generic_name = true;
}

Use list comprehensions to create lists that are subsets of existing data

The closest thing in php is to use an anonymous function and array_map.

$some_other_list = range(1,100);
$my_weird_list_of_numbers = array_map(
                              function($element){ 
                                if(is_prime($element){ return $element + 5; }                             
                              }
                            ,$some_other_list);

Use the 'in' keyword to iterate over an Iterable

The foreach loop in php uses the keyword as

$my_list = [ 'Larry' , 'Moe' , 'Curly' ];
foreach($my_list as $element){
    echo $element;
}

Use the enumerate function in loops instead of creating an 'index' variable

No need to use a function in a foreach loop to do this. It feels good to write that.

foreach($my_list as $index=>$element){
    echo $element;
}

PS note to self: create own blogger theme and never use blogger compose again.

Sunday, September 11, 2011

My first knockout.js experience

Because I wanted to see what the hype is all about, I dove in the documentation and tutorials of knockout.js.

The tutorial site is great!
But the first thing that bothered me was the data-bind attribute everywhere.

So I pulled up my sleeves and pimped the 'templates and lists' tutorial

The easiest way to test the code is to copy and paste the gist content from the article in the html and javascript fields of the tutorial site.

The html

The final markup of the tutorial looks like this:

As you can see the data-bind attribute is all over the place.

And this is my markup:

The data-bind attribute is only in the template.
The other bound elements have an id.

Instead of putting the seat count in the title, I put it together with the surcharge sum.
The tutorial code displays the surcharge sum when there actually is a surcharge, my code displays it from the moment a passenger is present.

The javascript code

The tutorial code looks like this:

Very readable if you are used to do all the legwork in jQuery.
I'm in the knockout camp if I need to create complicated interfaces from now on.

Before I show you my code I will do a blow-by-blow on what I did and what the hurdles were.

The first thing I wanted was to remove the data-bind attribute from the markup.
I knew someone wrote a jQuery plugin to make this possible.

It works fine until you want to use the plugin to bind the html elements in the template.
Because I didn't want to spend too much time looking for a way to make it work, I left the data-bind attributes.

Instead of using a ko.dependentObservable to make a sum of the surcharges I added it to the view model.
You should only use the method if the code depends on outside factors.

When I added the remove functionality it didn't work. I did some debugging and found out the this in the remove function was the view model object where it needs to be the seatReservation object.

I guess the unobtrusive plugin has to do something with it, but the quick solution is to bind the seatReservation object to the remove function.
Because jQuery is loaded I used $.proxy.

The tutorial adds an anonymous passenger but because that isn't allowed anymore, I added a prompt to the addSeat function.

So my code comes down to:

Conclusion

Amazing you can achieve so much with so little code. And the tutorial is still verbose because the availableMeals will be fetched using AJAX or generated by a server language, <?php echo json_encode($availableMeals); ?>

I grabbed it and I will not let it loose until something better comes along.

Tuesday, September 06, 2011

Ugling: the start of the template engine

The changes

If you look at the previous build.xml file you know processing content in phing will turn in spaghetti code very soon. So I moved it to the template task.

The new build.xml file is easy to read because now you just have two tasks.

To get the build result I want i needed to add an attribute to the markdown task, removefilesetdir.
For me it was a cleaner way to process the markdown files and add the processed files to another directory than the way the rSTTask documentation shows.

The template engine vision

I want working with the generator to be as easy as possible so I try to stay away from code-like constructions as much as possible.
But at the same time it has to be as flexible as possible too.

The first problem I encounter is how can I provide a default template but allow specific templates at the same time.

Because i started to work with base template I got the idea that each directory could have a template.html that wraps all files in that directory and its subdirectories.
The only exception is the root template directory, it's required to have a template.html there.

To allow file specific templates it seemed the most logical to use the name of the file, so if your content file is called test.md and you want a file template you create a test.html file in the templates directory.

The template task today

I took my MarkdownTask.php code to start the TemplateTask.php code.
I concentrated on getting it to work so the code isn't that clean yet.

The default template code is working.

To prevent placeholders showing up in the online files they are set to an empty string before the actual content is added or generated.

Next time

The next blog post I will have the template vision working and have come up with a plan to add generated navigation content.

Saturday, September 03, 2011

Ugling: the phing powered static site generator (the begin)

Preface


I was looking for a project to use phing in a way that isn't expected.

Using it to remove version software directories or run tests is done so many times before.


The cool programmers started using static site generators like jekyll and petrify.

Why would you need a database if most of your content is static.


So why not use phing to do the same thing.


I also want to make the threshold as low as possible.
Markdown is one thing but other elements like the navigation are going to be not that easy.


Transforming the markdown


Creating a task in phing is easy, certainly if someone already did a similar task.


I just copied the code from the rSTTask, removed the parts i didn't need and changed the code to use the markdown class.



The source layout



  • content

    • index.md



  • media

  • online

  • templates

    • base.html



  • build.xml


As you can see the content directory holds the markdown files.


You can add as many subdirectories as needed. And use index.md files to display content for an url without the html extension.


The media directory will hold css files, js files, and other public content.

I'm not sure i'm going to keep it because the only phing action will coppy the files to the online directory.


The online directory holds all the files you can place online.


The templates directory holds html files that have placeholders.
This will be for the 'expert' users.


The build.xml file is the phing hook which will take care of all the actions.


Later there can come a build.properties file to move the user accessible properties outside the build script.


Build.xml content



I think it's a readable file.



  1. Set the start target: default="loop"

  2. Add properties

  3. Add markdown task

  4. Find all markdown files and send the file names to the single target

  5. Process the markdown file and move it to the online directory


The future


Now that the easy part is over I can go to work on the necessary plugins.
Navigation is the first that needs attention.

Wednesday, August 17, 2011

My first phing buildscript

Because I get more and more components from version management tools it gets harder and harder to move from development to staging level. SVN repositories are the worst offenders, certainly if you see how clean the get and mercurial repositories are.

If you clone or checkout a repository most of the time it also includes test files, build files, and so on. It's stuff you don't need for your application.
Swiftmailer for example comes with a full blown test suite. What if hackers find a way to use it to their advantage?

The phing installation via pear is painless.

The way to delete a directory didn't appear in any of the searches i did. So i moved on to the documentation and I found what i needed.



It's not very elegant but i'm taking babysteps at the moment.

Sunday, July 03, 2011

Being a good programmer

First of all this is not a post about best practices, being smart and all that jazz. It's about me exploring new areas to use my programming knowledge.


Update


I put the code on github


The problem


I'm a fan of the WFMU radiostation. They have a wide variety of music and they archive all their shows.
The downside is that after a month they delete the mp3 archive of the shows and because I don't listen all the time I'm missing episodes of my favorite shows.
That is why I started to download the mp3's but it takes too many steps and I needed to switch programms.



  1. Download the m3u file.

  2. Open the m3u file

  3. Copy the content

  4. Open a browsertab

  5. Paste the m3u content in the locationbar


So i went in developer-mode and started to work out a faster way to download the mp3's.


The brainstorm session


As i'm getting the mp3 archives as an rss feed and i'm using google reader to view it, the step to making it a browser add-on was taken quickly.


The easiest way to download the mp3 for me is to right click the link, click on a context item and the download starts.


The development process


I've done only a little chrome extension development, but the browser makes it a painless process with it's extension developers-mode.

This mode lets you choose a directory on your pc where the extension files are located and once you 'installed' the extension you can reload it when you changed the source code.


Because i never used contextmenu code i donwloaded the sample code from the google code site, which i also use to learn more about the api's.


The contextmenu item


The code is simple enough to understand.



  • Define when the menu item has to be added, the contexts.

  • Iterate over all the defined contexts to add the menu item and click handler, the genericOnClick.


The m3u content


From the sample I learned the first parameter of the click handler, info, holds the m3u url, linkUrl. Not a lot of brainpower needed here.


From my previous experience i know to get the file content i have to do an ajax request.

To make a cross-origin request possible you need to add the sites to the permissions variable of the manifest.json. This file contains all the metadata of the extension.


The download


Now we come to the head scratching part. As much as I searched I couldn't find a way to use the ajax responseText to automate the download.


I was trying to inject the mp3 url in the originating tab and then programmatically clicking on it. To do this i had to use the tabs.executeScript method but as i found out the code is executed in a sandbox so it can not use values from the click handler.


So i had to settle with opening a new tab which has as url the mp3 url.


The future


Now the number of actions has reduced to 3 and i can stay in the browser.



  1. Right click the link.

  2. Click the contextmenu item.

  3. Save file from tab.


I'm not going to show the code now because I want to make it more robust and universal.

There are no messages when something went wrong. I assume the content of the file only contains one mp3 link but i know it can contain multiple files.


Later i could support more metadata files and use a converting service like zamzar to make it an allround downloading extension.

Sunday, February 08, 2009

Chromeless browser 2

My second day in a chromeless browser taught me i visually depend on more UI elements that i was aware of.

For instance the throbber. Because there is no statusbar or a locationbar that shows the page loading progress the throbber becomes a crucial element. Lucky for me vimperator gives a messaget when a background tab is opened. This gave me the idea to have a two tone throbber. The darker colour throbber would appear when the current tab loads and the lighter colour throbber would appear when a background tab is loading.

The throbber should be clickable. In the current tab it should stop the page loading. With background tabs it should do the same if only one background tab is loading and open a list of loading background tabs if there are more. There has to be an option to exclude often refreshing pages like passpack.com with one click on.

Another UI element is the download progress of files. I'm using the download statusbar add-on for a long while now and i find i come to depend on it. The add-on has an option to keep downloading in the download manager after the browser is closed but you can't see when a download is finished during the browser session.

The thing i miss the most is the tab overview the tabsbar gives me. So i installed the ctrl-tab add-on which gives an overview of the tabs using the shortcut ctrl-shift-A.

As a power user i want to have access to the url. I could make a ubiquity command for this but i don't know how to put the fetched url in the commandline.

Saturday, February 07, 2009

Chromeless browser



After seeing the video of Aza and Alex about designing a chromeless browser I was wondering how to get my browser chromeless to feel what it's like.

The first thing i did was hiding the statusbar. Next on the list is the tabsbar, as i already was using the tree style tab add-on i only needed to set the autohide options.
Then i needed to remove all toolbars, for that i installed the vimperator add-on.

I'm planning to use the Ubiquity add-on as my main chrome replacement. It's more user-friendly than the vimperator commands and it can be extended very easy.

For instance i want the awesombar functionality and i found the go 3.0 command, now i have the awsomebar and a screenshot preview as a bonus.

The first thing i noticed changing to the chromeless browser is how much i return to the tabsbar to select the tabs. Using the tab command to search for the tab with a certain name is useful when you have an overview of the tabs.

This will be an experiment as long as i can stand it so this could turn into a series.

Wednesday, December 17, 2008

Laptop future



source

There are two things i think are wrong with the picture above, both the keyboard and the screen are too small.
Lately it seems all cellphones get a full keyboard but they suffer the same defect as the mini pc.

If you have a computer the input and output should be made for a human not for a mouse.



source

This could be the future but i think the five parts that form a whole is too inflexible and you will not always have the possibility to project the keyboard or the screen.

I think the laptop of the future comes in three parts; the computer, the input device and the screen. This modularity makes the computer multifunctional.

Stan goes to work and he has a presentation to give. When he is dressed he puts the computer in one of his pockets and puts his projector and 24" rolled-up screen and alphanumeric keyboard with touchpad in his briefcase.
When he goes out of the door he puts on an ear piece and puts a hardcover touchscreen in another pocket.

Using his earpiece he recieves and makes calls while he does visual tasks on his touchscreen. When he arrives at work he places his 24" screen and keyboard on his desk.
Uh oh ten o'clock time to set up in the meeting room. He takes his projector and keyboard.

This is a computer orientated scenario but other input devices could be photo and video camera's, pens, cooking utilities, and so on. An other output device is a speaker.

I don't think we are that far of this picture of the future but it seems manufacturers rather want to make everything convenient then configurable.

Monday, September 29, 2008

locale number formating

With money_format you can do great things to display the number.

// Let's justify to the left, with 14 positions of width, 8 digits of
// left precision, 2 of right precision, withouth grouping character
// and using the international format for the de_DE locale.
setlocale(LC_MONETARY, 'de_DE');
echo money_format('%=*^-14#8.2i', 1234.56) . "\n";
// DEM 1234,56****

So it's very tempting to do

echo money_format('%!n',1234.56);

But the with the money function is that you either display decimals or you don't. I was looking for a function that has the possibility to only display decimals if the the number is floating.

After a few tries i came up with this

function locale_number($number,$decimals=2,$always_decimals=false)
{
if(is_int($number) && ! $always_decimals){ $decimals = 0; }
return number_format($number, $decimals, nl_langinfo(RADIXCHAR), nl_langinfo(THOUSEP));
}

I set the $always_decimals flag to FALSE because the money_format function will be faster if you always want to display decimals.

Saturday, September 27, 2008

CI/php trick for easier to remember function names

Most of the people who use php, including me, are not so keen on the inconsistent naming of the functions but with a php trick and the help op CI you can create easier to remember function names without performance loss.

Maybe some people will find this awkward at first but in php it's possible to assign a function to a variable by adding the function name as a value to the variable.

$STR_REMOVE_BEFORE = 'strstr';


In CI 1.6.1 they added the constants.php file which gets loaded early on so you could misuse this file to add your function variables but at the same time you could use all upper-case letters to distinguish the function variables from all the other variables. See the example above which gives you the opportunity to do;

echo $STR_REMOVE_BEFORE('name@example.com','@');


There is one problem with using a variable as a function and that is that you can't use it with parameters that are passed on by reference.

$ARR_LAST_VALUE = 'end';

Using this variable as a function will result in an error.

Saturday, September 20, 2008

Simple ubiquity commands

If you go to the command editor you can add these commands if you want.

// -------------------------------------
// firefox interfaces
// -------------------------------------
CmdUtils.CreateCommand({
name: "add-ons",
icon: "http://www.spreadfirefox.com/files/spreadfirefox_RCS_favicon.png",
execute: function(){
Utils.openUrlInBrowser( "chrome://mozapps/content/extensions/extensions.xul" );
}
});

CmdUtils.CreateCommand({
name: "downloads",
icon: "http://www.spreadfirefox.com/files/spreadfirefox_RCS_favicon.png",
execute: function(){
Utils.openUrlInBrowser( "chrome://mozapps/content/downloads/downloads.xul" );
}
});

CmdUtils.CreateCommand({
name: "places",
icon: "http://www.spreadfirefox.com/files/spreadfirefox_RCS_favicon.png",
execute: function(){
Utils.openUrlInBrowser( "chrome://browser/content/places/places.xul" );
}
});
// -------------------------------------
// website based functions
// -------------------------------------
CmdUtils.CreateCommand({
name: "copy-url",
icon: "http://www.spreadfirefox.com/files/spreadfirefox_RCS_favicon.png",
execute: function(){
Utils.openUrlInBrowser( context.focusedWindow.location.href );
}
});

As you can see the openUrlInBrowser function is the engine behind all of these functions. The firefox interface commands are based on the behavior of the vimperator, where the add-ons and downloads are presented in a tab.

Sunday, September 07, 2008

New FF add-ons

Ubiquity is the first add-on that makes me want to dive in the firefox internals. I tried creating add-ons myself but i was turned off by all the files you need to maintain. Ubiquity makes it easier to start playing with firefox. For example this Ubiq, ubiquity is just too long to write it all the time, command

// speeddial, sqlitemanager, fireftp, firefly
CmdUtils.CreateCommand({
name: "add-on-gui",
icon: "https://addons.mozilla.org/img/favicon.ico",
takes: {name: noun_arb_text},
execute: function(name){
var addon = name.text;
Utils.openUrlInBrowser( "chrome://"+addon+"/content/"+addon+".xul" );
}
});

Ubiquity is a javascript powered addon, they even included jQuery. It has several functions to let the creation of commands not stand in your way, CreateCommand is the most basic. As you see it takes a YAML like syntax as an argument, in javascript it's know as JSON.

What this command does is opening the GUI for add-ons like speeddial, sqlitemanager, fireftp, firefly in a new tab by pressing ctrl+SPACE, typing add-on-gui speeddial and pressing return.
If you used one of those add-ons extensively you could have bookmarked the url but in my opinion that makes your bookmarks more browser bound. Maybe i'm just an old school bookmarker thinking that bookmarks are only for websites.

Now i'm talking about bookmarks, another recent add-on is tagmarks. Tagmarks adds a number of icons next to the bookmark star in the locationbar for easy tagging. There are a few read later add-ons that want to make your bookmarks easier to maintain but firefox 3 bookmarks are database powered so maintaining them already is easy if you use the tag feature.
It comes out-of-the-box with a few tags most people won't find useful; radiation, add, stop. But creating your own tags is not that hard if you are willing to do a little bit of graphic work.

The icons are stored in the profile\extentions\tagmarks@felipc.com\chrome\skin\icons directory. If you look at the icons they have a grey and color part. This is called in css programming a sprite. Only one part of the image is visible. So if you want to make your own tagmark you have to make a sprite. I use xnview and inkscape to do it but there will be one application solutions.

  1. open the icon file you want to use in xnview

  2. grayscale the icon and save it

  3. import the color and gray icon in inkscape and position them next to eachother

  4. Select the two images and export as bitmap


Now all you need to do is, put the icon in the icons directory and open ...\tagmarks@felipc.com\chrome\content\taglist.js in notepad or another editor. There you find again a JSON formatted list that you can modify.

If you don't want to go through all this trouble you just press ctrl+SPACE, type tag any-tags-you-like and press return. So we are back to Ubiquity with one of the build-in commands. The add-on still needs a bit more work but it already proves to be an essential add-on, certainly for the people who are used to command line like applications as launchy, quicksilver, and others. Ubiquity will make it possible to reduce the number of add-ons if you like to type. But people who like GUI extensions are not left in the cold because of it.

Wednesday, June 18, 2008

First FF3 bug

In all the heat of the world record download attempt i still experience the same bug that kept me away from using the FF beta versions.

Closing the browser using alt-F4 or the close button in the upper right corner gets me me an empty page on restarting the browser when the homepage value is set to open previous tabs.

The only the tabs are restored is by closing the the browser with the file menu exit option.

Wednesday, May 07, 2008

IE8 < IE5

It's been a long time ago that i visited the windows update site and now that i installed IE8 beta i wanted to visit the site for the SP3 service pack but i've got the message i had to install IE with a higher version number than 5.

Is IE8 IE4 in disguise?

Sunday, March 23, 2008

php do

Recently i discovered you can't use do as a class method.

class Activate
{
function do()
{
return "it's good for you.";
}
}

if you want to use Activate::do() you will get an error.

Wednesday, March 12, 2008

simple word to number and number to word functions

I saw this python blog post and i wondered how the functions translate to php.

// to make the function language independent i put the array outside the functions
$array = array('zero','one','two','three','four','five','six','seven','eight','nine');
// number to words function
function d_to_w($digits,$array)
{
$temp = preg_split('//', $digits, -1, PREG_SPLIT_NO_EMPTY);
$return = array();
foreach($temp as $check)
{
if(is_numeric($check))
{
$return[] = $array[$check];
}
}
return implode(' ',$return);
}
// words to number function
function w_to_d($word,$array)
{
$temp = preg_split('/(\.|,|;|:| )/',$word, -1, PREG_SPLIT_NO_EMPTY);
$return = array();
foreach($temp as $check)
{
$temp2 = array_search(strtolower($check), $array);
if(is_numeric($temp2))
{
$return[] = $temp2;
}
}
return implode('',$return);
}

I've added a check to make the function more real world usable. An example use of the functions is;

echo d_to_w('100',$array).'
'.w_to_d('one zero zero',$array).'
';
echo d_to_w('1.00',$array).'
'.w_to_d('one,zero zero',$array).'
';

Saturday, February 16, 2008

Strange loop behaviour in php

I was doing some minor adjustments and i was puzzled why i could only get the last item from the loop. I found out the behavoir was created by a semi colon behind the round brackets.

$array = array(1,2,3);
foreach($array as $item);
{
echo $item;
}

Produces 3 and not 123 as expected.

Monday, November 12, 2007

CodeIgniter and jQuery

On the CodeIgniter forum there are quite a few jQuery questions so I'm bringing up some pointers.

jQuery file splitting


One big jquery file is great if you want to save http connections but it's not always the best approach. For instance if you have page specific code that doesn't need to be loaded until the visitor gets on that page.

Once you separated the page specific code into different files you can do two things :
- add the link to the javascript file to your page specific view
- have a variable in your view file and add the link to the javascript file when it's needed.
With the first method you can run into trouble if someone uploads his view without the javascript link. The second method can be a source of bugs if you have a templated site because the variable always needs a value if you add it to the basic lay-out.

Ajax


The relative url is most of the time (/index.php)/controller/method but if you refer to the same controller you can use ../method.

If you are using a get request don't add the parameters using jQuerys build in functionality but add them to the url (controller/method/key/value/key/value) and retrieve the key-value pairs using the CodeIgniter uri->uri_to_assoc method.

My latest jQuery snippets on the CodeIgniter forum


Content to new window
Highlight words using a sentence/keywords on the page
hack for inline links