0

New Blog Title, New Logo

As you already saw, I changed the title for this blog from “Robby Chen Personal Blog” to “Ubuntu Web Coder “as well as the logo.

One reason for changing the blog title is because I’m going to stick to Ubuntu, specifically Lucid Lynx (10.04.1), since I depend on some PPAs to get the updates. Maverick Meerkat (10.10) just doesn’t work for me. I will wait until Natty Narwhal (11.04) is out and see. If this still won’t work for me, I will stay with 10.04.1 and wait for the next release… Anyway, you get the idea.

As most of you who read this blog in the past know, I used to write code in Netbeans until I discovered the hidden potential of gedit for being such a good IDE. That’s why I abandoned Netbeans and replaced with gedit in the new logo. And I renamed blog title specifically to “coder” because I would like to try writing the code in each post from now on.

Besides the gedit logo in the new logo, I have also included two groups of logos, GNU/Linux and PHP. The GNU/Linux logos include Linux penguin, Chrome OS, Android, and Open Source. The PHP logos include PHP, CakePHP, and WordPress. I also included just released HTML5 logo created by W3C. I regularly use these tools and talked and will continue to talk about them in this blog. That’s why I included them in the logo.

What do you think about the new logo, blog title, and background color?

1

Optimize MySQL Database

For a long time since I created this blog, I had been struggled with the WordPress’ slowness. I sometimes wondered why are others’ WordPress so fast compared to mine. Then I blamed my hosting provider’s MySQL server not fast enough.

Until today, I googled for “improve mysql performance shared host” and found out about this article on optimizing MySQL performance. I logged into phpmyadmin on the server and look for the word “optimize”. At first, I was not able to find it. After carefully read the article, I found “optimize table” option under the “With selected:” drop down menu at the very bottom of Structure page.

Position of the "With selected:" menu

The arrow shows the location of the "With selected:" drop down menu which contains "Optimize table" option, click the image above to see the enlarge version.

After some experimentation, I was able to manipulate the same task in the command line (in my localhost of course, since ssh access is not available for my hosting account). The query for optimizing tables is easy:

OPTIMIZE TABLE table_name;

Note that you need back stick operator (`) if you need to use SQL keywords as table name. For example,

OPTIMIZE TABLE `table`;

Also note that SQL is case-insensitive in case you don’t know.

The video below shows you how to optimize MySQL table in action:

What do you think about this tip? Please leave your response below.

0

Some CakePHP Productive Tips

CakePHP Logo

I’ve been playing around with CakePHP for the last several days. I’m beginning to enjoy using it through the CLI (Command Line Interface) tools that comes with the framework. Maybe because I spent too much time on the command line thanks to the CR-48 (Chrome OS) developer mode :) . Anyway, here are some tips I found while learning this easy to use PHP framework:

  1. During the development, it’s a good practice to change the default value for CAKE_CORE_INCLUDE_PATH both in the index.php and test.php of webroot directory in case you forgot when deploy to the server. For example, I changed the value of this constant to $_SERVER['DOCUMENT_ROOT'] . DS . ‘cakephp’ which is converted into localhost/cakephp. Once I deployed the application to the server, the included path will change to robbychen.com/cakephp without any modification.
  2. According to the 1.2 documentation, each database has its own form control and data type relationship. For example, the tinyint data type for MySQL generates the checkbox control, whereas the boolean data type for SQLite also generates the checkbox control. It also applies to the latest stable version of CakePHP 1.3.
  3. If you want additional database options, you can download datasources plugin. This plugin also contains sqlite3 which, for some reasons, haven’t included with the CakePHP core yet. If you’re going to use SQLite in the framework without this plugin or just specify sqlite in the database config file, it will use version 2 instead.
  4. This is probably a bug in CakePHP: The CakePHP console cannot find the sqlite database file unless it’s in the root of the application folder, whereas the CakePHP web application looks for the file in the webroot directory of the application folder. The database configuration cannot be simply changed to webroot/database.sqlite. If it changes to that value, the console could find it (webroot/database.sqlite) but the web application could not (webroot/webroot/database.sqlite). The solution I decided is to make a link at the root folder to link to the sqlite file in the webroot directory. This way could both benefit the console and web application. It however does not suitable for some of you who are working on both the localhost and the production server, or often change folder, since the link target cannot be edited. The link will break once the whole directory is moved to a different machine or the target file was renamed or moved.
  5. Type cake api [type] [method] in the command line to browse through the CakePHP documentation. It is a very helpful command for use as a reference. However, you may learn some new tricks through this command, or you could use this as the primary learning resource for CakePHP assume that you already knew this command before you learn something else. For example, I found something useful for my project in the Ajax API: cake api helper ajax

I hope these tips help you to become more productive with CakePHP. If you have any questions regarding the above tips, feel free to post them in the comment below.

0

Use CR-48 as a Second Monitor (Updated)

Three laptops

Three laptopsUpdate: According to the Wikipedia, using meta tag to refresh the page is discouraged. However, I think it is okay for development. I also changed the refresh time. It seems that About.com where I originally copied the code from has incorrect information. The refresh time is in seconds, not in milliseconds.

Since my second monitor was broken long time ago, I always missed the two-screen experience.

I have an idea today that since CR-48 is always connected to the cloud, I can make it as a second monitor by connecting to my main machine’s localhost/IP address. This way I can write the code on my primary PC and instantaneously see the result from the secondary monitor by inserting the following meta tag to the testing web page:

<meta http-equiv="refresh" content="1" />

It allows web page to automatically refresh every one second so that it will show the latest rendering result whenever I save the edited web page.

Note that using this method, you can connect more than two PCs as multiple screens as long as they are connected to your home network.

Here are some photos demonstrating this method using a laptop, CR-84, and a netbook running different browsers:

Three laptops

From left to right: Firefox, Chrome OS, Opera

Address Bars

From top to bottom: Firefox (primary PC), Chrome OS, Opera

In case you don’t know, the command for checking the IP address for the primary PC is ifconfig or you can right-click the network connection icon at the top right corner and choose Connection Information:

Connection Information

Connection Information dialog

Discuss in the comment if you want to learn more about this method or have no idea what localhost is.

1

Download WordPress and Other Source Code files Directly to your Server without download Locally using PHP copy function

Intro

When I tried to get the development environment working with Chrome OS (CR-48), I thought since Chrome OS is primary working for the cloud, why am I downloading, editing, and testing the website files locally? I found out that my hosting provider, iPage, offers a file manager and a basic text editor to manage and edit my PHP files, and since I use gEdit as my main code editor, I’m pretty comfortable with the text editor.

Basic code editor

The basic code editor available in the control panel

I shortly found some useful file operation functions on the official PHP document, one of them is copy. According to its documentation, the source and destination can both be URLs since 4.3.0. This means that I can download the code from another website directly to my server using the server resources. I wrote a test page to test this function and it worked without problem.

The Code

<section id='fileDownloader'>
 <article id='urlForm'>
  <form id='url' name='url' method='post' action=''>
   <label for='urlInput'>The file to be downloaded (URL): </label>
   <input type='text' name='urlInput' id='urlInput' placeholder='URL' size='60' autofocus value="<?=($_POST['submit'])?$_POST['urlInput']:""?>" />
   <br />
   <input type='submit' value='Download' name='submit' />
  </form>
 </article>
 <?php if ($_POST['submit']): ?>
 <article id='downloadStatus'>
  <?php
  if (empty($_POST['urlInput'])): die("Please enter a valid download URL"); endif;
  $path = explode("/", $_POST['urlInput']);
  $fileName = $path[sizeof($path) - 1];
  ?>
  <?php if (file_exists($fileName)): ?>
  This file already <a href="<?=$fileName?>" title="Download file from this server">downloaded</a>.
  <?php elseif (!copy($_POST['urlInput'], $fileName)): ?>
  Download failed. Make sure that the URL is correct.
  <?php else: ?>
  Download completed. You have the option to <a href="<?=$fileName?>" title="Download from this server">download this downloaded file</a> or <a href="<?=$_POST['urlInput']?>" title="Download from the original server">download the original file here</a>.
  <?php endif; ?>
 </article>
 <?php endif; ?>
</section>

Note that I’m just staring to learn HTML5, so I can’t guarantee the above syntax is correct.

Questions

If you have any questions regarding this script, leave a comment below. And please don’t spam my server when testing on the test page, If you want to test it on your localhost, you can download the source code here.

1

A Small Fancybox Tip – Show scrollbar when viewing Large Images

onStart callback function

Intro

I use Fancybox jQuery plugin to view large/original size of images. However, its default settings don’t setup to view the large size images. It auto resizes based on the browser window size instead. According to the documentation, the options “autoScale” and “scrolling” disables the automatic scaling and enables the scrollbar to be visible respectively. However, I couldn’t figure out the scrolling option since the horizontal scrollbar is missing when viewing a large image that is bigger than the browser width. After looked into the code generated by Fancybox, I noticed that the scrolling option is applied to other than the body element, which is what I want the scrollbars to be at (edges of the browser window). So I used onStart option to write a callback function that set the overflow property for the body element to be visible.

The Code

$("element").fancybox({
 transitionIn: "elastic",
 transitionOut: "elastic",
 autoScale: false,
 onStart: function() {
  $("body").css({overflow:"visible"});
 }
});

Below is the difference between use the scrolling option and use the onStart callback function:

Scrolling

Scrolling Option

onStart callback function

onStart Callback Function

Questions

All of the above options are explained in the Fancybox document page. If you still have questions, feel free to ask them below.

0

Selectively Include jQuery Plugins

jQuery

Introduction

I’m often using jQuery and a little PHP because of the recent interest in the jQuery animation. Therefore I need lots of jQuery plugins to load in every web page. I need some plugins on each page such as Color plugin for the navigation and IE font-face ClearType fix for adding font-face support to IE, but I don’t need other plugins to load unless there is a page element specifically used with those plugins.

The Code

 // Function to create script element dynamically
function createScript(src) {
 var script = document.createElement("script");
 script.src = "scripts/" + src + ".js";
 script.type= "text/javascript";
 $("body").append(script);
}
$(window).load(function() {
  // Load the custom fonts in IE
 $("body").ieffembedfix();
  // Top Navigation Menu Animation
 $("#horiNav a").hover(function() {
  if ($(this).attr("id") != "currentPage") {
   $("#currentPage").stop().animate({backgroundColor:"#FFF", color:"#87CEEB"});
   $(this).stop().animate({backgroundColor:"#A7D4F2", color:"#FFF"});
  }
 }, function() {
  if ($(this).attr("id") != "currentPage") {
   $(this).stop().animate({backgroundColor:"#FFF", color:"#87CEEB"});
   $("#currentPage").stop().animate({backgroundColor:"#A7D4F2", color: "#FFF"});
  }
 });
 if ($("#slideshow").length != 0) {
   // Load the Cycle plugin dynamically
  createScript("jquery.cycle.all.latest");
   // Cycle through the slideshow on the home page
  $("#slideshow").cycle({
   fx: "fade",
   timeout:"3000",
   pager:"#SSnav"
  })
   // Stop the slideshow once it is clicked
  .bind("click", function() {
   $(this).cycle("toggle");
  });
 }
});

Explanation

Here I defined a function that creates a script element before the end of body. The function basically used raw Javascript code to create script element and a line of jQuery code to append the new element to the body.

I used $(window).load instead of $(document).ready method to execute the jQuery code after the page is loaded. I then demonstrated the code for the font-face support for IE and the navigation color animation.

In order to selectively include jQuery plugins, check the existence of the element that requires to use those plugins first. I used if statement to check the length of the element. Include the jQuery plugins if the number of the specified element is at least one. Then execute rest of the code within the if statement. The screenshot below shows Firebug that the page has successfully loaded the required plugin.

Loaded required jQuery plugin successfully

Loaded required jQuery plugin successfully

Head over to wcf.robbychen.com to see it in action. Make sure to open Firebug when visiting the site to see which jQuery plugins are loaded. Right now only the homepage and Who We Are page use additional jQuery plugins.

Questions

If you have any question about the above code, feel free to post them in the comments below.

27

Reinstall Ubuntu on CR-48 notebook with USB

Introduction

According to the /etc/X11/xorg.conf in the Chrome OS, the USB devices need to be manually mounted (AutoAddDevices=’false’). I inserted a sample USB device and run lsusb command to see if detected. It detected successfully without any problem. I then copied the image file with 5GB of size onto the USB drive with a little bit of issue. Using only steps from one small section on the official Chromium OS page, I was able to successfully reinstall Ubuntu on the Chrome OS in about 45 minutes (and downgraded to 10.04 since WebDAV support is broken in 10.10). Here are the detailed steps:

Steps

  1. You need an empty USB thumb drive. The file we are going to copy to the USB drive is more than a little 5GB. The file system for the most flash drives is vfat (FAT file system). It has a single file size limit of about 3GB which our file would fail to copy to the disk.  To solve this issue, you need to reformat your flash drive to the file system format other than FAT using the Disk Utility from System -> Administration menu.

    Disk Utility

    I formated my USB drive as EXT4

  2. Copy rootfs.bin you converted from VDI image to the USB drive.
  3. After it’s finished, insert the drive into the USB slot of CR-48.
  4. Boot into Chrome OS, press Ctrl + Alt + => to switch to develop mode, and login as chronos.
  5. Type sudo su to login to root and type the following line to get the information on where the USB drive is located:
    dmesg | grep sd
  6. /dev/sdb1

    My device is located at /dev/sd1

    My USB drive is located at /dev/sdb1, so I type the following to the command line (replace sdb1 with yours):

    mkdir /tmp/usb
    mount /dev/sdb1 /tmp/usb
    
  7. After it’s mounted, copy rootfs.bin to sda7 with dd command:
    cd /tmp/usb
    cat rootfs.bin | dd of=/dev/sda7
    

    This should take about 20 minutes.

  8. Mount sda7 after that and copy the necessary files to the disk:
    mkdir /tmp/urfs
    mount /dev/sda7 /tmp/urfs
    cd /tmp/urfs
    cp /usr/bin/cgpt usr/bin/cgpt
    chmod a+rx usr/bin/cgpt
    cd /lib/modules
    cp -ar * /tmp/urfs/lib/modules/
    
  9. And finally, don’t forget to unmount the disk:
    umount /tmp/urfs
    umount /tmp/usb
    
  10. There you have it, a brand new Ubuntu installation. You can use the following command to boot into Ubuntu or use the aliases from my last post:
    cgpt add -i 6 -P 5 -S 1 /dev/sda
    

Have issues?

Do you have any issues with any of the steps above? Please feel free to discuss them below.

0

Final Revision for Scrolling Animation Code, Maybe

scrollAnime

Introduction

After I revised the scrolling animation jQuery code yesterday, I was going to rewrite it using Mootools. However, I noticed that this code was doing two unnecessary actions. The first one is the removing of the first set of images, and another one is the appending of new sets of images. Several minutes after my eyes watched the scrollbar animate back and forth, I revised the code to the following.

The Code


if ($("#whoWeAreImages").length != 0) {
  // Scroll Animation for the images in the Who We Are page
 var $whoWeAreImages = $("#whoWeAreImages"),
 $wwaLink = $whoWeAreImages.find("a"),
 $wwaImg = $whoWeAreImages.find("img"),
 scrollWidth = $whoWeAreImages.attr("scrollWidth");
  // Do the following once the page is loaded
 $whoWeAreImages.css({overflow:"hidden"})    // Hide the images scrollbar
 .scrollLeft(0)    // Make sure the scrollbar is at the beginning when the page is reloaded
 .append($(this).html()) // Add one more set of images
  // Begin the animation
 .autoscroll({
  direction: 0,
  step: 50,
  onEvaluate: function() {
    // Click action for the images in the Who We Are page
   $wwaLink.fancybox({
    transitionIn: "elastic",
    transitionOut: "elastic"
   })
    // Scroll to the beginning once it scrolls to the beginning of the second set of images
   if ($(this).scrollLeft() >= scrollWidth) {
    $(this).autoscroll("pause");
    $(this).attr("scrollLeft", "0");
    $(this).autoscroll("resume");
   }
  }
 })
 .autoscroll("addpausesource", $wwaImg);
}

Explanation

In the above code, I removed the remove() action and added the append action at the beginning of the loop. It means that it will only has two sets of images available instead of an infinite loop that remove and append continuously to limit two loops which has slower performance.

After this revision, the animation lag still exists. This is probably the final revision of the code before I rewrite it using Mootools because I might discover some techniques during the rewriting of this code.

3

Revision for the Auto Scrolling Animation code

scrollAnime

Introduction

Since I wrote the auto scrolling animation code with jQuery two days ago, I struggled with the browser performance while running this animation. It seems that the animation needs lots of CPU power and it sometimes appears to be lagging. In order to solve the CPU issue, I included a jQuery plugin named Autoscroll. As the name applies, it automatically scrolls the specified element. This has the same feature as the code I wrote, but it’s a plugin and it will immediately stop the animation when in hover state whereas my code stops animation few seconds after the cursor was hovered over the element.

The Source Code

The following is the revised code:

if ($("#whoWeAreImages").length != 0) {
  // Scroll Animation for the images in the Who We Are page
 var $whoWeAreImages = $("#whoWeAreImages"),
     $wwa = $(".WWA:first"),
     $wwaLink = $whoWeAreImages.find("a"),
     $wwaImg = $whoWeAreImages.find("img"),
     scrollWidth = $whoWeAreImages.attr("scrollWidth"),
     wwaHTML = $whoWeAreImages.html();
  // Do the following once the page is loaded
 $whoWeAreImages.css({overflow:"hidden"})    // Hide the images scrollbar
 .scrollLeft(0)    // Make sure the scrollbar is at the beginning when the page is reloaded
  // Begin the animation
 .autoscroll({
  direction: 0,
  step: 50,
  onEvaluate: function() {
    // Click action for the images in the Who We Are page
   $wwaLink.fancybox({
    transitionIn: "elastic",
    transitionOut: "elastic"
   })
    // Remove the first set of images in order to limit loop
   if ($(this).scrollLeft() >= scrollWidth) {
    $wwa.remove();
    $(this).autoscroll("pause");
    $(this).attr("scrollLeft", "0");
    $(this).autoscroll("resume");
   }
  },
  onEdge: function(a) {
   if ($(this).attr("scrollLeft") != 0) {
     // Append the same images to the end of the last image if it finished scrolling to loop through the animation
    $(this).append(wwaHTML);
   }
  }
 })
 .autoscroll("addpausesource", $wwaImg);
}

Explanation

As you can see in the code, I optimized the code to use the chaining method for jQuery.

I also changed the way images were looped. When scrollLeft greater than or equals to scrollWidth, the first set of images will be removed/deleted, pause the animation, set scrollLeft to zero, and restart the animation.

This means that when the position of the scrollbar reaches the beginning of the second set of images (or second loop), delete the first set of images using :first pseudo selector and reset the scrollbar position to the beginning. Since the scrollbar position will be at the end of the first loop and the beginning of the second loop, remove the first loop and reset the scrollbar position have n0 effect on the animation. The animation would continue to loop through the images without interruption but it’s limited to two loops.

Although the code was optimized, the animation still has some lag. It will sometimes stop and continue without interaction, much like the under-powered graphics card. I have not yet find any solution to this issue yet. However, I found out that Mootools animation is sometimes more smooth than jQuery. I will try to use Mootools to animate the auto scroll later.

Do you believe that Mootools  animation is more smooth than jQuery? Please share your opinion in the discussion.

Pages ... 1 2 3 4 5 6 7 8 9 10 11