Home Notes Web development

Dynamic portfolio E-mail
Saturday, 18 April 2009 22:38

I wanted to give visitors a third "plain-clothes" option for viewing my portfolio - plain-clothes being without JavaScript or Flash.  But at the same time I wanted the data to be dynamically populated, the way it is in the jQuery and Flash versions.

The task was pretty easy using PHP 5's built-in XML DOMDocument class.  I used the same XML files that carry the data for the other sites, and rendered it with the following PHP code:

$xmlDoc = new DOMDocument();
$xmlDoc->load("name of XML file");
    $sites = $xmlDoc->getElementsByTagName("site");
    foreach ($sites as $site){
     echo "<p 'style=color:#CD6620;'><strong>" . 
    $site->getElementsByTagName('site_title')->item(0)->nodeValue . "</strong></p>";
     if ($site->getElementsByTagName('imageURL2')->item(0)->nodeValue == ""){
        echo "<p><a target='_blank' title='Visit site' href='" . 
    $site->getElementsByTagName('siteURL')->item(0)->nodeValue . 
    "'><img title='" . $site->getElementsByTagName('site_title')->
    item(0)->nodeValue . "' alt='" . $site->getElementsByTagName('site_title')->
    item(0)->nodeValue . "' src='" . $site->getElementsByTagName('imageURL')->item(0)->
    nodeValue . "' /></a></p>";

        echo "<p><a target='_blank' title='Visit site' href='" . 
    $site->getElementsByTagName('siteURL')->item(0)->nodeValue . 
    "'><img title='" . $site->getElementsByTagName('site_title')->
    item(0)->nodeValue . "' alt='" . $site->getElementsByTagName('site_title')->
    item(0)->nodeValue . "' src='" . $site->getElementsByTagName('imageURL')->item(0)->
    nodeValue . "' /></a>" . 
        "   <a target='_blank' title='Visit site' href='" . 
    $site->getElementsByTagName('siteURL2')->item(0)->nodeValue . 
    "'><img title='" . $site->getElementsByTagName('site_title')->
    item(0)->nodeValue . "' alt='" . $site->getElementsByTagName('site_title')->
    item(0)->nodeValue . "' src='" . $site->getElementsByTagName('imageURL2')->item(0)->
    nodeValue . "' /></a></p>";

echo "<p>" . $site->getElementsByTagName('description')->item(0)->nodeValue . "</p>";
     if ($site->getElementsByTagName('site_details')->item(0)->nodeValue != ""){
      echo "<p>" . $site->getElementsByTagName('site_details')->item(0)->nodeValue . "</p>";
     echo "<p><strong>Skills used</strong>" . $site->getElementsByTagName('skills_used')->
    item(0)->nodeValue . "</p><hr />";

echo "<p>" . $site->getElementsByTagName('description')->item(0)->nodeValue . "</p>";
     if ($site->getElementsByTagName('site_details')->item(0)->nodeValue != ""){
      echo "<p>" . $site->getElementsByTagName('site_details')->item(0)->nodeValue . "</p>";
     echo "<p><strong>Skills used</strong>" . $site->getElementsByTagName('skills_used')->
    item(0)->nodeValue . "</p><hr />";

I used the DirectPHP plugin available for Joomla, and placed the code above inside PHP tags within the article content.

The result can be viewed here

Book review | CodeIgniter E-mail
Sunday, 12 April 2009 10:27

I've read two books on CodeIgniter lately, and just wanted a write a few words about each one.


Professional CodeIgniterThis is the first book I read.  I found it informative, and I really appreciated its example-based approach.  It was a bonus that it used Agile methodology, although that wasn't its main focus.

The book, like any other technical book, is rife with errors and small oversights, but overall the book is a great way to get started with CodeIgniter.  This book is more about using CodeIgniter than about how it works, which is great, because it's complemented very well by the next book I read.










CodeIgniter for Rapid PHP Application DevelopmentThis book talks more about how CodeIgniter does its thing: how controllers work, how controllers interact with models and views, and what the limitations of each facet of the system are.  For example, users can't interact directly with models, libraries, helpers, or plug-ins.

It also talks about good practices.  Models, for example, can call views, but shouldn't, because that's the controller's job.

It explains the Active Record class, and gives a glimpse of what goes on behind the scenes in CodeIgniter that's conveniently hidden from the developer.

Overall it's a good book for not only learning about CodeIgniter but also the programming principles it is based on, like MVC and Active Record.  If I'm unclear on something I read or did from the previous book, this is the first place I would check for an explanation.

CodeIgniter E-commerce application E-mail
Thursday, 09 April 2009 21:32


I finally incorporated the Pkstore database into my photoblog database, which is a Pixelpost installation.  It was relatively simple.  The steps involved were:

  • Update references to the new database throughout the application
  • Change references to the new field names
  • Copy the tables that store the product sizes available and the product-size relationships to the Pixelpost database

The categories and product-category relationships were easily updated because they are stored in Pixelpost the same way they were stored in the Pkstore database.  So overall it was a pretty quick and painless process.

Now when I add a new picture to my photoblog, it automatically gets added to Pkstore as well.


I've updated the administration dashboard to accomodate viewing only.  Use demo/demo as username/password to view the dashboard.


I've launched a beta version of an e-commerce application I've written in PHP using the CodeIgniter framework at Pkstore.


The product on the site is my own photos, from my photoblog.

Some of the features of CodeIgniter I am using, alongside the core, are:

  • Form helper
  • URL helper
  • Image_lib library to generate large thumbnail for product page
  • Session helper

Some functionality I implemented:

  • Prints can be ordered in different sizes.  When a new print is added, the shopping cart checks whether a particular print in a particular size is already in the shopping cart.  If so, the count for the existing entry is updated to include the new entry, otherwise a new entry is created in the shopping cart.
  • Shopping cart can be updated both from the product pages as well as the cart itself.
  • Not all prints are available in all sizes.  The database stores which prints are available in which sizes and presents the appropriate choices in a drop-down menu.
  • Prints can belong to multiple categories.  Again, the database stores which categories a print belongs to and displays it in all appropriate views.

There is also an administrator dashboard, but at the moment I cannot provide guest access to it.  That will be changing soon.

Security measures in use:

  • Encryption of session data
  • Validation of form data to ensure it is the proper variable type and length

I debated whether to generate product thumbnails dynamically or store them on the server.  After some research I discovered it is much more efficient to store them locally, especially since they won't change once they are generated.  Hard drive space is cheap and dynamic generation is computationally expensive, so it's a win-win situation.

The Prototype JavaScript library is used for the image viewer as well as remove and update functions in the shopping cart, which use AJAX.

The design is my own, and, as always, is table-less CSS/XHTML.

Functionality I will be adding:

  • User groups for administration
  • Making dashboard accessible for guests to view (done)
  • Dynamic retrieval of product information from photoblog database (done)
jQuery, preloaders, and event delegation E-mail
Sunday, 29 March 2009 00:37

I set out this morning to create a pre-loader for my domain home, Pranshuarya.com.  Since I"m already using jQuery on the site and I feel comfortable with it, it only seemed natural to try to do it using jQuery.  I searched around for a while but nothing satisfactory was to be found.  Eventually I came across a script called Max's AJAX website preloader.  This pre-loader uses standard JavaScript to retrieve PHP and HTML content from a secondary file which it appends to the <body> tag of the index.html file where the pre-load animated GIF is being displayed.

It wasn't too much work to convert and compact the code using jQuery.  For my particular case the code went from:

// Get the HTTP Object
    function getHTTPObject(){
       if (window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP");
       else if (window.XMLHttpRequest) return new XMLHttpRequest();
       else {
          alert("Your browser does not support AJAX.");
          return null;
    // Change the value of the outputText field
    function setOutput(){
       if(httpObject.readyState == 4){
          document.getElementById('myBody').innerHTML = httpObject.responseText;

// Implement business logic
    function loadSite(){
       httpObject = getHTTPObject();
       if (httpObject != null) {
          httpObject.open("GET", "content.php", true);
          httpObject.onreadystatechange = setOutput;
    var httpObject = null;

to the following:
function loadSite(){
     jQuery.get("content.php", function(data) {

After that it came down to adding the loadSite() function to the jQuery(document).ready() function along with BlockUI:
jQuery(document).ready(function() {
      message: '<img src="images/ajax-loader.gif" />',
      css: {
       width: '100px',
       backgroundColor: '#000',
       border: '0',
       top: '40%',
       left: '45%'

One tricky problem was the fact that the elements that events were to be bound to weren't created yet, since they would appear in the document after the content.php file was loaded.  To overcome that I used the Live query plugin for jQuery for easy event delegation:

jQuery('#switcher_wrapper > div').livequery('click', function() {

and that was all it took to add a simple pre-loader image (courtesy of Ajaxload.info, by the way), to a website.

PHP frameworks E-mail
Wednesday, 18 March 2009 19:28


It's frustrating when the code that accompanies a book doesn't work.  I've gotten through half of the book and suddenly there's a problem that's mentioned on the book's forum - but without a solution.  The reason I prefer studying with books over tutorials and such is because they're structured and organized in one place, so it's disappointing when they just don't work.  I encountered the same problem in college with math errors in textbooks.  Errata are helpful but sometimes even those are incomplete!

Having seen what's possible with JavaScript frameworks like jQuery and Prototype, I set my eyes on trying out a PHP framework.  I did some reading on CakePHP, CodeIgniter, and Symfony, along with Smarty, which isn't a framework but a template engine.

I've chosen to dive in with CodeIgniter, and my tool of choice will be the following book:

Professional CodeIgniter

I chose CodeIgniter over the others mainly because of its simplicity in getting started and also its speed.  Apparently Symfony is powerful but has a steep learning curve, and CakePHP doesn't have as good documentation as the other two.

Internet Explorer resize bug E-mail
Thursday, 12 March 2009 10:15

Internet Explorer 6 and 7 have a bug where resizing a window leaves some elements fixed in position.  Specifically, elements with the style property position:relative are affected.

I came across many solutions to the problem after a search for "ie resize".  Most of them involved JavaScript.  However, I was lucky enough to find the simplest solution of all here: just add position:relative to the body element.  That's it!

jQuery and WordPress E-mail
Sunday, 01 March 2009 21:53
I'm impressed with the way jQuery integrates into WordPress.  It really helps that WordPress allows JavaScript in individual posts.  Using a script found here, it only took me a few minutes to integrate a mouseover image preview on my blog (hover over the hyperlink "trail").
Simple way to speed up your site E-mail
Wednesday, 28 January 2009 11:34

From this site I discovered a very simple way to speed up the loading of my website.

Between the </head> and <body> tags, just add:


That's it!  What this does is "It allows you to send your partially ready HTML response to the browser so that the browser can start fetching components while your backend is busy with the rest of the HTML page."


Page 5 of 8