Subscribe to Tutorial Feed

Flash and PHP Bible

The Flash and PHP Bible has been released! The book can be found on Amazon or wherever fine books are sold in your area.

The Flash and PHP Bible has a forum for quick support.

Scriptplayground » tutorials » php » Tag Cloud

Tag Cloud

Build one of those popular tag clouds as found on sites such as: "Flickr", "del.icio.us" and others.

View an Example of this article before you get started.

A tag cloud is a list of tags that are sized based on keyword count. For this example we will be using a static array of tags, but this can easily be extended to a database application.

We will start off with the CSS which will provide the visual element to this tutorial.

<style type="text/css">
.tag_cloud { padding: 3px; text-decoration: none; }
.tag_cloud:link  { color: #81d601; }
.tag_cloud:visited { color: #019c05; }
.tag_cloud:hover { color: #ffffff; background: #69da03; }
.tag_cloud:active { color: #ffffff; background: #ACFC65; }
</style>

Next up, a function that will return an Array we will be using. As you will see it is a simple Multi-dimensional Array that stores the tag/count pairs.

function get_tag_data() {
    $arr = Array('Actionscript' => 35, 'Adobe' => 22, 'Array' => 44, 'Background' => 43, 
	'Blur' => 18, 'Canvas' => 33, 'Class' => 15, 'Color Palette' => 11, 'Crop' => 42, 
	'Delimiter' => 13, 'Depth' => 34, 'Design' => 8, 'Encode' => 12, 'Encryption' => 30, 
	'Extract' => 28, 'Filters' => 42, 'Flash' => 32, 'Functions' => 19, 
	'Gaussian Blur' => 44, 'Grafix' => 49, 'Graphics' => 35, 'Hue' => 47, 'Illustrator' => 8, 
	'Image Ready' => 12, 'Javascript' => 47, 'Jpeg' => 15, 	'Keyboard' => 18, 'Level' => 28, 
	'Liquify' => 30, 'Listener' => 10, 'Logo' => 12, 'Loops' => 22, 'Macromedia' => 26, 
	'Method' => 28, 'MySQL' => 18, 'Obfuscation' => 13, 'Object' => 39, 'Optimize' => 25, 
	'PDF' => 37, 'PHP' => 44, 'PSD' => 17, 'Photography' => 28, 'Photoshop' => 46, 
	'Revert' => 50, 'Saturation' => 35, 'Save as' => 28, 'Scope' => 11, 'Scripting' => 9, 
	'Security' => 41, 'Sharpen' => 49, 'Switch' => 41, 'Templates' => 11, 'Texture' => 22, 
	'Tool Palette' => 30, 'Variables' => 50);
    return $arr;
}

Now that we have the array function all setup, we move on to the function that will return our cloud tag HTML

function get_tag_cloud() { ... }

Lets run through this big function and explain what is going on. First off we define the min and max font sizes.

// Default font sizes
$min_font_size = 12;
$max_font_size = 30;

Call our "get_tag_data" function to retrive an array of tags.

// Pull in tag data
$tags = get_tag_data();

We pull out the minimum and maximum count from our tags. Creating a spread to be used in our font size calculations. Check to see if we have a good spread, if not, set one.

$minimum_count = min(array_values($tags));
$maximum_count = max(array_values($tags));
$spread = $maximum_count - $minimum_count;

if($spread == 0) {
    $spread = 1;
}

Finally we start the HTML building process to display our tags. For this demo the tag simply searches Google using the provided tag. We then return the HTML code.

$cloud_html = '';
$cloud_tags = array(); // create an array to hold tag code
foreach ($tags as $tag => $count) {
	$size = $min_font_size + ($count - $minimum_count) 
		* ($max_font_size - $min_font_size) / $spread;
	$cloud_tags[] = '<a style="font-size: '. floor($size) . 'px' 
		. '" class="tag_cloud" href="http://www.google.com/search?q=' . $tag 
		. '" title="\'' . $tag  . '\' returned a count of ' . $count . '">' 
		. htmlspecialchars(stripslashes($tag)) . '</a>';
}
$cloud_html = join("\n", $cloud_tags) . "\n";
return $cloud_html;

Here is some example HTML to call this tag builder.

<h3>Sample Tag Cloud results</h3>
<div id="wrapper"
<!-- BEGIN Tag Cloud -->
<?php print get_tag_cloud(); ?>
<!-- END Tag Cloud -->
</div>

There you have it a step by step guide on how to write your very own Tag Cloud... until next time... Happy Coding.

Follow Scriptplayground on Twitter (@scriptplay)

Comments: Tag Cloud

 thomas  Fri Jul 7, 2006 10:39 am  
okay, well, i really like this and you did a great job. but i want to make it work with my database. so i've added a column to my "pages" table and i now have a feild to input the tags 4 that page when u make it, but how do i get the number of occurances to average out from the database. i'm a little confused. actually, do u think u can quickly add how to use it with a database. thanks in advance.
 thomas  Fri Jul 7, 2006 6:35 pm  
please somebody help. If you do i can probably promote your site or do a custom web deign or smoething for you, please, i just really want to do this. thank you......
 Matthew Keefe  Fri Jul 7, 2006 9:01 pm  
Hey Thomas,

Thanks, that is a great idea.

I added a new tutorial extending this one to use a MySQL database instead of the static array.

Tag Cloud with Database

Matt
 thomas  Fri Jul 7, 2006 9:58 pm  
well, i actually wrote it my self based on a bunch of other tutorials and then put them all together, but i really appreciate you writing the new one jsut for me, thank you so much. you can email me at thrasher.basher@gmail.com if you'd like to talk about advertising or whatever. and i'm on aim at iplayguitar214 if u ever just want to chat. Thank you so much matt. Ur a lifesaver.
And i don't think your comment capacha uses random strings because it's been the same everytime.
 Matthew Keefe  Sat Jul 8, 2006 3:19 am  
Glad to hear you got it worked out and thanks again for the idea. That is how this site works, the reader suggests it and we write it.

In regards to the anti-spam measures, I am aware of that and also know the cause but am going to let it stay until the new site is launched. Thanks for the heads up though.

Matt
 cem  Thu Nov 23, 2006 5:59 am  
Does this skript count the klicks on the tags and changes them in the database? Please help me...
 Matthew  Thu Nov 23, 2006 8:35 am  
No, it is used to display the popularity of a tag. However if you wanted to use it to track a tag then you would set up a function to increment (update) the database entry whenever it is clicked.
 Bill  Mon Dec 11, 2006 10:50 am  
Newbie here so please excuse me... is there an example PHP file of this code to view so that I can see it "constructed" correctly?
 Matthew  Mon Dec 11, 2006 11:27 am  
Not a problem, here is the example PHP file. TagCloud-source
 Bill  Thu Dec 14, 2006 12:48 am  
Cheers, Thanks very much Matthew ;)
 Akash Takyar  Tue Feb 20, 2007 11:28 am  
Thats a perfect job. Thank you Matthew.

 mkeefe  Sat Feb 24, 2007 7:19 pm  
Not a problem, this has been a popular one.
 FP Images  Thu Mar 22, 2007 8:42 am  
You can employ more than one color with discretion.
One way to use colors in your cloud tag:
- select a main color, assign it to the biggest font;
- "blend" this color for smaller fonts.
A "coloring" example at
Tag cloud. Key words visualization
 anita  Sat Apr 14, 2007 7:22 am  
can anyone please help me.. how to make this work...i mean i have to paste all code in html files or have to make sepreate css, js php n html file

please help me out
Thanks
 mkeefe  Sat Apr 14, 2007 9:11 am  
I am on the road at the moment so putting an extended usage together would take some time, however I have posted 1 file that has everything you need to recreate the static array version (seen on this page).

http://v2.scriptplayground.com/article_files/Tag-Cloud/TagCloud-source.phps

Hope this helps.
 anita   Sat Apr 14, 2007 2:22 pm  
Thanks alot now i m tryiing to make it database version .. lets see if i can paste if correctly..
will need again help if anything goes wrong..
 Gerald  Fri Apr 27, 2007 5:29 am  
Hi,

Forgive my apparent retardation but I get an error in line 8 when I copy and paste the original.

It's the

functionget_tag_data(){

line
 mkeefe  Fri Apr 27, 2007 5:55 am  
What error do you get?
 Gerald  Fri Apr 27, 2007 5:56 am  
Parse error: syntax error, unexpected T_STRING in blah/blah/blah/test/index.php on line 8
 mkeefe  Fri Apr 27, 2007 7:49 am  
Hmm, make sure you have an opening and closing ' on all of your tag words. Also make sure you have a closing ] at the end of the array.

Hope that helps and fixes it.

Let me know
 Gerald  Fri Apr 27, 2007 8:56 am  
Hi,

Actually, it's really copied and pasted correctly. No ] anywhere around array section, though.

It seems to work for others - so no worries. I'll check it out when there's more time. Thanks.

Do not know if this is possible but could you php a tutorial for a script that would search a webpage for the category name or a css tag and then produce the cloud from that?

Thanks,

Gerald
 Marco  Fri Jun 22, 2007 10:49 am  
Is there any solution in asp ?

thanks
 Mr Bill  Wed Jul 11, 2007 12:31 pm  
Thank you will try to sort this. Would be nice to have a straight forward download if that wold be possible
 Mellowman  Wed Aug 22, 2007 1:45 pm  
Great tutorial but I was confused on how to put all this together. Could not get it to work.
 RigRank  Sat Oct 6, 2007 2:27 pm  
Thanks. Anyone know how to make the URL connect to some kind of search page as seen in del.icio.us ?
 roberto  Wed Oct 31, 2007 11:42 pm  
I tend to get better looking tagclouds by using log(count) instead of just count as described in

http://blogs.dekoh.com/dev/2007/10/29/choosing-a-good-font-size-variation-algorithm-for-your-tag-cloud/
 Monkey Tuk  Sat Nov 10, 2007 4:33 pm  
Good work man. It's running 100% thanks.
 Edward Han  Mon Nov 26, 2007 10:17 pm  
I have Tag field where users can input their Tags separated by comma. Example:
hat, shirt, clothes, dress

This will be saved in the Tag field. I have used your example above and when it shows, instead of showing one word per Tag, it is showing as the entire words per Tag.

How can I separate them to be individual word per Tag?

Thanks!
 mohamed  Thu Nov 29, 2007 7:17 pm  
welcome
thanks for this nice tutorials i joined my tags with search engine in my script
i have small problem in title page with arabic cha when you open it with ie 7 (like google cach link&title)
my title page show like
ظظظٹطط-العاب
this is command which show my title in the search page
$sitename2 = $searchTerm .
if you can help me tell me how to display this in encoding UTF-8
$sitename2 = $searchTerm .
thanks
 mohamed  Thu Nov 29, 2007 7:19 pm  
sorry the example for title didnt show it look like
ظظظٹطط
 mkeefe  Fri Nov 30, 2007 3:45 am  
This should help you:

http://www.hotpeachpages.net/a/characters.html

Matt
 mohamed  Fri Nov 30, 2007 4:12 am  
i think you not understand me
i want to slove it in the script
can you look here please and show how my title appear
http://www.google.com.eg/search?hl=ar&rlz=1T4GGLJ_enEG247EG247&q=site%3Agame.paramegsoft.com%2Ftags%2F%D8%A7%D9%84%D8%AC%D8%A7%D8%B3%D9%88%D8%B3%D8%A7%D8%AA&meta=

 mohamed  Fri Nov 30, 2007 7:12 am  
sloved
i was want something like
$str = mb_convert_encoding($str,"encoding1","encoding2");
it ok now
thanks Matt
 mohamed  Fri Nov 30, 2007 8:11 am  
if i want to add (-) between word and another how i do it
example
if this word the tag PHP TUTORIALS

i want it show in the link like

http://v2.scriptplayground.com/tags/PHP-TUTORIALS

how i can do that
thanks
-sorry for my many questions and comments
 cedric x  Mon Dec 17, 2007 4:46 pm  
my problem really solve this tutorials, but one more thing, i want to change the density of the word for example i search the word "computer", all word that are related to computer will be bolder or bigger than the other. Will that be possible?
 Pat  Wed Jan 16, 2008 2:46 am  
Here is a nice tag cloud script with mysql database, easy to configure :

http://www.ilikeyoutube.com/cloud/

Enjoy.
 sam  Sun Feb 17, 2008 8:48 am  
Great idea.
 Jeff  Sun Feb 24, 2008 1:55 pm  
I like this Tag cloud , Thanks for posting it .

Regards,,
 flash games  Thu Mar 20, 2008 1:29 am  
Thank you for Nice Post
 sharly  Sun Mar 23, 2008 8:06 am  
god
 Myspace Proxy  Sat May 17, 2008 11:10 pm  
So why would you advertise your script here on his site? I like this script is this project still being maintained or is ther further development in the future?
 chuck  Sun Jun 1, 2008 9:39 am  
Your script is great and works fine from a mysql table but when I try to display it in a table cell the tags overrun the width of the cell. I've tried defining the width of the cell from inside the cell tag to in css. In your posted example, what html container for the cloud is being used. Thanks for the post.
 mkeefe  Sun Jun 1, 2008 11:28 am  
@Myspace Proxy, yes, this script is still maintained.

@chuck, Display in a table cell? Do you mean an HTML table? The example is a div with a forced width.
 sunjester  Sun Jun 15, 2008 8:46 am  
not your best, but its not that bad. im kinda curious as to why you stoired them all in an array like that as opposed to using a database or flatfile, xml would have been perfect for this.
 mkeefe  Sun Jun 15, 2008 8:48 am  
@sunjester, I used an array approach to explain the tag cloud concept. I try to limit how much work I do for the reader, otherwise they never learn.

However, I created a database example after a bunch of comments came in requesting it.
 Tutorials Room  Mon Jun 16, 2008 10:29 am  
Nice tutorial! It was chosen for the main page of http://www.tutorialsroom.com and under Web Development tutorials. Please feel free to submit more of your good tutorials using this link: http://www.tutorialsroom.com/tutorials/submit_tutorials.html.
 Horoscope  Thu Jun 26, 2008 5:19 am  
These are very interesting information. Thank you for having published.
 gescom  Thu Jul 17, 2008 12:59 pm  
Great script!!
Would it be possible to use "txt" or "rss" source instead of MySql?

thanks,
cheers
 ilahiler  Mon Jul 21, 2008 11:38 am  
thankssa
 mkeefe  Sun Jul 27, 2008 6:00 pm  
@gescom - The overall code would be the same, just substitute the Database process with a file loading routine.
 sajidali  Thu Jul 31, 2008 1:33 am  
Thank you very much for the script.

It helps me a lot. :)
 nil  Thu Aug 7, 2008 2:45 am  
thanks....!
 kishore  Fri Aug 29, 2008 2:33 am  
the tag cloud is good . but i want a little bit modification in the application i.e when common English words r given by the user then it has stem(cut ) into one single word with counting the words example of my requirement . is if the string contains : (processing process processed processes) then the output has to come as only process only with count as 4 by grouping them
 NARKOZ  Thu Sep 4, 2008 2:26 pm  
Thanks very much
 ozox  Wed Sep 17, 2008 10:12 am  
Great, nice, fine work+ ideas -
and it works well!
thanks a lot and more,
and studies go on . . .
 Deb  Thu Dec 18, 2008 8:16 pm  
Newbie here - can one create a .txt file and enter the file name of each .html page, and a list of tags associated with the page - as input to the code?

I had always thought that clouds, read in the web's pages and then computed the words that were most found.... rather then use webmaster generated tags. ?

If I cannot create a .txt file - can I creaet an sql DB file with name of each .html file, with its associated tags?
 mkeefe  Thu Dec 18, 2008 8:41 pm  
@Deb - A tag cloud is connected to any number of options. Names of HTML pages is certainly one way, although it would be better to link the tag words to a SQL table entry that referenced the HTML page names.
 Jey  Sat Jan 3, 2009 11:28 am  
Can you help me make a page which inserts tags. Like when writing a post, fill a field named TAGS with the tags you want, separated by commas. I made a working page but I have a problem. I made it like when you insert a tag that already is in the database, the count of the tag increases by 1 but it doesn't work and the record has only 1 count. Please help me.
 mkeefe  Sat Jan 10, 2009 6:56 am  
@Jey - Do you have any code online or anything? Errors or warnings displayed would also better assist when attempting to solve your issue.
 Kenneth   Wed Jan 21, 2009 3:53 pm  
<?php sidebarCategories(); ?>

<?php

function sidebarCategories() {
global $separator, $postdir, $entries, $config_menuEntriesLimit;
$category_array_unsorted=array();
if (is_array($entries)) {
foreach ($entries as $value) {
$entry =explode($separator,$value);
$category=$entry[4];
array_push($category_array_unsorted,$category);
}
$category_array_unique = array_unique($category_array_unsorted);
foreach ($category_array_unique as $value) {
echo "".$value."";
}
}
}

?>
 Dainius  Sun Jan 25, 2009 3:59 am  
Hello, thanks for this,

i want to know what about making tag clouds design patterns, it means templates, it is my job. Who can help me?
 mkeefe  Sun Jan 25, 2009 8:41 pm  
@Dainius - I am not sure what you mean.
 Dainius  Mon Jan 26, 2009 10:06 pm  
You know that thing template? that you can use as much time as you want, that you only need to change data. for example I have 5 different webpages, and in every is tagcloud, where I use the same structure but different data. I think that data shut be taken automatically.

I dont know how to explain to you, please help. :)
 mkeefe  Tue Jan 27, 2009 8:04 am  
@Dainius - Well I think you mean a web site that loads the same data across many sites? If so, that is achieved by having a central database which is shared.

Hope this helps.
Matt
 Adam  Fri Mar 13, 2009 3:32 am  
You have saved me a lot of time, and the tag cloud looks very nice... thank you
 Agung Prasetyo   Tue Apr 14, 2009 8:24 pm  
Thanks. I already test your tagcloud and it's work well. But I have a question, how if i want to limit the tag just for 50 tag with the large count only. Is there any modification I must do ?

Thanks
 mkeefe  Tue Apr 14, 2009 8:39 pm  
Do you mean limit it to tags that are 50 or higher?
 Agung Prasetyo  Tue Apr 14, 2009 11:07 pm  
Yes. I like to ask one more (sorry).
How to make this tag cloud have random color.. I already search at google, but still can't found it.

Help Please
 mkeefe  Wed Apr 15, 2009 6:00 pm  
For the greater than 50 portion, add a simple conditional in the for..each loop.


if($count < 50) continue;


For the random color, simply use a function to generate a color, search google for random HEX color generator and replace the current color code.
 Phumla  Tue May 19, 2009 12:41 pm  
I'm struggling with my tag cloud project, after I clicked submit I dnt see any text on my handle form except errors.

 mkeefe  Mon May 25, 2009 12:22 pm  
@Phumla - What errors do you receive? That will help answer.
 Mark  Mon Jun 15, 2009 11:16 am  
Any suggestion on cleaning up text. Mine doesn't look as good as the example. When the larger font is shown, it tends to screw up the next line.
 mkeefe  Fri Jun 26, 2009 8:07 pm  
@Mark - I am not sure what is causing the blurry text, but make sure you are not performing a non-proportionate sizing.
 arabyana  Mon Aug 24, 2009 4:26 am  

I was really glad to read your writing

Thank you for the great post

http://sites.fatakat.com

http://arabyana.com

http://food.fatakat.com
 الع  Thu Oct 15, 2009 3:02 am  
its such a nice post thanks for sharing
http://games.m5zn.com
 donna  Mon Nov 9, 2009 10:32 pm  
hey hi.

where do i put the codes??
 mkeefe  Wed Nov 11, 2009 4:47 pm  
@donna - The PHP goes in a .php file and the HTML would be placed on your web site with the rest of your markup.
 donna  Sun Nov 15, 2009 5:18 pm  
i add in the codes in visual studio? i dont know where is the .php file. hmm.
 mkeefe  Mon Nov 16, 2009 7:30 am  
@donna - I am not sure if Visual Studio will work here. Simply open a text editor (Notepad for instance), create a new file, place the code inside and save it as file with a .php extension. Then you should be all set.
 bg  Tue Dec 22, 2009 2:03 am  
Look how M$ software screws up people.
 pratik  Wed Dec 23, 2009 8:17 pm  
Notice: Undefined variable: tags in C:wampwwwaaUntitled-1.php on line 57

Warning: Invalid argument supplied for foreach() in C:wampwwwaaUntitled-1.php on line 57


it shows the error on the line
foreach ($tags as $tag => $count)
{


for the forech loop it shows the error

can u tell what is the problem
}
 pratik  Wed Dec 23, 2009 8:28 pm  
hi

its working

only i closed the braces with the end of the
$spread=1;

now its working

i need a help .
likw i have $dtags
which have the value

how to pass the variable $dtags to the array
as $dtags array have the values from the db

please help me in that

thanks
 enam  Wed Jan 20, 2010 9:39 pm  
thanks a lot....this is really helpful...
 Download  Tue Feb 16, 2010 10:49 am  
i have same Q.

where do i put the codes??
 denseman  Thu Feb 25, 2010 2:51 pm  
hi, i am a newbie in regard to the tutorial. but i am yearning to learn yet how it works. i copied and pasted the codes and all i got was ...

Sample Tag Cloud results

why aren't there any results displayed within the page? can anyone help. thanks in advance. love you people.
 mkeefe  Tue Mar 2, 2010 5:43 am  
@denseman - Have you verified your server has PHP enabled and running?
 ازي  Tue Mar 16, 2010 5:21 am  
my site
 Helen  Tue Mar 16, 2010 5:46 am  
Hi,

Thanks for all your comments - I've learnt a lot from them. But I'm still pretty much a newbie too. At work, I have a text file of all the search terms from a knowledge base. I'd like to turn these into a tag cloud that automatically updates. How can I get this tag cloud to read the text file automatically?
 mkeefe  Tue Mar 16, 2010 7:59 am  
@Helen - You could use fopen/fread to populate an array to be used with the Tag Cloud, but that would be processor intensive. I would recommend importing the txt file into a database and then build the Tag Cloud around that. You can follow the update to this tutorial for help with creating a Tag Cloud from a Database.
 mmrtnt  Thu Apr 8, 2010 8:04 am  
Thanks.

I included a shout-out to you guys for the code.

http://www.southrustern.com
 mkeefe  Wed Apr 21, 2010 1:45 pm  
@mmrtnt - Thanks! Much appreciated.
 Brixter  Wed Aug 18, 2010 4:07 am  
Hello @ mkeefe, I'm really confused about this tag cloud. I want to implement one and I have tested some tutorials. But my question is, how does a tag is weighed? Is it by number of views or by the it's content?
 matthew nalett  Mon Feb 14, 2011 1:25 am  
Hello i have a music site and i wanted it to fetch keywords from my site actually and also what keywords people are using to access my site how would that be possible in the tags (area). to fetch keywords that are being used on my site not ones i install. Also to put the artists or djs name into the cloud as well automatically.

[code]
function get_tag_data() {
$arr = Array('DJ Promotions' => 35, 'Chicago Music Promotions' => 22, 'Array' => 44, 'Chicago Music Artists' => 43,
'Matthew Nalett' => 18, 'Chicago Promotions' => 33, 'Class' => 15, 'Color Palette' => 11, 'Crop' => 42,
'Delimiter' => 13, 'Depth' => 34, 'Design' => 8, 'Encode' => 12, 'Encryption' => 30,
'Extract' => 28, 'Filters' => 42, 'Flash' => 32, 'Functions' => 19,
'Gaussian Blur' => 44, 'Grafix' => 49, 'Graphics' => 35, 'Hue' => 47, 'Illustrator' => 8,
'Image Ready' => 12, 'Javascript' => 47, 'Jpeg' => 15, 'Keyboard' => 18, 'Level' => 28,
'Liquify' => 30, 'Listener' => 10, 'Logo' => 12, 'Loops' => 22, 'Macromedia' => 26,
'Method' => 28, 'MySQL' => 18, 'Obfuscation' => 13, 'Object' => 39, 'Optimize' => 25,
'PDF' => 37, 'PHP' => 44, 'PSD' => 17, 'Photography' => 28, 'Photoshop' => 46,
'Revert' => 50, 'Saturation' => 35, 'Save as' => 28, 'Scope' => 11, 'Scripting' => 9,
'Security' => 41, 'Sharpen' => 49, 'Switch' => 41, 'Templates' => 11, 'Texture' => 22,
'Tool Palette' => 30, 'Variables' => 50);
return $arr;
}
[/code]
 seo experts  Fri Apr 22, 2011 10:39 am  
i found your script, but can not understand how can i implement this script upon my blog
 Mike Smith  Mon Oct 24, 2011 2:40 am  
Great script. I have actually re-written it to work in Codeigniter 2. I've done just about everything in the model and created a widget that I can include in any view. I had a minor problem with the CSS and Google Chrome but changing DISPLAY:INLINE to DISPLAY:INLINE-BLOCK fixed it.

Thank again you saved me a lot of time.
Add a comment
The ability to add new comments has been disabled in this archived version.

Loading
Main | Tutorials | Articles