Miles Per Hour

programming at the speed of 1011000.

Dec

5

Reading Backbone.js POST variables from PHP

By mike@mike-miles.com

For a recent project, I had to read POST variables sent from Backbone.js to PHP. Now is turns out Backbone.js does not simply send normal POST variables (retrievable from $_POST). Instead it sends a json object of the variables.

So simply querying the global $_POST object for the variables you are looking for will not work, PHP will say that the $_POST is empty.Enter “php://input” .

“php://input” is the input stream that allows you to read raw data from the request bod. Basically you can read in the raw POST data this way. so for example if you called file_get_contents(“php://input”); it would return the POST data.

Now as I said before, Backbone.js sends the POST data as a json object. So reading in the contents of the php://input will get your the values that are posted. Let’s look at an example.

Let’s say that Backbone.js was sending us the following variables:
category_id: 1
sub_catagory_id: 34
title: “my saved data”

Say Backbone.js was sending the following through POST

{"catagory_id":1,"sub_catagory_id":34,"title":"my saved data"}

Notice, Backbone.js sends only a json string, not variable name to access. the POST is the string. so trying to view the $_POST with say a print_r would return false. But using “php://input” with file_get_contents, we can get the raw POST data and place it into a variable.

<?php
  $post_data = file_get_contents("php://input");
?>

and $post_data would then be a json string

<?php
  echo $post_data; //{"catagory_id":1,"sub_catagory_id":34,"title":"my saved data"}
?>

And now you can simply use json_decode($post_data) to retrieve a the json object of values. (passing a second argument returns an associative array instead of an object.)

<?php
  $post_data = file_get_contents("php://input");
  $post_data = json_decode($post_data,true);
/* $post_data returns the following
  array(
   "catagory_id":1,
   "sub_category_id":34,
   "title":"my saved data",
  );
*/

But wait, that may solve our problem if we know for sure that “php://input” contains data from Backbone.js (a json string). But what if it doesnt? wouldn’t it make sense to cover our bases. How about writing a function that can return the POST data no matter what?  Well then a function like the following might suffice.

<?php
function get_post_data(){
	if ($input = file_get_contents("php://input")){
		//test for json
		if ($json_post = json_decode($input,true)){
			return $json_post;
		}else{
			parse_str($input,$variables);
			return $variables;
		}
	}
	return false;
}
?>

One additional function to note I am using is “parse_str“. parse_str parses a string as if it were the query string passed via a URL and sets variables in the current scope. Passing the second argument sets the parsed data into a variable. So with this function, if the POST data is a json string, it gets parsed into an associate array, and if it is normal POST data, it gets parsed into an associative array. A win win for all cases.

Oct

19

Drupal like templating for your wordpress plugin

By mike@mike-miles.com

As part of my job, from time to time I am responsible for building custom WordPress plugins for client sites. One of the biggest pains of building a plugin (besides the miss-mash of resources/tutorials on how to build one) is theming the output. Weather it be output to the front end user, or an admin screen or a form, I have never been able to find a great way to separate back end code and front end code (not having HTML within the plugin itself). That is until the idea came to me to mimic the method Drupal uses to template output (I do a lot more Drupal development, than I do wordpress). On the latest wordpress plugin I had to develop, I decided to implement my idea and it worked quite well. so I thought I’d share the methods used so that any other wordpress plugin developer out there might use it.

A quick basic overview of how Drupal templates content for any of you who maybe unfamiliar. When a Drupal module (module is to Drupal, what plugin is to WordPress) want to output content it calls a theming function, an example:

<?php
//... other module code
return theme('my-template-file',$arg1,$arg2);
?>

So basically, you call a function ( called ‘theme’) and pass it the name of the template file you want to use along with the arguments to pass to that template. (This is a very basic overview of how the Drupal theme function works).

What Drupal then does is start an output buffer, render the content of the template (passing the arguments as variables in the local scope) captures the output, clears the output buffer and return the rendered content. here is the function that does it (from ‘theme.inc’ in the Drupal directory ‘includes’).

<?php
function theme_render_template($template_file, $variables) {
	extract($variables, EXTR_SKIP);  // Extract the variables to a local namespace
	ob_start();                      // Start output buffering
	include "./$template_file";      // Include the template file
	$contents = ob_get_contents();   // Get the contents of the buffer
	ob_end_clean();                  // End buffering and discard
	return $contents;                // Return the contents
}
?>

So we want to replicate this function in our WordPress plugin, all be it with a few additions. First, we’ll need to be able to get the location of our plugin, and thus the full location of the template file (Drupal does something similar with themes and modules in other functions to get the full $template_file path). Second, we’ll want to extend the functionality of this to allow multiple templates to be used. This is again, modeled after Drupal. What the Drupal theme engine allows you to do is have different versions of a template file. For instance, there will be a basic one with the module, but any theme can also have the same template file which will be used instead (This allows Drupal sites to customize output without needing to alter the modules core code).

So our WordPress plugin function will look something like this:

<?php
//... other module code
function myplugin_theme($template,$variables){
        //empty content to start
	$contents = '';
	//no template path to start
	$template_file = false;
	//get the path or the current active theme
	$theme_path = get_stylesheet_directory();
	//get the path to our plugin template directory
	$plugin_path = dirname(__FILE__).'/templates/';
	//assume the template name we are given does not have the extension
	$template.='.tpl.php';
	//see which template file we want to use
	//doe the theme have the template file?
	if (file_exists($theme_path.'/'.$template)){
		//it does, so use this as the path
		$template_file = $theme_path.'/'.$template;
		//does the plugin have the template file?
	}else if (file_exists($plugin_path.$template)){
		//it does, use that instead
		$template_file = $plugin_path.$template;
	} // else, there is no template file found.
	//do we have a template file to output?
	if ($template_file){
		extract($variables, EXTR_SKIP);  // Extract the variables to a local namespace
		ob_start();                      // Start output buffering
		include "./$template_file";      // Include the template file
		$contents = ob_get_contents();   // Get the contents of the buffer
		ob_end_clean();                  // End buffering and discard
	}
	return $contents;                // Return the contents
}
?>

A quick break down of our function and how it work. The function retrieves the current active theme path, as well as the path to our plugin. It first checks to see if the theme has the template file (indicates the theme creator has specialized the output of this template), else it sees if the plugin has a base template file (as it should). If there is a template file, then the function uses the PHP extract function to move the variables passed into the local namespace. It then does the same thing as the Drupal function, renders the content and returns it. Not that, if the template file is not found our function returns an empty string.

So how might one use this? Well here is an example, say our module displays a list of restaurants near a users location. We don’t know how many results are being returned, but we want to template how the list looks. so we might do something like this:

<?php
function mymodule_display_restaurants(){
	//User submitted their zipcode via a form
	$zipcode = $_POST['zipcode'];
	//we retrieve a list of restaurants near the users zipcode
	$restaurants = mymodule_get_restaurants($zipcode);
	//display restaurants to user
	echo mymodule_theme('restaurant-list',array('restaurants'=>$restaurants));
}
?>

What is happening here is the function ‘mymodule_display_restaurants’ is sending an array of restaurants to the template file ‘restaurant-list.tpl.php’. Here is an example of what that template file might look like:

<div id="restaurant-list">
<?php if (sizeof($restaurants)>0){ ?>
	<p>Here are the restaurants in your area</p>
	<ul>
	<?php foreach ($restaurants as $restaurant){ ?>
		<li><?php echo $restaurant->title; ?> - <?php echo $restaurant->address; ?></li>
	<?php } ?>
	</ul>
<?php }else{ ?>
	<p>It looks like there are no restaurants in your area.</p>
<?php } ?>
</div>

There is still PHP in our template file, but what is most important is that the HTML to display this list is separated from our plugin code. This means that a theme developer could create a custom template for our plugin to display this data differently (say in a table).

This system also allows you to build complex themed output, theming individual parts with separate template files and theming all the output in a template. Example, we might change our previous function to something like this to make it more flexible:

<?php
function mymodule_display_resturants(){
	//User submitted their zipcode via a form
	$zipcode = $_POST['zipcode'];
	//we retrieve a list of resturnats near the usrs zipcode
	$resturants = mymodule_get_resturants($zipcode);
	if (sizeof($resturants)>0){
		foreach ($resturants as &$resturant){
			$resturant = mymodule_theme('resturant',array('resturant'=>$resturant));
		}
	}
	//display resturants to user
	echo mymodule_theme('resturant-list',array('resturants'=>$resturants));
}
?>

The ‘restaurant.tpl.php’, might look something like this:

<div>
        <strong>Name:</strong><?php echo $resturant->title; ?><br />
	<strong>Address:</strong><?php echo $resturant->address; ?><br />
</div>

And our ‘restaurant-list.tpl.php’ will now look something like this:

<div id="restaurant-list">
<?php if (sizeof($restaurants)>0){ ?>
	<p>Here are the restaurants in your area</p>
	<?php
		foreach ($restaurants as $restaurant){
			echo $restaurant;
		}
	?>
<?php }else{ ?>
        <p>It looks like there are no restaurants in your area.</p>
<?php } ?>
</div>

So you can see, this gives themers much more control over the output of your plugins data without needing to alter your plugin.

 

I hope this post proves useful and your able to build upon and use this theming convention to make your plugin development much more flexible.

 

 

 

Mar

2

Drunken Stumble: a breakdown

By mike@mike-miles.com

So my last post, I mostly went through the process of how Drunken Stumble was built and competing in the boston hack day challenge.  So I thought I would follow up with  a more in depth post about Drunken Stumble itself.

Read more »

Mar

1

Drunken Stumble, a Drupal 7 Web App Built in a Weekend

By mike@mike-miles.com

This past weekend I took part in the Boston Hack Day Challenge; a weekend long event where teams of developers, designers and programming geeks formed teams and competed to build the best app in a single weekend. Read more »

Dec

1

Semantics and Readability

By mike@mike-miles.com

When you write code there are two overlying important aspects to remember. First being that your code is semantically correct (else it wont work, duh) and readability. As in the ability for your code to be read and understood by other developers and yourself in the future (you WILL forget how your code works, trust me).

Read more »

Oct

24

Genuine Labs: the Augmented Reality Business card

By mike@mike-miles.com

I’ve said this before, and I’ll say it again, I love my job and where I work (Genuine Interactive).  It’s an enviroment that fosters hard work, creativity and great results.  It’s also a place where the guys in charge have made it clear that everyone can chime in and express their ideas for projects.

A few months ago I did just that.  I was talking to Chris Pape, and I asked him if any of our flash developers had experience with augmented reality.  I told him I had an idea I wanted to try, making an augmented reality business card where our company logo was the symbol.  He thought it was a great idea, and told me it was something he’d love to look into.

Read more »