Categories
Books

Developing Hybrid Applications for the iPhone

Developing Hybrid Applications for the iPhonePicked up a copy of Developing Hybrid Applications for the IPhone by Lee S. Barney earlier this week. Had a 33% off coupon at Borders and was itching for something new to read.

Been messing with iPhone development for a bit and since I’m a web developer figured I’d take a hard look at writing web applications for the iPhone vs going the SDK Objective-C route.

I’m really glad I picked this book up. They do an excellent job of reminding me how cool Dashcode is for developing web applications for the iPhone. My only knock on Dashcode in the past was the lack of documentation, but this book does a decent job of covering it. Still wish there was more documentation on Dashcode if anyone is reading this.

The book covers both using the QuickConnect and PhoneGap frameworks for developing hybrid iPhone apps. It’s a fairly easy read and they do cover most of the iPhone functionality that would be used in the majority of projects. While the SDK and Objective-C are still the best way to go, sometimes web applications or hybrid applications do make sense, and that’s where this book was very handy. Just for me to rediscover Dashcode alone justified the purchase.

Categories
Books

Learning Joomla! 1.5 Extension Development

If you’re looking to create extensions for Joomla! 1.5 then you should really check out Learning Joomla! 1.5 Extension Development. I had a project that required a custom component to be created, and the online documentation wasn’t really as good as I’d of liked it to of been.

So I went looking to see if any books had been published recently on extension development. Learning Joomla! 1.5 Extension Development got some decent review online, and I was really stumped with creating my component. So a copy was ordered.

The book does an excellent job of building an extension that makes use of most of the features that would be found in a typical extension. Covering, components, modules, as well as plugins.

With it’s focus on MVC practices, this at first seemed like overkill to me, but once all the features were piling up, it really paid off.

The chapters on creating the admin end of a component were extremely valuable to me. My client now has an easy to use custom component that makes use of the Joomla! admin interface for a seemless CMS experience.

Categories
Development

YUI 3 Gallery

I’ve really been meaning to make the switch over from YUI 2.x to 3.x, and I do believe the YUI 3 Gallery has made up my mind. The Gallery is a repository of YUI 3 modules that aren’t addressed by the core library. Also, all modules are released under the same BSD license as the YUI Library.

Even though the Gallery is fairly new, the amount of modules is already pretty impressive. Some that I’m very excited to play with are:

This looks very cool, and if you’re using YUI3 go now.

Categories
Development

Google App Engine

I’ve finally gotten around to messing around with the Google App Engine over the weekend. It allows you to run web applications on Google’s infrastructure for free as long as you don’t go over roughly 5 million page views in a month. If your app has the good problem of going over that traffic then you’re billed by usage.

Currently only Python and Java are the supported languages. I’ve been interested in dabbling with Python a bit more than I have, and building an app on this platform has given the excuse I need to try it out.

Getting started is fairly easy. Sign up for an account at the Google App Engine site. Then download the SDK for your OS. Leopard already has Python 2.5 installed, so I didn’t have to install or upgrade that.

There’s an amazing getting started guide available for building a simple Python app. It’s one of the better tutorials I’ve done in a while, even if you’re not proficient with Python it’s easy to follow along.

Using the datastore to work with data vs. a relational database seemed strange at first, but it’s very easy to work with. The GQL can be very similar to working with SQL.

I’ve got a couple of ideas I’ll like to try building, and this seems like a great platform to build on.

Categories
Development

Insert row into Google Spreadsheet using Zend Framework

I got a little stumped when attempting to insert a new row in a Google Docs Spreadsheet using the Zend Framework, so I figured I’d share this in case someone else runs in the same problems. The documentation provided is really great, but I was getting caught in how the row data was supposed to be getting passed. It just needs a basic array with key/value pairs.

First you need to have the Zend Framework installed on your server. Google Code has a great article on getting started. Then you need to have a spreadsheet in Google Docs.

Now we’re going to write a simple PHP script that will input a new row into a basic spreadsheet. First you need to call the following Zend Framework include files for the script to work:

require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Spreadsheets');

Next we’re going to set two variables with your Google Docs login info to authenticate our row creation. Enter you Google Account login:

$email = '<your_google_account_username>';
$pass = '<your_google_account_password>';

Now we authenticate ourselves with Google Docs and create a Zend_Gdata_Spreadsheets object.

$authService = Zend_Gdata_Spreadsheets::AUTH_SERVICE_NAME;
$httpClient = Zend_Gdata_ClientLogin::getHttpClient($email, $pass, $authService);
$spreadsheetService = new Zend_Gdata_Spreadsheets($httpClient);

Next we have to let Google Docs know which of our spreadsheets we want to write to. To do this we need the spreadsheet key. Obtaining the key is fairly simple, just grab it from the spreadsheet’s URL.

For instance:

https://spreadsheets.google.com/a/atlantic.edu/ccc?key=pqtY4KMBjwqlinsu9-f1PEg&hl=en

the key is:

pqtY4KMBjwqlinsu9-f1PEg

Not only do we need the spreadsheet key, but you also have to know what the worksheet id is too. Obtaining the worksheet id can be a little tricky, but if you only have one worksheet then it usually always is od6.

$spreadsheetKey = 'pqtY4KMBjwqlinsu9-f1PEg';
$worksheetId = 'od6';

Now we have to create the row data that we want to add to the above mentioned spreadsheet. You have to pass it an array with key/value pairs. The key is the column label in all lower case.

So to add a new row containing the string smurf to a column named stuff you build the following array:

$rowData = array('stuff' => 'smurf');

That’s it. If you were adding to more columns you would just pass more key/value pairs to the variable.

Now you just call the insertRow method and you’re all set.

$insertedListEntry = $spreadsheetService->insertRow($rowData, $spreadsheetKey, $worksheetId);

Pretty easy and very cool stuff.

Categories
Development

Feature Box

Needed to create an area on a web page that could contain several feature items that could be easily navigated through. There are many excellent carousel type components available, but they didn’t meet all my needs or were conflicting with a drop down menu that we have on this particular site. So I decided to create my own solution.

So that it’s semantically correct, all you need is to wrap a div around an ordered list and give that div an id of “feature-box”.

<div id="feature-area">
    <ol>
        <li><img src="http://www.atlantic.edu/aca/images/homeSplashCareer.jpg" width="548" height="200" alt="Turn your passion into a culinary career" /></li>
    	<li><img src="http://www.atlantic.edu/aca/images/homeSplashBaking.jpg" width="548" height="200" alt="Rise to the challenge of a baking and pastry career" /></li>
    	<li><img src="http://www.atlantic.edu/aca/images/homeSplashFire.jpg" width="548" height="200" alt="Get fired up for a culinary career" /></li>
    	<li><img src="http://www.atlantic.edu/aca/images/homeSplashRestaurant.jpg" width="548" height="200" alt="Learn in a real restaurant setting" /></li>
    </ol>
</div>

The rest of my javascript relies pretty heavily on the YUI DOM Collection and the YUI Event Library, so I included their yahoo-dom-event.js file. YUI library is amazing and if you’re not familiar with it I highly recommend you check it out.

<script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>

Then I wrote up a little function that on page load takes the ordered list and only shows the first item and creates the navigation to control the feature box.

init:function(e) {
    // object test if js available
    if (!document.getElementById || !document.createTextNode){return;}
    if (!document.getElementById("feature-area")) return false;
 
    // assign feature-aread div, ol, and items
    var featureDiv = document.getElementById('feature-area');
    var featureOl = featureDiv.getElementsByTagName('ol');
    var featureItems = featureOl[0].getElementsByTagName('li');
 
    // set class on li's to hide and show for the first item
    for (var i=1; i<featureItems.length; i++) {
        YAHOO.util.Dom.addClass(featureItems[i], 'hide');
    }
    YAHOO.util.Dom.addClass(featureItems[0], 'show');
 
    // create navigation
    var navDiv = document.createElement('div');
    navDiv.setAttribute('id', 'feature-nav');
    navDiv.innerHTML = '<a href="#" id="feature-prev">prev</a> <span id="feature-nav-marker"></span> <a href="#" id="feature-next">next</a>';
 
    // insert navigation
    YAHOO.util.Dom.insertAfter(navDiv, featureOl[0]);
 
    // create nav dots
    for (var i=0; i<featureItems.length; i++) {
        var navMarkerItem = document.createElement('span');
	var navMarkerId = 'feature-nav-'+i;
	navMarkerItem.setAttribute('id', navMarkerId);
	navMarkerItem.innerHTML = 'item '+i;
	var navMarkerList = document.getElementById('feature-nav-marker');
	navMarkerList.appendChild(navMarkerItem);
	// assign class of active to first marker
	if (i==0) {
	    YAHOO.util.Dom.addClass(navMarkerItem, 'active');
	}
	YAHOO.util.Event.addListener(navMarkerItem, "click", acccFeatureArea.gotoFeature);
    }
}

First we grab then apply the class of “hide” to all the list items’s. But the very first list item we apply a class of “show”. Now only the first list item is being displayed.

// assign feature-aread div, ol, and items
var featureDiv = document.getElementById('feature-area');
var featureOl = featureDiv.getElementsByTagName('ol');
var featureItems = featureOl[0].getElementsByTagName('li');
 
// set class on li's to hide and show for the first item
for (var i=1; i<featureItems.length; i++) {
    YAHOO.util.Dom.addClass(featureItems[i], 'hide');
}
YAHOO.util.Dom.addClass(featureItems[0], 'show');

Then we create the navigation. To figure out how many navigation dots to create, we have to figure out how many list items there are. Also those navigation dots need an event handler attached to them so they can be used to control the feature box.

// create navigation
var navDiv = document.createElement('div');
navDiv.setAttribute('id', 'feature-nav');
navDiv.innerHTML = '<a href="#" id="feature-prev">prev</a> <span id="feature-nav-marker"></span> <a href="#" id="feature-next">next</a>';
 
// insert navigation
YAHOO.util.Dom.insertAfter(navDiv, featureOl[0]);
 
// create nav dots
for (var i=0; i<featureItems.length; i++) {
    var navMarkerItem = document.createElement('span');
    var navMarkerId = 'feature-nav-'+i;
    navMarkerItem.setAttribute('id', navMarkerId);
    navMarkerItem.innerHTML = 'item '+i;
    var navMarkerList = document.getElementById('feature-nav-marker');
    navMarkerList.appendChild(navMarkerItem);
    // assign class of active to first marker
    if (i==0) {
        YAHOO.util.Dom.addClass(navMarkerItem, 'active');
    }
    YAHOO.util.Event.addListener(navMarkerItem, "click", acccFeatureArea.gotoFeature);
}

Functions are attached to the navigation arrows to reveal the next item in the list while hiding all the other items. If it’s at the end or beginning of the list it then circles around to the first or last item.

nextFeature:function(e) {
    var currentItem = YAHOO.util.Dom.getElementsByClassName('show', 'li', 'feature-area');
    var nextItem = YAHOO.util.Dom.getNextSibling(currentItem[0]); 
    // if no more items, go to first item
    if (nextItem == null) {
        var featureItems = YAHOO.util.Dom.getElementsByClassName('hide', 'li', 'feature-area');
	var nextItem = featureItems[0];
    }
 
    YAHOO.util.Dom.replaceClass(currentItem[0], 'show', 'hide');
    YAHOO.util.Dom.replaceClass(nextItem, 'hide', 'show');
    acccFeatureArea.setMarker();
}

The navigation dots get their own function attached to them to reveal their respective list item. It adjusts the class associated with the list items as well as the navigation dots to control the feature box.

gotoFeature:function(e) {
    // assign feature-aread div, ol, and items
    var featureDiv = document.getElementById('feature-area');
    var featureOl = featureDiv.getElementsByTagName('ol');
    var featureItems = featureOl[0].getElementsByTagName('li');
 
    var navMarker = document.getElementById('feature-nav-marker');
    var navMarkerItems = navMarker.getElementsByTagName('span');
 
    var navMarkerId = this.getAttribute('id');
    var currentSelection = navMarkerId.substring(navMarkerId.length-1);
 
    if (this.className != 'active') {
        for (var i=0; i<featureItems.length; i++) {
	    YAHOO.util.Dom.replaceClass(featureItems[i], 'show', 'hide');	
	}
	YAHOO.util.Dom.replaceClass(featureItems[currentSelection], 'hide', 'show');
 
	for (var i=0; i<navMarkerItems.length; i++) {
	    YAHOO.util.Dom.removeClass(navMarkerItems[i], 'active');
	    YAHOO.util.Dom.addClass(navMarkerItems[currentSelection], 'active');
	}
    }
}

Here is a link to a sample of this.