Archive for December, 2007

December 22nd, 2007 at 3:32 pm

Optimize your CSS

CSS files are the most downloaded parts of a website, as they are usually loaded with every webpage. Also, CSS files usually contain a lot of, from a technical point of view, unnesseccery characters. Therefore it is a good idea to optimize your CSS file(s) for faster loading. A good tool to remove pretty much all spare characters is the CSS compressor, which can reduce the file size of your CSS up to 25%. Of course, you should always keep a “source” version for modifications.

That tool of course is not able to optimize your CSS semantically, this must be done by you. Semantic optimization means that you should scrutinize your CSS file for redundancy. Do you possibly define background-image, background-position and background-repeat separately? Merge them into a single statement like background: #fff url(image.png) top left; — you need the first ones only for overwriting a single other property. (That’s why they are called Cascading Style Sheets.) Same goes for margin, border and padding with their -top, -right, -bottom, -left: Use them only for overwriting. In all other cases, merge them into one statement: For example, margin: 5px 2px; will assign a margin of 5px to the top and bottom, and 2px to the left and right. margin: 5px 2px 3px; will assign a margin of 5px to the top, 2px to the left and right, and 3px to the bottom. And margin: 5px 2px 3px 4px; will assign a margin of 5px to the top, 2px to the right, 3px to the bottom, and 4px to the left.

Other possibilities: Consider using relative paths to images instead of absolute ones. Remove unneeded definitions (or comment them out before sending them through the compressor). Combine multiple selectors in a single one (e.g. if you have #content_left a, #content_right a it could be possible to use #content a instead).

Optimizing your CSS by compression and good semantical style will shrink your CSS by 30-60%. This will make the loading of a webpage from your website noticeably faster, even with a fast connection.

December 19th, 2007 at 10:14 pm

Codelog WordPress theme released

I’m happy to announce the public release of the Codelog theme 0.1 for WordPress. The Codelog theme is a stylish and very lightweight two-column theme. If plain blogging is what you do, this theme is for you. The only features of this theme are fast loading, clean code and the elegant look. Ok, it also comes with multi-language support (German translation already included). But that’s it, less is more!

If you like the Codelog theme, download it and give your blog a new look!

December 18th, 2007 at 10:07 am

Improve loading speed of webpages by compressing HTML

Here’s a simple HTML “compressor” in PHP, which will reduce the size of HTML served to the client by 10 to 20 percent, depending on your indentation style and commenting. If many of your readers have lousy bandwidth, the slight overhead of this method is worth it.

<?php
	function compress($content)
	{
		$content = preg_replace('/[\n\t\s]+/s', ' ', $content);
		$content = preg_replace('/<!--.*?-->/s', '', $content);
		return $content;
	}
 
	ob_start();
	require "/var/www/htdocs/somefile.php";
	$content = ob_get_contents();
	ob_end_clean();
 
	echo compress($content);
?>

By the way, if you have a rather hungry dynamic application (e.g. WordPress with certain plugins) on a rather weak server, consider using a caching solution, so you don’t have to regenerate the pages everytime somebody retrieves them. And, of course, consider using output gzip compression – be it via webserver modules such as mod_gzip/mod_deflate or based on your web application.

December 17th, 2007 at 4:31 pm

Copying is expensive, moving is cheap

When you replace a comprehensive file tree via FTP, you will realize that it takes some time to do all the uploading. If your upload is going to replace old content, then one would usually first delete the old content, then upload the new one. (It is not a good idea to let the FTP client overwrite old contents, unless one knows exactly how the client behaves. For example, some clients merge existing trees, not deleting old files that are expunged rather than replaced, thus potentially raising security problems.)

However, the procedure of first deleting and then copying can leave your site naked or uncomplete for a couple of endless minutes. In the worst case, a user retrieves a page from your incomplete site and causes a database corruption or messes up the internal settings (this is not too unlikely with CMS applications). Therefore, the better way is to first upload the new content under a different name and then rename folders.

For example, if your web documents are in /var/www/docroot/, you would usually do the following: You delete everything in that directory and then upload the new content — which has the above mentioned side effects. Instead, you should better do the following: Upload all new content to /var/www/docroot_new/, rename /var/www/docroot/ to /var/www/docroot_old/, finally rename /var/www/docroot_new/ to /var/www/docroot/. Afterwards, you can delete /var/www/docroot_old/. Renaming is very fast, as only the base directory’s name has to be changed in the filesystem.

With this method, your website will only be naked for a few seconds, and there won’t be an incomplete installation at any time.

December 15th, 2007 at 5:26 pm

Count over two SQL tables

A bit of SQL that saved my butt lately: Have you ever needed to relate a value from one table to the count of another value in another table? Given you have two tables, one for a timetable, the other for tickets, and you want to find out how many tickets are sold for each tour in the timetable, the following will give it to you (tours.tour_id is related to tickets.ticket_tour_id, who’d have thought of that):

SELECT DISTINCT tour_id, COUNT(ticket_tour_id)
FROM tours
RIGHT JOIN tickets
ON tour_id = ticket_tour_id
GROUP BY ticket_tour_id
ORDER BY departure;
December 12th, 2007 at 12:47 pm

Playing with xgettext

xgettext is a great shell tool to create po files (i.e. Gettext translation templates). It is also able to merge existing translations with new strings. For example, to create a po template from all PHP files in a directory tree and preserve already done translations from the file my_translation-de_DE.po, enter:

mv my_translation-de_DE.po messages.po
find . -type f -iname "*.php" | xgettext --keyword=__ --keyword=_e -j -f -
mv messages.po my_translation-de_DE.po

Now you have a new my_translation-de_DE.po, with all the translated and the newly added strings appended to this file. (The --keywords parameter is very useful to specify your translation function(s), because if you do so, xgettext will not extract all the other strings, too.)

Unfortunately, xgettext is not able to expunge strings that are no longer existing. This behaviour is easy to explain: In many cases, you might be doing an incremental update of your translation template (i.e. you only add the strings for a subset of your files). If xgettext would expunge the translations for which no sting wasn’t found in your code, you would always have to recreate the po template completely. Anyway, a little option to expunge translations that weren’t found in the original, would be nice.

A little trick will at least help to determine the strings that do no longer exist: Open the po file to be merged and delete all #: lines (the regex ^#:.*$ will match them). Then merge the files as usual. In the new file, all messages without a #: marker do no longer exist. You can even modify the above code to do so automatically:

grep -v "^#:" my_translation-de_DE.po > messages.po
find . -type f -iname "*.php" | xgettext --keyword=__ --keyword=_e -j -f -
mv messages.po my_translation-de_DE.po

This way, you will preserve your translations, but your references are recreated, and you can easily see which strings do not exist anymore.

Update, 16.04.08: When I wrote this post, I didn’t know about the msgmerge tool. Using it is much better than the grep foo above. Use it as follows:

echo '' > messages.po # xgettext needs that file, and we need it empty
find . -type f -iname "*.php" | xgettext --keyword=__ --keyword=_e -j -f -
msgmerge -N existing.po messages.po > new.po
mv new.po existing.po
rm messages.po

It looks a bit more complex, but it’s the best generic solution I can provide. Note the -N parameter for msgmerge: It suppresses the fuzzy mode, which yields more confusion and extra work than anything else.

December 11th, 2007 at 7:17 am

Calculating the V.A.T. amount from the total price

Sometimes you need to calculate the V.A.T. (for Germans: MwSt.) from a given total price. This is, for example, if you charge an arbitrary total price, but need to display the V.A.T. percentage along with the V.A.T. amount. For this purpose, you can use the following code:

<?php
	function calc_vat_amount_from_total($total, $vat)
	{
		$total = (float)$total;
		$vat = (float)$vat;
 
		if (!$total || !$vat) return false;
 
		$net = $total / (float)('1.'.$vat);
		$vatAmount = $total - $net;
 
		return sprintf("%01.2f", $vatAmount);
	}
 
	$total = '35.00'; // It's a string, but could also be a float or int.
	$vat = '19'; // dito
 
	$vat_amount = calc_vat_amount_from_total($total, $vat);
	echo "The ticket fare of $total &#8364; contains $vat% V.A.T. ($vat_amount &#8364;).";
 
?>