Creative Meat Blog
Tutorials

Oneupweb : Write a Simple Ajax Library for Javascript!

Posted by Brian in Development, Tutorials on August 23, 2011 - 8:34 pm

Everyone has their favorite Ajax library. Weather it be prototype, jQuery, or some lesser known yet equally awesome library that allows you to harness the power of Ajax—it seems you can find these anywhere these days.

In this tutorial, we are going to explore writing our own simple Ajax module using JavaScript.

Setup the module

True to the JavaScript module pattern, we will wrap our little tool up in an anonymous function

(function(){

}).call(this); //"this" will be the window object

Why do we do this? We can easily invoke this function on the global window object, and because we are inside of a function we can gain the benefit of private members, and thus avoid naming conflicts and people accidentally overwriting our methods. Let’s take advantage of this fact by setting up a few private properties and methods for our Ajax module:

(function(){
//the global window object
var root = this,
//our XMLHttp object
http = null,
//a function to get the XMLHttp object
getXmlHttp  = function() {
	if (! http ) http = new XMLHttpRequest;
	return http;
},
//a helper function to build query strings
joinParams = function(params) {
	var str = '';
	for ( var k in params ) {
		str += k + '=' + params[k] + '&';
	};
	return str.replace('/&$/','');
}
}).call(this);

//create our namespace on the global window object
root.Ouw = {};

Add the Ajax singleton

We are going to create a single Ajax singleton to act as our powerhouse for Ajax interaction. We can do this by adding an Ajax property to our module.

Ouw.ajax = {
};

Next we add all the necessary methods to communicate with the server.

Ouw.ajax = {
	request:function(params) {
		var method = params.type,
			url = params.url,
			data = joinParams(params.data),
			success = params.success;

		if ( /get/i.exec(method) ) {
			if ( data ) url = url + '?' + data;
		}
		http = getXmlHttp();
		if ( http ) {
			http.open(method.toUpperCase(),url,true);
			http.onreadystatechange = function() {
				if ( http.readyState == 4 ) {
					if ( http.status == 200 ) {
						success(http.responseText);
					}
				}
			}
		}
		if ( /get/i.exec(method) ) {
			http.send(null);
		} else {
//send the same headers an html form would
			http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			http.setRequestHeader("Content-length", data.length);
			http.setRequestHeader("Connection", "close");
			http.send(data);
		}
	},
        //a wrapper for easy get requests
	get:function(url,fn) {
		this.request({
			type:'get',
			url:url,
			success:fn
		});
	},
        //a wrapper for easy post requests
	post:function(url,data,fn) {
		this.request({
			type:'post',
			url:url,
			data:data,
			success:fn
		});
	}
};

Putting it all together

The source code as a whole:

(function(){
var root = this,
	http = null,
	getXmlHttp  = function() {
		if (! http ) http = new XMLHttpRequest;
		return http;
	},
	joinParams = function(params) {
		var str = '';
		for ( var k in params ) {
			str += k + '=' + params[k] + '&';
		};
		return str.replace('/&$/','');
	}

root.Ouw = {};
Ouw.ajax = {
	request:function(params) {
		var method = params.type,
			url = params.url,
			data = joinParams(params.data),
			success = params.success;

		if ( /get/i.exec(method) ) {
			if ( data ) url = url + '?' + data;
		}
		http = getXmlHttp();
		if ( http ) {
			http.open(method.toUpperCase(),url,true);
			http.onreadystatechange = function() {
				if ( http.readyState == 4 ) {
					if ( http.status == 200 ) {
						success(http.responseText);
					}
				}
			}
		}
		if ( /get/i.exec(method) ) {
			http.send(null);
		} else {
			http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			http.setRequestHeader("Content-length", data.length);
			http.setRequestHeader("Connection", "close");
			http.send(data);
		}
	},
	get:function(url,fn) {
		this.request({
			type:'get',
			url:url,
			success:fn
		});
	},
	post:function(url,data,fn) {
		this.request({
			type:'post',
			url:url,
			data:data,
			success:fn
		});
	}
};

}).call(this);

Using this bad boy is a snap!

Ouw.ajax.get('http://www.creativemeat.com/test.xml',function(xml){
    alert(xml);
})

//or how about a post request
Ouw.ajax.post('http://www.creativemeat.com/someaction.php',{one:'two'},function(resp){
    alert(resp);
});

Clean it up and make it your own

It’s up to you to support older versions of IE, and add any kind of fancy functionality to your new module. Happy coding!

GD Star Rating
loading...
Tutorials

Coding a simple jQuery centering plugin

Posted by Brian in Tutorials on July 28, 2011 - 8:36 pm

There are quite a few tutorials out there on how to make plugins for jQuery. Quite a few of those tutorials cover how to make a plugin that centers an element within another one.

This tutorial will recap some plugin development basics, as well as add a bit more utility to our center plugin.

Step One: The shell of a jQuery plugin

Every jQuery plugin should be wrapped in a closure like so:

(function($){
//plugin code here
})(jQuery);

This anonymous function allows us to have variables in a private scope that matter to our plugin and only our plugin. Since the anonymous function is invoked right away and passed the window’s jQuery object, which we pass in as the famous dollar sign, we don’t have to worry about any naming conflicts.

Step Two: jQuery.fn—the place to plugin

jQuery provides a place to add functions to the jQuery object. This place is jQuery.fn. Any properties you add as functions to this, will be available to jQuery. To make a center function that will allow something like $(‘#myelem’).center(), we set our plugin up like so:

(function($){
    $.fn.center = function(options) {
    };
})(jQuery);

You will notice we create an argument for our function called options. This is a great way for people to pass in configuration options for the plugin. Let’s set up our center plugin.

Step Three: Setting up the center plugin

Let’s set up our default options, and the functions we will need to handle the centering:

(function($){
    $.fn.center = function(options) {
        //keep your var declaration count down
        var defaults = {
            type:'both',
            //this could be body,a selector, the window, whatever floats your boat
            container:$('#container')
        },
        //this refers to the current jQuery object i.e $('#myelemtocenter')
        elem = this,
        //our helper function to center vertically
        vert = function() {
            elem.css("top", ((options.container.height() - elem.outerHeight()) / 2) + options.container.scrollTop() + "px");
        },
        //our helper function to center horizontally
        horiz = function() {
            elem.css("left", ((options.container.width() - elem.outerWidth()) / 2) + options.container.scrollLeft() + "px");
        }
    };

    //finally we map our defaults and any options that override them
    options = $.extend({},defaults,options);
})(jQuery);

Step Four: Let’s center some stuff

It’s as easy as looking at our options and reacting accordingly:

(function($){
    $.fn.center = function(options) {
        var defaults = {
            type:'both',
            container:$('#container')
        },
        elem = this,
        vert = function() {
            elem.css("top", ((options.container.height() - elem.outerHeight()) / 2) + options.container.scrollTop() + "px");
        },
        horiz = function() {
            elem.css("left", ((options.container.width() - elem.outerWidth()) / 2) + options.container.scrollLeft() + "px");
        }
    };
    options = $.extend({},defaults,options);

    //set the position to absolute
    this.css('position','absolute');
    //if you like, set the parent position to relative
    //personally, I would save this for a stylesheet
    //this.parent().css('position','relative');

    //check the options and use the helpers!
    if ( options.type === 'horizontal' ) {
        //just center horizontally
        horiz();
    } else if ( options.type === 'vertical' ) {
        //just center vertically
        vert();
    } else {
        //center both vertically and horizontally
        horiz();
        vert();
    }
    //always return this to maintain the ability to chain
    return this;
})(jQuery);

Step Five: Use that plugin!

Using the center plugin is really easy!

//center vertically and horizontally in the default container
$('#box').center();

//center vertically and horizontally in the body
$('#box').center({
    container:$('body')
});

//center just horizontally in the main div, then change the background color
$('#box').center({
    type:'horizontal',
    container:$('#main')
}).css('background','red');

Hopefully this tutorial gave you a good head start on plugin development in jQuery, and hopefully will provide a handy little tool to use in your projects.

GD Star Rating
loading...
Tutorials

Oneupweb : Web Scraping—The Freaker Way!

Posted by Brian in Development, Tutorials on June 29, 2011 - 3:40 pm

It is nothing new. Giants like Google have been scraping the web for ages now. What is this scraping you ask? Web scraping is the process of collecting data from another web page and usually involves using that data in a meaningful way. Our team here has nothing but mad love for the folks over at Freaker USA. It all started with a post by one of our interactive graphic designers, which inspired our PR specialist to give a shout out, and now I’m joining in on their freaky obsession. So today I am going to give a brief how-to on web scraping, specifically collecting Freaker data and creating your own Freaker catalog with PHP to promote this boss sauce of a product.

View Final Product

Tools of the trade…

We need to fetch the catalog page from the Freaker USA website, and parse the contents that are returned. The main workhorse of our script will be:

  1. The PHP function file_get_contents (for fetching the remote web page)
  2. The PHP DOM extension (for parsing the requested page)

Fetch those Freakers!

Let’s take a look at our function that will get our Freaker data.

function get_freakers() {

	//our site details
	$domain = 'http://www.freakerusa.com';
	$catalog = $domain . '/collections/all';
	$products_id = 'products';

	//read the catalog
	$document = new DOMDocument();
	$page_contents = file_get_contents($catalog);
	@$document->loadHTML($page_contents);

	//get the products
	$productsElem = $document->getElementById($products_id);
	$products = array();
	$listItems = $productsElem->getElementsByTagName('li');

	$i = 0;
	while ( $listItems->item($i) )
	{
		$title = $listItems->item($i)->getElementsByTagName('h3')->item(0)->nodeValue;
		$anchor = $listItems->item($i)->getElementsByTagName('a')->item(0);
		$img = $anchor->getElementsByTagName('img')->item(0);
		$href = $domain . $anchor->getAttribute('href');
		$image = array(
			'alt' => $img->getAttribute('alt'),
			'src' => $img->getAttribute('src')
		);
		$price = $listItems->item($i)->getElementsByTagName('p')->item(0)->nodeValue;
		$products[] = array(
			'title' => $title,
			'href' => $href,
			'img' => $image,
			'price' => $price
		);
		$i++;
	}

	return $products;
}

If we head over to the Freaker USA catalog, we can see each product is wrapped in a nice list item belonging to an unordered list with an id of “products”

<li>
	<!-- START IMAGE -->
	<div class="image">
		<div class="align">
			<div><a href="/collections/all/products/america"><img alt="Vin Diesel" src="http://cdn.shopify.com/s/files/1/0066/5282/products/IMG_1366_medium.jpg?100851"></a></div>
		</div>
	</div>
	<!-- END IMAGE -->
	<h3><a href="/collections/all/products/america">Vin Diesel</a></h3>
	<p>$8.00</p>
</li>

Get the remote page

The first thing we do is get the catalog page from the Freaker site. This is done in the following lines of the get_freakers function:

//our site details
$domain = 'http://www.freakerusa.com';
$catalog = $domain . '/collections/all';
$products_id = 'products';

//read the catalog
$page_contents = file_get_contents($catalog);

First we create a variable for the domain of the Freaker USA site—this helps us if we want to read additional pages as well. And as we will see it can be used in targeting pesky relative URLS.
Next we create a variable for the catalog and the ID of the main element that is responsible for holding the individual products. This information will be useful for getting the actual product catalog and parsing it with the DOM extension. Now we are all ready to parse out the information that we want.

Getting the relevant information

The rest of our function deals with getting the individual products:

    $document = new DOMDocument();
	@$document->loadHTML($page_contents);

	//get the products
	$productsElem = $document->getElementById($products_id);
	$products = array();
	$listItems = $productsElem->getElementsByTagName('li');

	$i = 0;
	while ( $listItems->item($i) )
	{
		$title = $listItems->item($i)->getElementsByTagName('h3')->item(0)->nodeValue;
		$anchor = $listItems->item($i)->getElementsByTagName('a')->item(0);
		$img = $anchor->getElementsByTagName('img')->item(0);
		$href = $domain . $anchor->getAttribute('href');
		$image = array(
			'alt' => $img->getAttribute('alt'),
			'src' => $img->getAttribute('src')
		);
		$price = $listItems->item($i)->getElementsByTagName('p')->item(0)->nodeValue;
		$products[] = array(
			'title' => $title,
			'href' => $href,
			'img' => $image,
			'price' => $price
		);
		$i++;
	}

	return $products;

We first create a new DOMDocument object and load our requested content into it. (The little @ symbol suppresses the warnings that are common when requesting remote pages; HTML parsers are picky little buggers). Once we have our page loaded into our document object we select the product container by its ID (in this case ‘products’). Remember from looking at the html above from the Freaker USA catalog page that each product is an HTML list-item belonging to the “products” list. We store our products in the variable $listItems. This isn’t a tutorial on using the DOM extension, but you should be able to follow the while loop that is getting all the data we need. We return all of our Freaker data in an array of associative arrays containing everything we need to output Freakers anywhere on our site!

Output your Freaker catalog

Now that we have our handy get_freakers function, we can ouput our catalog any way we like. I will choose to use a small little template like so:

<?php
require_once 'freaker.php'; //we keep our get_freakers function in here
$freakers = get_freakers();
?>
<div id="freakers">
<?php foreach ( $freakers as $freaker ):?>
	<div class="freaker">
		<h3><a target="_blank" href="<?php echo $freaker['href']; ?>"><?php echo $freaker['title']; ?></a></h3>
		<div class="freaker-thumb">
			<a target="_blank" href="<?php echo $freaker['href']; ?>">
				<img src="<?php echo $freaker['img']['src']; ?>" alt="<?php $freaker['img']['alt']; ?>" />
			</a>
		</div>
		<p class="price">
			<?php echo $freaker['price']; ?>
		</p>
		<a target="_blank" class="buy" href="<?php echo $freaker['href']; ?>">BUY!</a>
	</div>
<?php endforeach; ?>
</div>

Add a dab of CSS and…. voila! We now have a catalog of our very own to promote such a fabulous product!
Our very own Freaker USA catalog! BOSS!!

How will you get your Freaker on?

The cool thing about this is it will stay up to date with the Freaker USA catalog (provided they don’t change their markup, but you being the pro you are now, you can certainly keep up to date on this ). There are plenty of other possibilities for this type of application. You could use the data you collect to create a handy sidebar widget for WordPress, or maybe create a Facebook tab? There is no stopping you! So go get your web scraping on!

GD Star Rating
loading...
Tutorials

Oneupweb : Ajax in WordPress

Posted by Brian in Development, Tutorials on May 12, 2011 - 8:31 pm

Ajax in WordPress is all kinds of easy. We are going to give an example in the functions.php file, but you can just as easily implement this inside of a plugin. Ajax functionality is accomplished like many other things in WordPress, through the use of actions and callback functions. Let’s give the example of outputting a simple message sent from the server:

add_acction('wp_ajax_alert_message','get_alert_message');
add_acction('wp_ajax_nopriv_alert_message','get_alert_message');
function get_alert_message() {
     $response = array(
            'user' => 'Brian',
            'message' => 'Hello'
      );
      header('Content-Type: application/json');
      echo json_encode($response);
      //make sure you exit otherwise further output will be processed and mess up your response!
      exit;
}

The little snippet above will put a hook in place for your JavaScript to make a call to. The actions we are adding to are “wp_ajax_alert_message” and “wp_ajax_nopriv_alert_message”. The “alert_message” part of those actions are what we will reference in our JavaScript. We prefix our action name with “wp_ajax_” and “wp_ajax_nopriv_” to say we want logged in users (wp_ajax_) and non logged in users (wp_ajax_nopriv_) to be able to see this ajax in action.

Let’s queue up our JavaScript like so:

add_action('init','my_alert_script');
function my_alert_script() {
       wp_enqueue_script('myalertjs','path/to/js/myalert.js',array('jquery'));
}

And our JavaScript……

(function($){

$(document).ready(function(){
    var data = {
          action:"alert_message" //look familiar? this comes after our wp_ajax_ and wp_ajax_nopriv_ actions we added in functions.php
    };

    //lets talk to the server when we click a button
    $('#mybutton').click(function(){
           //ajaxurl is a global JavaScript variable WordPress provides. neat huh?

           //if for some reason you are getting ajaxurl is undefined, it points to /wp-admin/admin-ajax.php
           //var ajaxurl = "/wp-admin/admin-ajax.php"
           $.post(ajaxurl,data,function(resp){
                   alert(resp.message + ' ' + resp.user);
           },'json');
    });
});

})(window.jQuery); //easy workaround to use the $ factory we all love so much

Try it out!

Naturally I can’t wait to see how you use your new found knowledge of ajax in WordPress to take WordPress functionality to the next level!

GD Star Rating
loading...
Tutorials

Back to the Basics: Basic Photo Retouching Tips & Tricks

Posted by admin in Design, Tools, Tutorials on May 5, 2011 - 1:54 pm

Understanding photography is only half of the battle to taking a successful picture. Understanding Photoshop and how it can help to enhance your photo is the other half. In today’s blog I will briefly go into some very basic and simple editing tools that can help take your photo to the next level.

(Example based on PC version of CS4)

To help demonstrate these tools I will take this already dashing gentleman and make him even more dashing (to avoid his fan club and stalkers, because let’s face it, he’s a pretty big deal) and I will refer to him simply as “Ronaldo”:

Levels: The very first thing, regardless of how perfectly you set up your lighting, you will want to adjust the levels of your image. This will help to enhance the dark and light areas of your photo and make it more balanced if done correctly. To find the levels panel in Photoshop simply go to Image > Adjustments > Levels or ctrl  + L. When editing levels play with the two outer arrows (remember: the one to the left will adjust your shadows or blacks and the one to the right will adjust your light or highlights) to find a good balance; I generally go by feel and keep adjusting until I am satisfied. The main thing to keep in mind is if you stray too far from the original point the picture will end up looking blown out and lose an immense amount of quality.

Here is Ronaldo after we played with his levels:

You will notice the stronger bits of contrast, and how the lighting seems to make the photo visually warmer and more balanced.

Imperfections on the Body: Whether it’s a blemish or a smudge, or maybe some pen ink; the easiest way to get rid of the imperfections on a photo is by using the healing brush. To access the healing brush look for the Band-Aid icon on the left toolbar or press the letter “J” on the keyboard. The healing brush works by first using the “alt” key to select the area where you would like to sample from, then clicking on the area in which you want to replace. So if you have a freckle that needs to be removed, you would take a sample of the face with a similar skin tone and put it over the freckle. When utilizing the healing brush for blemishes always remember to use a soft small brush, about the size of the blemish and avoid dragging; only click on the area. If you drag you will lose quality of the image and pixels will get mushed up.

Let’s take a look at our very own Ronaldo after his blemishes (very minor and ineffectual) get removed:

As you will notice, I’ve removed some freckles.

Color Alterations: To change the colors of eyes and hair, whiten teeth, and brighten shirts use the hue & saturation tool. To access the hue & saturation tool look at the bottom of the layers menu for the small black and white circle, click on it then look for “hue & saturation”. In order for the the hue & saturation tool to work you will need to create a path first around the area that you wish to change. This path needs to be selected for the hue & saturation tool to work properly. Once you have clicked on the the hue & saturation tool it will do two things, it will create a layer and bring up a new toolbar in which you will be able to play with colors. This may look overwhelming at first, but after a few times you will get the hang of the things.

And here is the final; take a look at this stud (whistles) after he’s been hue & saturated (among some other tricks):

You will notice his teeth are perfectly white, his shirt is dark and his eyes are bluer.

In an effort to not overwhelm you, I will stop there for the day, but please know these are the very, very basics of retouching. There is a never ending list of things I could teach you; if you have any questions please feel free to ask. Also, in later days look for posts with advanced tips and tricks for retouching.

Disclaimer: The higher quality of image you have the easier it will be to retouch. This was taken with a Nikon D200, 17-55mm lens

GD Star Rating
loading...