How To Locate Your Website Visitors Via IP

October 13th, 2009

More and more websites are using a geolocation service to show advertisements and offers near a visitor’s location. Using such a service on your own website is quite easy. This post only focuses on using the MaxMind GeoIP City database based on IP addresses and using it with PHP because I have already implemented this solution on one of my websites and wanted to share this tutorial because I think it may be helpful for my visitors.

This tutorial requires that you are able to compile PHP extensions on your system which means that you must have root access to your server and need to be able to access it from the Linux command line.

Although the price you have to pay for the MaxMind database may appear high at first glance you may not need the full database but may just purchase a database for a single country - just as I purchased the German database only. There is also a free GeoLite City database available from MaxMind which has a worldwide coverage and has an accuracy of 79% for US cities.

There are just 6 simple steps for you to perform - I will cover using the German database on an Ubuntu Linux system only but only the file name is different with versions for other countries so you need to adjust some values in the examples below.

  1. Purchase and download the database (choose the API version, not the CSV file)
  2. Unpack the file and move the contents to the appropriate directories:

    tar -xvzf GeoIP-132de_20090901.tar.gz
    mkdir /usr/local/share/GeoIP
    mv GeoIP-132de_20090901/GeoIPCityde.dat /usr/local/share/GeoIP/GeoIPCity.dat
  3. Install the header files for the library:
    apt-get install libgeoip-dev
  4. Install the geoip extension for PHP:
    pecl install geoip

    If you’re getting an error like this

    checking for LGPL compatible GeoIP libs... wrong version
    configure: error: You need version 1.4.0 or higher of the C API

    you can fix this by downloading the C files directly from MaxMind and compiling them manually:

    wget http://geolite.maxmind.com/download/geoip/api/c/GeoIP-1.4.6.tar.gz
    tar -xvzf GeoIP-1.4.6.tar.gz
    cd GeoIP-1.4.6
    ./configure
    make
    make check
    make install
    apt-get remove libgeoip-dev
    pecl install geoip

  5. Load the new PHP extension - add these lines to your php.ini:
    extension=geoip.so
    geoip.custom_directory=/usr/local/share/GeoIP
  6. Restart your (Apache) web server

You can now use all of the PHP functions the geoip extension offers such as:

<?php var_dump(geoip_record_by_name($_SERVER['REMOTE_ADDR'])); ?>

In the next post I’ll cover using the GeoLocation object available in JavaScript in Firefox 3.5 and using it to get even more detailed locations.

Share and Enjoy:
  • DZone
  • del.icio.us
  • Digg
  • StumbleUpon
  • Mixx
  • TwitThis
  • Technorati
  • FriendFeed
  • Google Bookmarks
  • BlinkList
  • blogmarks
  • Furl
  • LinkArena
  • Live
  • MySpace
  • NewsVine
  • Ping.fm
  • Reddit
  • Simpy
  • Spurl
  • Identi.ca
  • LinkedIn
  • MisterWong
  • Slashdot
  • Sphinn
  • Yahoo! Bookmarks
  • Facebook
  • RSS
  • Turn this article into a PDF!
  • Print this article!

Looking for JV Partners/Affiliates For A Halloween-Related Product

September 11th, 2009

Halloween Fearscapes Vol. 1 & 2I know that I haven’t posted here for a long time and this is actually because I’m working hard for the Halloween season creating many digital products most of which will be available for free on my German website halloweenies.de. Be assured that a Halloween website in English is coming next year. It will be available at halloweenies.info.

Having just finished the new Halloween Fearscapes Vol. 2 Halloween horror atmosphere CD I just relaunched the already-existing fearscapes.com website allowing everybody to buy both volumes as digital MP3 versions via instant download. Payment is handled through PayDotCom.com and thus possible via PayPal.

The downloads are still very cheap at just $17 each but this price will go up in October.

Anyways, I’m offering an unbelievable 50% commission on all sales of each of the products.

So if you have a Halloween-related website or a mailing list which you think might be interested  in these products just go straight to the affiliate page and become a JV partner/affiliate. If you have any questions please do not hesitate to ask me.

Share and Enjoy:
  • DZone
  • del.icio.us
  • Digg
  • StumbleUpon
  • Mixx
  • TwitThis
  • Technorati
  • FriendFeed
  • Google Bookmarks
  • BlinkList
  • blogmarks
  • Furl
  • LinkArena
  • Live
  • MySpace
  • NewsVine
  • Ping.fm
  • Reddit
  • Simpy
  • Spurl
  • Identi.ca
  • LinkedIn
  • MisterWong
  • Slashdot
  • Sphinn
  • Yahoo! Bookmarks
  • Facebook
  • RSS
  • Turn this article into a PDF!
  • Print this article!

Refactoring Your PHP Code

July 7th, 2009

This article describes in a nutshell what I learned from the Refactoring Workshop with Lars Jankowfsky and Thorsten Rinne at the International PHP Conference 2009 Spring Edition in Berlin some weeks ago. The main focus was on refactoring and test-driven development which I always wanted to do but actually never did. I had already installed PHPUnit some years ago after attending a session with Sebastian Bergmann but knowing how to install and use PHPUnit does not necessarily mean that you know how refactoring works and what you need to focus on.

So it has actually been very helpful for me to attend that workshop although I now know that continuous refactoring is essential. It doesn’t make sense to refactor a project and then again refactor it a year later despite adding new features and fixing bugs during the whole year. You always have to refactor your code while developing. It is essential when beginning with refactoring not to start a large refactoring project that takes a year to complete because this is expensive and doesn’t create any value for the end user, i.e. the visitor of your website or your customer. Instead you should allocate a specific amount of time, e.g. 20-30% to spend on refactoring your code.

I won’t go into the complete details because that would be far more than I want to cover in this article. Also remember that I have not yet used unit testing so this article reflects just what I have learned yet.

Refactoring is better that rewriting your code because rewriting normally takes too long and is therefore too expensive. I personally love to rewrite but I know that it may take very long and if there is something more important - something that is directly related to revenue - I may stop rewriting and instead focus on the more important project. Just remember that starting a project from scratch once again may feel good but most of the time it takes much more time than you may have anticipated at the beginning.

I have learned that refactoring with methods like pair programming is very helpful especially if a senior developer is working together with a less experienced developer so that he can learn new methods as well and gets to know the code much better.

When Should I Refactor?

If a specific method has (too) many lines of code and you cannot understand within a short time what the purpose of that method is or if it has more than around five parameters in the constructor most of the time it’s time for refactoring. Long methods can almost always be broken down into several smaller methods which also eases writing unit tests for the code.

Test-Driven Development

Test-driven development is the way to go and it always reappeared during the conference in many different sessions. You need to distinguish between unit tests and acceptance tests however. To test your layout and GUI (i.e. the view) you should use tools such as Selenium instead.

Tests should be regarded as part of the documentation because they actually help documenting your code.

So how to start? First of all never refactor the easy parts first, move the risks to the beginning. It’s not helpful if you have created 100 tests which may have taken only 30 minutes to complete but the one single test that’s missing requires 30 hours to create.

When refactoring always create a test for the existing code first then change the code so that you can be sure that you did not actually introduce a new bug during refactoring.

How To Create Testable Code

With test-driven development you first of all create the raw skeleton of the method you wish to create the test for (i.e. implement the feature) and then implement the first test which will of course fail because no code has yet been written in the method that has been tested.

By focusing on just getting the code (the single method) to work you are no longer tempted to abstract and will just focus on implementing the feature that is required. So no longer try to implement a feature that you may eventually some time in the future need to implement but in fact most of the time would never be used. Just implement what is required, what your test need to succeed.

You should never use global or superglobal variables in your methods because this doesn’t make your code testable. So don’t use $_GET, $_SESSION etc. in any of your methods at all and instead give these values as parameters.

You also need to implement one test per result type that the method returns, i.e. if it returns false in one case and true in another you need to create two tests for that method.

Useful Tools

There are several tools available that help you with test-driven development and refactoring:

  • phpcpd which is a copy&paste detection tool
  • phpcs - PHP CodeSniffer which will check if the code does not violate your coding guidelines
  • a coding style plugin for Eclipse
  • ZendStudio For Eclipse offers debugging, profiling and a good integration of the Zend Framework

Always test protected and private methods as well because if you only test public methods you are unlikely to immediately find the source of a failing test if a tested public method calls private or protected methods internally. If you need to write tests for protected methods you can use the unittools to create a proxy class.

Static methods make creating tests extremely difficult (may be possible using dependency injection) - maybe you do not have to use static methods as all?

You do not need to create tests for methods which only use some of PHP’s built-in functions like filesystem functions that load a file if it exists because you want to test your own code, not PHP’s code.

Quite often - e.g. if you are using a database or some other dynamic datasource - you need to make sure that you are really testing your PHP code and the test won’t fail if the database server is down. You need to make sure that the underlying data structure is not dynamic. In that case you have to create fixtures and/or mock objects that simulate the dynamic structure (albeit static) in your tests.

You may also want to have a look at (PHP)YAML

Checklist

Here is a short checklist I got to know at the workshop:

  1. use phpcs to find errors
  2. Fix all errors
  3. Find duplicates with phpcpd (copy/paste lines)
  4. Create tests for old code (w/ refactoring if needed to remove dependencies) (mock/fixtures)
  5. Refactor

I only scratched the surface in this article and I am very keen on beginning with test-driven development. I hope that I could share some insight into what I learned at the PHP conference regarding refactoring. For more in-depth information you should really attend one of the conferences - especially the workshops.

I am planning to share more information on setting up and using PHPUnit in one of the following articles on my blog so stay tuned.

Share and Enjoy:
  • DZone
  • del.icio.us
  • Digg
  • StumbleUpon
  • Mixx
  • TwitThis
  • Technorati
  • FriendFeed
  • Google Bookmarks
  • BlinkList
  • blogmarks
  • Furl
  • LinkArena
  • Live
  • MySpace
  • NewsVine
  • Ping.fm
  • Reddit
  • Simpy
  • Spurl
  • Identi.ca
  • LinkedIn
  • MisterWong
  • Slashdot
  • Sphinn
  • Yahoo! Bookmarks
  • Facebook
  • RSS
  • Turn this article into a PDF!
  • Print this article!

Bing’s Blatant Censorship In Germany

June 7th, 2009

Microsoft’s new search (decision) engine decides too much in Germany with very blatant and in my opinion stupid censorship despite no obvious reason for it. Of course Google doesn’t have these problems in Germany, so with Google in Germany you may actually search for a new pantyhose with Bing it’s impossible (this link only shows the message if accessed from Germany):

bingcensorship_1

The text says (in German):

The search pantyhose may return sexually explicit content.
To get results, change your search terms.

This censorship was already in use sometime on the MSN Live Search before. So does Microsoft really think this kind of censorship makes sense and will lead to more use than Google in Germany sometime in the future?

The problem I see is that the restrictions seem to be based only on specific words, so it is very easy to circumvent it. Sometimes it is even sufficient just to add an additional word. The most simple solution would be to change the country in the top right corner on the Bing website. Even if you are in Germany - just by switching the country to e.g. the United States there are no restrictions anymore whatsoever.

This kind of censorship also happens in other countries like India.

I have compiled a list of terms here that shows some of the words that are blocked and their corresponding translation. Ambiguity of words does not seem to matter at Bing. Very explicit terms have been excluded - anyways viewer discretion is advised:

bing-censored-search

It is amazing that even such terms like “handcuffs” and “pantyhose” are blocked by Bing.

Doublethink? Advertisers Are Allowed To Use These Terms

Interestingly there does not seem to be such a restrictions for advertisers. Although the ads are not shown if the search has been blocked by Bing searching for related words shows ads containing words that you can’t even search for. There are even some more explicit terms in the ads than I have used in the sample above.

bing-censored-ads

Do advertisers know that these words have been blocked? If I would be a website owner trying to sell pantyhose I would like to have my ad shown when someone searches for the word.

Good For Microsoft?

I highly doubt that this kind of censorship will be beneficial for Microsoft in Germany given the current discussions on internet censorship in Germany. But it shows what may be used in the future anyways not only on Bing.com.

If you want to protect your child from potentially harmful content on the internet (in a way that cannot be circumvented by two clicks as with Bing currently) there are other ways like talking with your child about it or in the worst case install a filter software on your PC. But if someone is trying to find websites on syringes (blocked in Germany) on Bing please let him find results.

My personal conclusion: I do not like censorship therefore I do not like Bing. I’ll stick with Google although it is being censored as well but not to such a degree based on single results not on search queries.

Share and Enjoy:
  • DZone
  • del.icio.us
  • Digg
  • StumbleUpon
  • Mixx
  • TwitThis
  • Technorati
  • FriendFeed
  • Google Bookmarks
  • BlinkList
  • blogmarks
  • Furl
  • LinkArena
  • Live
  • MySpace
  • NewsVine
  • Ping.fm
  • Reddit
  • Simpy
  • Spurl
  • Identi.ca
  • LinkedIn
  • MisterWong
  • Slashdot
  • Sphinn
  • Yahoo! Bookmarks
  • Facebook
  • RSS
  • Turn this article into a PDF!
  • Print this article!

How To Hide Links To Avoid NoFollow PageRank Sculpting Issues

June 6th, 2009

Just recently Google’s Matt Cutts announced a change in how Google handles NoFollow attributes in links thus making a “rel=nofollow” useless on your JavaScript-enabled onClick event handlers. The best method in this case would be to hide links on your page that you would normally have used “nofollow” on so you could only show them via JavaScript.

Instead of using “rel=nofollow” on your links as you did previously you may want to hide the links completely and only make them appear when JavaScript is enabled. You should also show a user which does not have JavaScript enabled that there is a link but it is not enabled. So I decided to create a small JavaScript which converts <span> elements with a specific class name to links when the user has JavaScript enabled. If there is no Ja

vaScript the “links” will look like this:
followlink_1

If JavaScript is enabled and the page has finished loading the links will look like this:
followlink_2

This is the HTML code for the <span> tag which will be converted into a link which needs to be given as the title attribute of the element:

<span class="hiddenJSLink" title="http://www.saschakimmel.com/">Hidden Link</span>

This is how the link will look after the script has been executed:

<a href="http://www.saschakimmel.com/">Hidden Link</a>

You can also add both an id and additional classes to the source <span> - they will be copied to the final link.

The script requires the prototype.js JavaScript framework - I am using this because I know that many websites are already using it on their pages.

This is some code of an example HTML page - you can download it and the JavaScript file in a package below.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
<head>
<title>Hidden Links</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="hiddenLinks.css" type="text/css" />
<script type="text/javascript" src="prototype-1.6.0.3.js"></script>
<script type="text/javascript" src="hiddenLinks.js"></script>
</head>
<body>
<ul>
<li><a href="http://www.saschakimmel.com/">Normal Link</a></li>
<li><span class="hiddenJSLink" title="http://www.saschakimmel.com/">Hidden Link</span></li>
</ul>
</body>
</html>

So in essence the only thing you need to do is to add these three lines of code to the <head> section of your HTML file after you have downloaded the JavaScript/HTML/CSS package below:

<link rel="stylesheet" href="hiddenLinks.css" type="text/css" />
<script type="text/javascript" src="prototype-1.6.0.3.js"></script>
<script type="text/javascript" src="hiddenLinks.js"></script>

Acessibility Notice!

Please note that from an accessibility standpoint using JavaScript is not recommended as it renders the links useless on screen readers. But currently there seems to be no other way to hide links from Google for legitimate PageRank sculpting.

License

Creative Commons License
This code by Sascha Kimmel is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License. This means that if you are using it on your site (personal and commercial sites are ok) you need to add a link somewhere (only on one page)  as provided here:

HiddenLinksJS by <a href="http://www.saschakimmel.com/" target="_blank">Sascha Kimmel</a>

If you don’t want to add a link to your site you can donate any amount to my PayPal account which will entitle you to use the HiddenLinkJS on any page without any requirement for adding a link:


View hiddenLinks.js
View hiddenLinks.css
View hiddenLinks.html demo page

dlnow

Share and Enjoy:
  • DZone
  • del.icio.us
  • Digg
  • StumbleUpon
  • Mixx
  • TwitThis
  • Technorati
  • FriendFeed
  • Google Bookmarks
  • BlinkList
  • blogmarks
  • Furl
  • LinkArena
  • Live
  • MySpace
  • NewsVine
  • Ping.fm
  • Reddit
  • Simpy
  • Spurl
  • Identi.ca
  • LinkedIn
  • MisterWong
  • Slashdot
  • Sphinn
  • Yahoo! Bookmarks
  • Facebook
  • RSS
  • Turn this article into a PDF!
  • Print this article!

6 Free Nature Wallpapers For Your Desktop

June 2nd, 2009

From time to time as a way of saying thank you for reading my blog I’m releasing some free graphics as well. Here are 6 free exclusive wallpapers for your desktop with a resolution of 1280×1024 pixels so best suitable for 19″ although they can of course be used on lower or higher resolutions as well.

I have take these photos myself so I hope that you like them.




Please be advised that I retain copyright and you are only allowed to use these photos as a desktop background.

Share and Enjoy:
  • DZone
  • del.icio.us
  • Digg
  • StumbleUpon
  • Mixx
  • TwitThis
  • Technorati
  • FriendFeed
  • Google Bookmarks
  • BlinkList
  • blogmarks
  • Furl
  • LinkArena
  • Live
  • MySpace
  • NewsVine
  • Ping.fm
  • Reddit
  • Simpy
  • Spurl
  • Identi.ca
  • LinkedIn
  • MisterWong
  • Slashdot
  • Sphinn
  • Yahoo! Bookmarks
  • Facebook
  • RSS
  • Turn this article into a PDF!
  • Print this article!

How To Use The Bing Webmaster Tools To Get Info On Your Site

June 1st, 2009

Just today bing.com, Microsoft’s new search engine, has launched. Surely you have already checked out the search results and checked positions of your favorite keywords. But have you also checked out all the tools Microsoft now offers webmasters to analyze their websites?

Verify Ownership Of Your Website

Just go to the Bing Webmaster Center and click on the “Add a site” button to add your website. In the form that is shown enter the URL of the website you wish to add. Bing even allows you to provide an email address ” to contact you if [they] encounter specific issues with your site” which sounds very interesting because Google does not provide that feature. Only the following weeks and months will show what the result of using that email feature will be.

bing-scr01

After submitting the form you have to add some verification code to your site (or your server). In contrast to Google which only requires you to create an empty file with a specific name Microsoft wants you to add an XML file to your server which a specific content. You can also choose to add a META tag to your site but I recommend using the XML file because it’s much simpler - you only need to upload it once to your server whereas you’d have to add the META information to the homepage template.

bing-scr02

After you have added the META tag to your homepage or uploaded the XML file click on the “Return to list” button. You’ll see your website in the list. Just click on the domain name.

Bing will access your website immediately and check for both the META tag or the XML file. If you have done everything correctly you will be taken to the site summary page which provides a wealth of information on your site as seen by Bing.

bing-scr03

Site Summary And Domain Score

The site summary shows you when your site was last crawled by the Bing crawler, the number of indexed pages, whether Bing has been blocked from accessing your site (if you have blocked it via the robots.txt file for example) and a domain score which is shown as five boxes. Microsoft writes here:

“Domain Score provides a measurement of how authoritative Bing views your domain to be, with five green boxes being the highest rating and five empty boxes being the lowest. This is based on many of the same factors Bing uses to determine static rank, but isn’t directly comparable.”

Luckily this blog has a domain score of 5/5 at the time of writing.

Bing also shows you the top 5 pages of your site.

Your Profile

When selecting “Profile” from the top navigation you can change the settings you have already seen when you added your site. You can also see the current verification method Bing is using to verify your site ownership.

Crawl Issues

This section shows you crawling issues that may have occurred on your site such as pages that Bing could not find (404 error) or pages blocked by the robots.txt file.

It also shows you a list of long dynamic URLs Bing has flagged because they think it might lead the crawler into an infinite loop trying to crawl the dynamic URLs and may also lead to duplicate content.

The Crawl Issues page also tells you whether the crawler found pages on your site which it believes to be infected with malware or using unsupported content types.

bing-scr05

Backlinks

The backlinks page shows you all of the backlinks Bing has found to your domain together with the page score, language and region of the page linking to your content. I really like the inclusion of the page score because it may be used to find “bad neighborhoods” linking to your site although Microsoft says that the score isn’t directly comparable.

The page will only show the first 20 backlinks but you can download the complete list as a CSV file to your system.

bing-scr04

Outbound Links

This page will show you all of the links on your site Bing has found that are leading to other websites. Just like on the backlinks page it shows you the page score, language and region as well and even allows you to show your outbound links to malware sites - let’s hope you don’t have any on your site.

Just like before you can also download the complete list as a CSV file.

Interestingly all of the links on my page leading to Twitter (the source of which is a Twitter plugin for Wordpress which shows the latest tweets on my blog) have a page score of 5/5. Does that mean that Bing sees Twitter as an authoritative site?

bing-scr06

Keywords

This page allows you to see “how your site performs in search results for searches using specific keywords” although I don’t quite understand the results. You can enter a keyword in the text field provided and it will show you the page on your site, the page score of that page and once again the language, region, last crawl date and whether the Bing crawler was prevented from accessing the page.

bing-scr07

It is interesting but I had expected to see SERP positions for the given keyword which would be a great feature. Entering “wolframalpha” shows a page score of 5 for my article on WolframAlpha yet when searching for “wolframalpha” on bing.com that page is not listed in the first 100 results.

More (Not So) Interesting Stuff

You can also add your sitemap directly by clicking on the Sitemaps tab.

The “Related Tools” section in the navigation on the left side lists some links that sound interesting at first but in my opinion they are a bit disappointing. If you thought that by clicking on the Robots.txt validator link you would be able to analyze the robots.txt file for your current site you’re wrong. You can copy the contents of any robots.txt file there to check it for incompatibilites with the MSNBot but that’s all. Slightly disappointing.

Likewise the HTTP Verifier and Keyword Research Tool links lead you directly to the default pages on the Microsoft website.

Bottom Line…

I recommend that you add your site(s) to the Bing Webmaster Center so that you can access the interesting statistics they provide - I’m sure many more tools will be provided in the future.

You should also check out the forum for many interesting discussions.

I’m amazed that Microsoft provides these features just from the launch day on.

We’ll see what else will be provided in the future.

Share and Enjoy:
  • DZone
  • del.icio.us
  • Digg
  • StumbleUpon
  • Mixx
  • TwitThis
  • Technorati
  • FriendFeed
  • Google Bookmarks
  • BlinkList
  • blogmarks
  • Furl
  • LinkArena
  • Live
  • MySpace
  • NewsVine
  • Ping.fm
  • Reddit
  • Simpy
  • Spurl
  • Identi.ca
  • LinkedIn
  • MisterWong
  • Slashdot
  • Sphinn
  • Yahoo! Bookmarks
  • Facebook
  • RSS
  • Turn this article into a PDF!
  • Print this article!

How To Add A DZone.com Button To Your WordPress Blog Posts Automatically

May 30th, 2009

After previously adding the DZone.com voting buttons manually to each post (which you really don’t want to do every time as you need to set the post URL manually for the index page) I have modified the JavaScript provided by DZone and integrated some code into the WordPress files so that a button is added automatically on each post now just like the button to the left of this text.

Uploading The Modified JavaScript File

I noticed that DZone isn’t currently sending a cache header on every JavaScript request and that the snippet you are given to integrate into your post redirects via a 302 header to the real file. If you have 5 DZone buttons on your blog’s homepage (if you are displaying 5 posts) that means 10 additional HTTP requests to DZone.com that take time and delay the page loading process.

If you have already integrated the JavaScript snippet provided by DZone you should remove it now otherwise you will get two buttons per post. Just download this file and upload it to a directory of your choice on your server. You may even use the WordPress uploader but write down the final path to the JavaScript file as you need to enter it in the next step.

Now open Appearance > Editor in the WordPress Admin Panel on the left hand side and click on header.php on the right hand side. Add the following line somewhere within the <head> of the document:

<script src="/js/dzone.js" type="text/javascript"></script>

Replace “/js/dzone.js” by the path where you have uploaded the dzone.js file before. Then click on “Update File“.

Adding The Button To Every Post

After saving click on the link “single.php” on the right side just as you did before with the header.php file. Depending on your chosen WordPress theme the HTML code may look more or less like this:

<div class="entry">
<?php the_content('<p class="serif">Read the rest of this entry &raquo;</p>'); ?>

Just between the opened <div> tag and the following <?php tag insert the snippet code:

<span style="float:left;margin:0 10px 10px 0"><script type="text/javascript">dzone_show_linkbox('<?php the_permalink(); ?>', '<?php the_title(); ?>', null, 1);</script></span>

Thus the modified code will look like this:

<div class="entry"><span style="float:left;margin:0 10px 10px 0"><script type="text/javascript">dzone_show_linkbox('<?php the_permalink(); ?>', '<?php the_title(); ?>', null, 1);</script></span><?php the_content('<p class="serif">Read the rest of this entry &raquo;</p>'); ?>

Save the file by clicking on “Update File” afterwards.

Repeat this step for the index.php file and you’re done.

If you are using the WP Super Cache plugin or any other caching plugin you may need to clear the cache otherwise you won’t see the modified pages. When using WP Super Cache select Settings > WP Super Cache on the left side and then on the “Delete Cache” button on the page.

After reloading your blog’s homepage or any article page you will now see a DZone button just like this article does.

Share and Enjoy:
  • DZone
  • del.icio.us
  • Digg
  • StumbleUpon
  • Mixx
  • TwitThis
  • Technorati
  • FriendFeed
  • Google Bookmarks
  • BlinkList
  • blogmarks
  • Furl
  • LinkArena
  • Live
  • MySpace
  • NewsVine
  • Ping.fm
  • Reddit
  • Simpy
  • Spurl
  • Identi.ca
  • LinkedIn
  • MisterWong
  • Slashdot
  • Sphinn
  • Yahoo! Bookmarks
  • Facebook
  • RSS
  • Turn this article into a PDF!
  • Print this article!

Tutorial: How To Use Prototype.js On Your Site

May 30th, 2009

prototype.js is an amazing JavaScript framework that I have been using for some years now. This tutorial shows you how to work with prototype.js and what some best practices are. It won’t go into details on every available method but it will give you a quick introduction.

I apologize for the coding style but the WordPress plugin seems to eat spaces and tabs.

Obtaining Prototype.js

You can download the latest version of the prototype library from the download page and include this on your page like this if you have saved it as prototype.js in your document root directory:

<html>
<head>
<script src="prototype.js" type="text/javascript"></script>
...
</html>

There are also some packaged and minimized versions of the file available because the file itself is quite large.

Using Google To Load Prototype.js

Another option is using Google to include the Prototype JavaScript Library on your page thus offloading traffic from your server to Google. You can use Google’s AJAX Libraries API for that purpose. If you want to use Google which has the benefit of distributed servers around the world therefore likely speeding up the download this is how it works:

<script src="http://www.google.com/jsapi"></script>
google.load("prototype", "1.6.0.3");
google.setOnLoadCallback(function() {
// What to do once the file has been loaded
....
}
</script>

Throughout this tutorial I am assuming that you are loading the library without using Google as this makes initializing your own code more complicated.

JavaScript Coding With Prototype.js

After you have included the prototype.js library it’s time to start implementing your JavaScript code. With prototype.js I have come to use classes exclusively because this allows for a object-oriented architecture of your JavaScript code and encapsulates the code.

Create a new file - for demonstration purposes in this tutorial named test.js - and save it in your document root (or in any other directory like /js, just make sure to change the path accordingly in the <script> tag). Now add the following code to it:

// Create the class
var myTestClass = Class.create({
initialize:function()
{
// Is called when the page has finished loading by the Event.observe code below
alert('Works!');
}
});
// Global variable for the instance of the class
var myTest;
// Creating an instance of the class if the page has finished loading
Event.observe(window, 'load', function() {
myTest = new myTestClass();
});

Now you need to create an HTML file named test.html containing the following code:

<html>
<head>
<title>prototype.js Test</title>
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript" src="test.js"></script>
</head>
<body>
<h1>prototype.js Test</h1>
<div id="container" style="display:none"></div>
<ul id="list">
<li>Item 1</li>
<li class="highlight">Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
<a href="http://www.dzone.com/" target="_blank" id="demoLink">Click me!</a>
</body>
</html>

If you then load this file in your browser a JavaScript alert box will pop up saying “Works”.

By creating an event hook for the window’s load event handler you can be sure that every element on the page has been loaded. If you are not using this code and leave out the Event.observe code in the test.js file it may happen that some elements on your page may not yet have loaded so the user may receive a JavaScript error message if you are trying to access elements on the page that do not yet exist.

You can also use ‘dom:loaded‘ instead on ‘load‘ in the Event.observe call which will be executed once the DOM tree of the HTML document has been fully created. This means that individual elements may not have been loaded (e.g. an image) but you can already access all of the elements on the page.

The Constructor

Whenever a new instance of a class is created the initialize() method of the class is called automatically (just like PHP’s __construct() method). You can of course define an arbitrary number of parameters as well. Just modify the line to see how it works:

 initialize:function(url)
{
// Is called when the page has finished loading by the Event.observe code below
alert('Works @ '+url);
}

and

Event.observe(window, 'load', function() {
myTest = new myTestClass(location.href);
});

Methods

Defining methods within the class is very easy. In contrast to other programming languages you cannot declare specific methods (functions) as private, protected or public thus they can be accessed from the outside anyways even if you do not desire it.

Let’s create a new method and modify the class so that it looks like in this example:

var myTestClass = Class.create({
initialize:function(url)
{
// Is called when the page has finished loading by the Event.observe code below
alert('Works @ ' + this.toUppercase(url));
},
toUppercase:function(str)
{
return str.toUpperCase();
}
});

Please note the specific syntax for creating new methods. Every method must be separated by the one before with a comma and the last method in the class must not be followed by a comma (Internet Explorer does not like this).

You can simply call methods by prefixing them with a “this.” from within the class.

Accessing Elements

The most often used function from my experience is the $() function which allows you to access any element that has an id. The HTML code contains a link to dzone.com which has an id. To access that element you simply need to write

$('demoLink')

No need to write the long document.getElementById(’demoLink’) anymore. Here is an example you can add to the initialize() method at the very end:

alert($('demoLink').getAttribute('href'));

This will show an alert box with http://www.dzone.com in it. Likewise you can set specific attributes easily:

$('demoLink').setAttribute('href', 'http://www.saschakimmel.com/');
alert($('demoLink').readAttribute('href'));

This will change the href attribute pointing to this blog’s homepage.

Now you may feel tempted to give any element that you may wish to access a specific id attribute. But wait - that’s not required! The Prototype library contains the $$() method which allows you to use CSS3 selectors (yes, even if the browser does not yet support it). So just as you might do with CSS you can do with prototype.js:

$$('#list li.highlight')[0].update('I was Item 2');

The $$() method always returns an array. Because our code only contains a single LI element with the given class “highlight” in an unordered list with the id “list” this code works.

You could even use something like this to achieve the same result:

$('list').down('li.highlight').update('I was Item 2');

The Element.up() and Element.down() methods return only a single element which is the first element found from the element given and also support CSS3 selectors.

The Element.select() method is similar to $$() but whereas the $$() method searches globally the select method searches from the given element within the DOM tree so you could also have used this code as well:

$$('ul')[0].select('.highlight')[0].update('I was Item 2');

This code may look a bit complex at the beginning but if you start using the library you will quickly recognize the different methods. I just urge you not to give every single element an id so that you can access it by using the $() method. You should use ids on semantic blocks like #topbar, #navigation and so on and use classes within the code wherever possible.

This way you are not blowing up your code by only using ids for accessing elements with JavaScript. It’s just not necessary if you’re using the prototype.js library.

Add more semantics to your code.

Updating And Modifying Elements And Classes

As you have already seen in the examples above you can use the Element.update() method to update element contents. If you wish to modify attributes you should use the Element.setAttribute() method (which is a native browser method).

You can also add, edit and remove class names at runtime easily.

To add a CSS class use the Element.addClassName() method:

$('demoLink').addClassName('democlass');

To find out whether a specific element has a specific class use Element.hasClassName():

$('demoLink').addClassName('democlass');
if ($('demoLink').hasClassName('democlass')) {
alert('Yikes!');
}

Loops

Forget those annoying for loops you have learned when using JavaScript. Prototype has its own methods that ease the implementation of loops. There are some pitfalls however which I am going to explain here.

We now want to loop over the <li> elements of the list and wrap a <strong> around the current contents of each <li> element. This is how it works:

$$('#list li').each(function(el) {
el.update('<strong>'+el.innerHTML+'</strong>');
});

In fact this is a method that is a bit dirty because we are using HTML code as a string in the update() method. This is a cleaner method but it’s very long in contrast to the method before:

$$('#list li').each(function(el) {
var oldContent = el.innerHTML;
var strongEl   = new Element('strong');
el.update('');
el.appendChild(strongEl);
strongEl.update(oldContent);
});

Most of the time I’m sticking with the shorter method above.

Using bind()

Now let’s call the toUppercase method we created in our class. Because the each() method has been implemented by prototype.js using the this keyword within the each loop would reference the each method itself so this will throw the error “this.toUppercase is not a function”:

$$('#list li').each(function(el) {
el.update('<strong>'+this.toUppercase(el.innerHTML)+'</strong>');
});

So in this case we need to bind the this keyword to our class. This can be achieved by using the bind() method:

$$('#list li').each(function(el) {
el.update('<strong>'+this.toUppercase(el.innerHTML)+'</strong>');
}.bind(this));

Now our code works! Whenever you are using specific prototype.js methods where you can use a this inside the method you need to bind it to your class in that way.

Event Handlers

Remember this code?

<a href="..." onclick="doThis()">Click here</a>

Or even this code?

<a href="javascript:doThis()">Click here</a>

You don’t need this with prototype.js anymore as you can use the unobtrusive event handlers it provides. If a link is only useful and functional with JavaScript enabled only you should add a CSS style of “display:none” to the element and make it visible in the initialize() method.

Now let’s add an event listener to the link:

$('demoLink').observe('click', function() { alert('This link has been disabled!'); });

If you reload the page and click on the link you will see an alert box and if you click on the OK button the link will be opened in a new window/tab anyways. To prevent this you need to stop the event. Just modify the code to look like this:

$('demoLink').observe('click', function(e) { alert('This link has been disabled!'); Event.stop(e); });

As you see now the link is no longer opened. However using anonymous functions inline is not a good programming style so let’s create an additional method in our class:

showDisabledMessage:function(e)
{
Event.stop(e);
alert('This link has been disabled!');
},

You also need to modify the Event observer:

$('demoLink').observe('click', this.showDisabledMessage.bindAsEventListener(this));

Just as you did before with the call to the bind() method when using the each method when using an event listener you need to use the bindAsEventListener() method to bind the function to your class.

Here is some more code for you to see some more of what is possible with event listeners:

$('demoLink').observe('mouseover', function(e) { Event.element(e).setStyle({
'color': 'red',
'fontSize':'30px'
}); });
$('demoLink').observe('mouseout', function(e) { Event.element(e).setStyle({
'color': 'blue',
'fontSize':'12px'
}); });

I won’t go into the details on these methods so please have a look at the documentation.

AJAX

I know I have to show some demo code for AJAX usage when writing an article on the Prototype.js JavaScript framework so here we go. Create an HTML file named ajax.html and add the following code to it:

<div style="border:5px solid red;padding:15px;">
<h1>Loaded via AJAX!</h1>
</div>

We now want to update the <div> with the id “container” with this content after the ajax.html file has been loaded via AJAX after clicking on the link. Let’s clean up the code of the initialize() method:

initialize:function(url)
{
$('demoLink').observe('click', this.loadContent.bindAsEventListener(this));
},

Now add this method to the class:

loadContent:function(e)
{
Event.stop(e);
new Ajax.Updater('container', 'ajax.html', {
onComplete:function() {
$('container').show();
}
});
},

This method stops the event (i.e. it won’t open the dzone.com homepage in a new window/tab), sends an AJAX request to the ajax.html file, updates the div with the id “container” (the first parameter) and when the request has finished makes the container visible with the show method as it has an inline style reading “display:none”.

As you see you don’t even need any dynamic code on the server to use AJAX.

In this article I have only scratched the surface of what prototype.js has to offer. In encourage you to read the documentation and just play around with the methods. Prototype.js has so much in store it’s really fun developing. As you may have noticed in the article I am using unobtrusive JavaScript which means that there is not a single line of JavaScript code in the HTML file (except the two <script> elements of course).

Download the source code

Share and Enjoy:
  • DZone
  • del.icio.us
  • Digg
  • StumbleUpon
  • Mixx
  • TwitThis
  • Technorati
  • FriendFeed
  • Google Bookmarks
  • BlinkList
  • blogmarks
  • Furl
  • LinkArena
  • Live
  • MySpace
  • NewsVine
  • Ping.fm
  • Reddit
  • Simpy
  • Spurl
  • Identi.ca
  • LinkedIn
  • MisterWong
  • Slashdot
  • Sphinn
  • Yahoo! Bookmarks
  • Facebook
  • RSS
  • Turn this article into a PDF!
  • Print this article!

How To Install Apache, MySQL and PHP (WAMP) On Windows Manually

May 29th, 2009

If you are using Windows as your operating system when developing your websites you should always test your websites on your local system before you upload the files to your live server.

Although there are several pre-packaged Apache-PHP-MySQL (WAMP) packages available for download when using these you are bound to their release cycles and the structure of the directories they are using.

This article describes how you can install Apache, PHP and MySQL manually on your local system with maximum flexibility because you can quickly update one program if the need may arise, e.g. if a new PHP version has been released.

This method also shows you where specific files are located which you may need to edit when changing settings so you can dive a bit deeper into the configuration files which may be quite helpful if an error occurs.

WAMP Setup

In this tutorial I’m assuming the following:

  • Apache, PHP and MySQL are installed to subdirectories of d:\webserver
  • The document root is d:\webroot
  • the first test domain is www.webserver.local
  • the document root for that VirtualHost is d:\webroot\www.webserver.local\htdocs which will contain all documents accessible via the browser

Installing The Apache Server

First of all you need to download the latest Windows distribution of the Apache HTTP server from the Apache download page. Pick the MSI installer including OpenSSL which is named something like „Win32 Binary including OpenSSL 0.x.x (MSI Installer)” and is listed under the section named something like “Apache HTTP Server 2.2.xx is the best available version”.

After launching the setup program pick the „Custom” setup and choose the directory d:\webserver\Apache as the installation path. Enter the information as shown in the screenshots below.

apache-install

apache-install-2

Installing PHP

Dowload the latest (stable) PHP 5 version from the PHP download page. Choose the „PHP 5.x installer”. After download and launching the file when prompted to select a directory choose d:\webserver\PHP

php-install

Webserver Setup - “Select the Web Server You Wish To Set Up” select “Apache 2.2.x”.

php-install-2

When prompted for the Apache configuration directory select d:\webserver\Apache\conf.

php-install-3

On “Choose Items To Install” select the extensions you’d like to install.

If you don’t know which might be useful you may use the following list to find some suggestions:

  • cURL (good for accessing HTTP servers)
  • EXIF (if you’re dealing with photos and wish to extract meta information)
  • GD2 (image creation and manipulation)
  • Multi-Byte String (mbstring, for i18n, e.g. conversion from ISO-8859-1 to UTF-8)
  • mcrypt (for encryption)
  • mysql, mysqli
  • other database extensions you might be using (postgreSQL etc.)
  • OpenSSL (for accessing https URLs)
  • PDO, PDO_Mysql, PDO_SQLITE
  • SOAP (if you’re planning to access SOAP resources or create you own SOAP server)
  • SQLite

Installing MySQL

To download the MySQL server visit this MySQL website and download the Windows MSI Installer package under „Community Edition”.

To ease administration and creation and editing of tables and databases I encourage you to download and install the MySQL GUI tools as well.

In the MySQL setup dialog pick the custom installation and select the directory d:\webserver\MySQL as the installation directory.

mysql-install-1

mysql-install-2

When configuring the MySQL server use the detailed configuration.

mysql-install-3

Use “Developer Machine” as your server type

mysql-install-4

Select “Multifunctional Database” in the database usage dialog:

mysql-install-5

Keep the default InnoDB tablespace settings and click Next:

mysql-install-6

Select “Decision Support” on the next dialog:

mysql-install-7

Keep the default values on the next screen:

mysql-install-8

When prompted to select a character set use the one that fits best, I’m using UTF-8 as the default charset.

mysql-install-9

On the next dialog you have to choose whether to install the server as a Windows service and if it shall be started automatically at boot time. This setting depends on how often you’re developing on your system. I’m keeping MySQL running in the background most of the time because it doesn’t eat that much memory.

mysql-install-10

The next dialog prompts you to select a root password. Keep this in mind.

mysql-install-11

After the installation has finished the MySQL server is already running and you can now begin to configure PHP and Apache.

Configuring Your System

For every VirtualHost (i.e. website/domain) you need to add a corresponding entry to your HOSTS file so that your browser knows that the given domain will be handled by the webserver running on your local system. Edit the file c:\windows\system32\drivers\etc\hosts with a text editor.

Windows Vista Information

On Windows Vista you have to launch Notepad as an administrator to see and edit the file.

Add a new line to your hosts file which has the following content:

127.0.0.1 www.webserver.local

Now requests to www.webserver.local from your browser will be sent to the webserver running on your local system.

Configuring The Apache Webserver

There are actually two files to edit. Please note that you always need to use forward slashes or a double backslash in path names.

General Settings

Open the file d:\webserver\Apache\conf\httpd.conf and search for the line reading

DocumentRoot "D:/webserver/Apache/htdocs"

The default document root is D:/webserver/Apache/htdocs. We now need to change this to point to the d:\webroot directory as defined above. So change this line now to

DocumentRoot "d:/webroot"

You also need to modify the line reading

<Directory "D:/webserver/Apache/htdocs">

to

<Directory "D:/webroot">

If you wish to use .htaccess files you also have to change the line reading

AllowOverride None

to

AllowOverride All

To include the VirtualHosts file which will contain all mappings of hostname to document root directory (and more) you have to change the line

#Include conf/extra/httpd-vhosts.conf

to

Include conf/extra/httpd-vhosts.conf

To enable automatic execution of an index.php file when the user accesses a directory (which you should always do) you need to add index.php to the DirectoryIndex directive just as in this example - simply add „index.php” to the end of the line:

<IfModule dir_module>
DirectoryIndex index.html index.php
</IfModule>

Creating The VirtualHosts Configuration

Open the file d:\webserver\Apache\conf\extra\httpd-vhosts.conf. Now it’s time to create a VirtualHost for our domain www.webserver.local.

Just add the following block to the end of the file.

<VirtualHost *:80>
ServerAdmin webmaster@example.com
DocumentRoot "D:/webroot/www.webserver.local/htdocs"
ServerName www.webserver.local
ErrorLog "logs/webserver.local-error.log"
CustomLog "logs/webserver.local-access.log" common
</VirtualHost>

This will tell Apache…

  • that the server administrator can be reached via webmaster@example.com (no need to enter your real email address, because on your own development system you’re the only one that would see your real email address so it doesn’t make sense
  • that the documents for www.webserver.local can be found in the directory d:/webroot/www.webserver.local
  • to log errors to the file d:/webserver/Apache/logs/webserver.local-error.log
  • to log every access to d:/webserver/Apache/logs/webserver.local-access.log

Creating The Documents

Create the directory D:/webroot/www.webserver.local/htdocs recursively and create the file D:/webroot/www.webserver.local/htdocs/index.php with the following contents:

<?php phpinfo(); ?>

Configuring PHP

The default PHP installation would not show you any errors in the browser and instead just return a 500 server error which would materialize as an empty white page.

Although this is the recommended setting for productions servers where you do not normally want to reveal any specific information like paths when an error occurs this makes life quite hard on your local development server. To enable the display of error messages in the browser open your php.ini file which is located at d:\webserver\php\php.ini and change the line

display_errors = Off

to

display_errors = On

To enable sending of emails via the mail() function you need to define a specific SMTP server name and port. You would normally enter your providers’s mail server name here. Please keep in mind that some providers use a so-called „POP-Before-SMTP” so that sending mails with PHP may fail if you have not downloaded new messages via POP3 from the server before.

Testing The Installation

Now you are ready to test your new web server. First of all you need to restart the Apache server via the included taskbar tool or via the Windows services panel.

After that open up your browser and enter http://www.webserver.local/

This should show the phpinfo() page.

And now: have fun developing!

Share and Enjoy:
  • DZone
  • del.icio.us
  • Digg
  • StumbleUpon
  • Mixx
  • TwitThis
  • Technorati
  • FriendFeed
  • Google Bookmarks
  • BlinkList
  • blogmarks
  • Furl
  • LinkArena
  • Live
  • MySpace
  • NewsVine
  • Ping.fm
  • Reddit
  • Simpy
  • Spurl
  • Identi.ca
  • LinkedIn
  • MisterWong
  • Slashdot
  • Sphinn
  • Yahoo! Bookmarks
  • Facebook
  • RSS
  • Turn this article into a PDF!
  • Print this article!