Posts in jQuery

Tuesday, December 29, 2009

An Open Source Milestone: Spaz webOS 1.0

President Wilson at First Regularly Scheduled Airmail Service Ceremony

I really don’t like to toot my own horn. Well, actually I do, but I’m also embarassed by it, so writing the title for this post was a bit painful. Nevertheless, I do think it’s accurate: Spaz webOS 1.0 is now available in the Palm App Catalog, and that’s a significant milestone for the project, and for open source on webOS.

I first started playing with webOS a year ago, over Christmas break at my day job. In June, Spaz webOS was in the App Catalog at release, and back then I was quite proud of the fact that we’d been able to ship a truly open source, transparent app on the first day of a new platform. And now, a year since I first cobbled together a Hello World in Mojo, Spaz has reached a reasonable level of maturity – at least as mature as something called “Spaz” will ever have.

Originally I was going to call this release v0.6. I am shy of using 1.0 because I am painfully aware of all the flaws in my software, and it certainly never feels “done” or “ready” to me. However, a recent discussion with Keith Casey led me to think more seriously about using the “1.0” designation – Spaz webOS is very much Safe To Use, but a pre-1.0 version might make some potential users to think otherwise.

And potential users are a bit more of a consideration now, because in a couple weeks (probably the week of January 11), Spaz webOS will start charging $2 for App Catalog downloads in the United States. This is something I’ve been planning for a while, but it’s still stepping out a bit, both for me (I’ve never charged for software before) and for open source software in general. To be clear, here’s how it will work:

  1. Spaz webOS will cost $2 to download in App Catalog markets that support payments. Right now the only market that supports payments is the US. It will be free in all other markets.
  2. Spaz will still be completely open source. The full source code will always be available.
  3. I will not stop users from packaging and installing Spaz webOS themselves. In fact, I encourage it! I always need more testers, designers and developers. Hacking, patching, and messing with Spaz are fully endorsed. If you can’t help in one of these ways, consider donating to the SpazCore project.
  4. Revenue made from paid App Catalog downloads will be used to support development and offset equipment and hosting costs. I’ve never made any money from Spaz, and despite some generous donations over the past couple years, I’m still well in the red. I don’t do this for the money (obviously), but lightening the burden and compensating myself and other people who have given their time for Spaz is reasonable, I think.

Another thing that isn’t changing is the principles that guide the Spaz project. I wrote up a statement of purpose a while, back, which I’ll replicate here:

  1. Spaz was built for the sake of building it. It is not a means to an end. However, creating it has had several good consequences.
  2. Spaz demonstrates that making things is good, and sharing how you make them is better.
  3. Spaz is a necessary counter to closed, hidden technologies. Spaz must always be open.
  4. The value of Spaz does not lie in the judgements of others, but in the process of building it, and the enjoyment derived by those who use it.
  5. We welcome anyone who wishes to participate in the Spaz Project with open arms, as long as they understand and respect the purposes of the project.
  6. The Spaz project values clear and open communication between participants.

This is how I think software should be made. If you agree, I hope you’ll consider supporting what we’re doing in a way you see fit. We always need help!

Thank you for making Spaz far more than I could have imagined.

Posted in My Projects, JavaScript, jQuery, Mobile, Spaz, webOS by funkatron on 12/29 at 05:01 PM
(0) CommentsPost a comment

Friday, October 23, 2009

ZendCon 09: PHP, JavaScript, and RIAs, Oh My!

Elephant is good student

No more travels for me until SXSW in March, I believe. I’m far too tired.

Did I say that? I actually knew very well that a week later, I would be traveling to San Jose for ZendCon 09. Foolish me.

I spoke at ZendCon on Building Desktop RIAs with JavaScript and PHP. I’ve given this talk other places, but this time I showed off some fun PHP-powered jQuery within Titanium. Here’s a snippet:

<script type="text/php">        
    /**
     * run the passed function when DOM Ready event runs 
     */
    $jQuery()->ready( function () use (&$jQuery) {
        /**
         * set some CSS properties 
         */
        $jQuery('#phpjQ')->css('display', 'none')
                        ->css('background-color','#333')
                        ->css('padding','10px')
                        ->css('border','2px solid #000');
        /**
         * bind a delegated click event to the passed function 
         */
        $jQuery('#invokePHP')->live('click', function () use (&$jQuery) {
            /**
             * set the text color and reveal 
             */
            $jQuery('#phpjQ')->css('color', 'red')->slideToggle(500);
        } );                
    } );
</script>       

Building Desktop RIAs with JavaScript and PHP

Posted in AIR, JavaScript, jQuery, PHP by funkatron on 10/23 at 09:20 PM
(2) CommentsPost a comment

Friday, October 09, 2009

Codeworks 09 talks

Nametag

Unlike some others, I only participated halfway in CodeWorks 09, doing the east coast leg of Atlanta, Miami, Washington, D.C., and New York City. It was an enjoyable adventure, and I liked being able to try different approaches in my talks and see what worked best.

I was able to record audio with the voice memo app on my iPhone. Getting hour-long recordings off is a bit of an adventure – they refuse to appear in the voice memo playlist in iTunes, so you have to find the files in the MobileSync backups folders and do some renaming work – but they turned out pretty well.

Introduction to CodeIgniter

Building Desktop RIAs with JavaScript and PHP

No more travels for me until SXSW in March, I believe. I’m far too tired.

Posted in AIR, jQuery, PHP by funkatron on 10/09 at 05:48 PM
(1) CommentsPost a comment

Wednesday, April 15, 2009

Searchatron, Titanium, and Funding Open-Source Development

Searchatron 0.7

A few of you may know of a small app I did in AIR a while back called Searchatron. It’s mostly a proof of concept, but does have some usefulness in making it a bit easier to track multiple Twitter search queries. Searchatron uses an MVC-style pattern similar to how the next version of Spaz will be built, and much of Searchatron’s code provided the basis for the SpazCore component library.

As more of you may know, I’m very interested in the new Titanium platform. It’s similar to AIR, but fully open-source, and much more extensible. In order to learn more about Titanium, I tasked myself last week with converting Searchatron from AIR to Titanium. The whole process only took a couple hours. You can download the result from http://get.titaniumapp.com/app/12GKqr3.

What’s interesting is that Appcelerator, the creators of the Titanium platform, are running a contest right now. Two $500 prizes will be awarded for the most downloaded app, and the highest-rated app, respectively. If Searchatron wins either of these prizes, I’m pledging now to use the prize money to support further development of Spaz and the SpazCore project, in the form of cash gifts to our most giving volunteers. It might not be a lot, but it does mean real money is going to people working on open-source development. I hope to continue doing so when feasible and prudent.

If you’re interested in helping, this one is pretty easy: download Searchatron, and if you like it, suggest others do the same. Feel free to point them here if you like. By doing so, you’ll be doing a lot to encourage the continued development Spaz and its related projects.

Posted in AIR, My Projects, jQuery by funkatron on 04/15 at 01:07 PM
(0) CommentsPost a comment

Tuesday, December 23, 2008

PHP Advent 2008 Post: JSON is Everybody’s Friend

Security

Reposting something you wrote is a lot easier than coming up with original content. This article was originally posted as part of the 2008 PHP Advent Calendar

Last year I wrote some kind of feel-good, hippie crap for the PHP Advent Calendar. This year I got a haircut, took a shower, and am ready to tell you about something practical: working with JavaScript Object Notation (JSON) in PHP.

“JSON?!” you cry. “But that’s for JavaScript fruitcakes!” And you’d be right. But JSON, while valid JavaScript code, is actually a very effective serialized data format for exchanging data between applications written in a variety of languages. And as of PHP 5.2, we have native support for JSON encoding and decoding.

But I Love XML!

Who doesn’t? The thing is, for moving data around—not documents, but data—I think JSON is superior to XML. This is mainly because JSON tends to map better to the data models in most programming languages—arrays, objects, etc. JSON is serialized JavaScript, so it’s easy peasy representing these kinds of things. Moving between JSON and your language’s internal data models is usually just a single function call. Smarter people than me can debate the pros and cons of XML and JSON in various scenarios, but for a lot of what I do, JSON does the same thing and requires less work.

Get Your PHP Objects On

In PHP 5.2+, there are two functions that handle JSON: json_encode(), which takes a PHP data structure and returns a JSON string, and json_decode(), which takes a JSON string and converts it into a PHP data structure. Let’s take a look at json_encode() and how it handles converting a PHP object into JSON:

&lt;?php
// make a simple object
$obj->body           = 'another post';
$obj->id             = 21;
$obj->approved       = true;
$obj->favorite_count = 1;
$obj->status         = NULL;

// convert into JSON
$json_obj = json_encode($obj);
echo $json_obj;

This will output the following JSON string:

{"body":"another post","id":21,"approved":true,"favorite_count":1,"status":null}

Now, let’s take that JSON and turn it back into PHP:

// convert back into PHP
$new_obj = json_decode($json_obj);
var_dump($new_obj);

And we’ll have the following PHP object:

object(stdClass)#2 (5) {
  ["body"]=>
  string(12) "another post"
  ["id"]=>
  int(21)
  ["approved"]=>
  bool(true)
  ["favorite_count"]=>
  int(1)
  ["status"]=>
  NULL
}

Notice that the data types are retained in the process. JSON supports strings, numbers, objects, arrays (kinda), booleans and NULL. Things like methods, constants, and non-public properties are dropped in the encoding process, as shown in the example below:

&lt;?php
class Foo {
  const     ERROR_CODE = '404';
  public    $public_ex = 'this is public';
  private   $private_ex = 'this is private!';
  protected $protected_ex = 'this should be protected';

  public function getErrorCode() {
    return self::ERROR_CODE;
  }
}

$foo = new Foo
$foo_json = json_encode($foo
echo $foo_json

This outputs the following JSON:

{"public_ex":"this is public"}

Also note that when you decode JSON into a PHP object, the object type is always stdClass. If we use $foo_json from above…

$foo_new = json_decode($foo_json);
var_dump($foo_new);

…we’ll get back the following object:

object(stdClass)#4 (1) {
 ["public_ex"]=>
 string(14) "this is public"
}

Arrays, Indexed & Associative

Array support in JSON is limited to indexed arrays—those with sequential, numeric keys. Associative arrays are converted into an object with corresponding properties.

&lt;?php
// here's an indexed array. JSON natively handles these
$arr = array('orange', 'yellow', 'green', 122);
$json_arr = json_encode($arr);
echo $json_arr."\n";

That gives us this JSON:

["orange","yellow","green",122]

And we can convert it back into PHP…

$new_arr = json_decode($json_arr);
var_dump($new_arr);

…without losing anything in the process.

array(4) {
  [0]=>
  string(6) "orange"
  [1]=>
  string(6) "yellow"
  [2]=>
  string(5) "green"
  [3]=>
  int(122)
}

With associative arrays, the array is converted to an object. Also note that all associative keys are converted into strings in the process:

// associative PHP arrays are converted into objects
$assoc = array('orange'=>'yellow', 'green'=>122, 9=>122);
$json_assoc = json_encode($assoc);

The encoded JSON will be {"orange":"yellow","green":122,"9":122}. Decoding that gives us this PHP object:

object(stdClass)#5 (3) {
  ["orange"]=>
  string(6) "yellow"
  ["green"]=>
  int(122)
  ["9"]=>
  int(122)
}

You can, however, convert the JSON object back into a PHP associative array by passing TRUE as the second param to json_decode() (thanks Richard Orelup).

Playing Well with Others

That’s all fine and good, but it might help to actually do something useful with all this encodin’ and decodin’. JSON is a really good choice for moving data between client-side JavaScript applications and server-side applications, because JSON is JavaScript code, and maps perfectly onto JavaScript’s data structures.

So, let’s contrive a simple application that passes a “counter” object back and forth between the client and server. The counter object stores information on how often the PHP server application and the JavaScript client application “touch” it. First, we’ll make a PHP script to serve up some JSON code to our JavaScript client. It will look for an action parameter in $_GET, perform the requested action, and serve up some JSON in return.

&lt;?php
if ($_GET['action'] === "getinit") {

  // make the PHP object and add a PHP touch
  $counter->php_touches    = 1;
  $counter->js_touches    = 0;
  send_as_json($counter);

} elseif ($_GET['action'] === "updatedata") {
  // decode JSON
  $counter = json_decode($_POST['counter']);

  // increment php touch counter
  $counter->php_touches++;

  // serve up as JSON
  send_as_json($counter);

} else {
  send_as_json(false);
}


function send_as_json($obj) {

  // convert object to JSON
  $json = json_encode($obj);

  // set appropriate headers
  header('Content-Type: application/json');

  // output JSON string as body
  echo $json;
}

The getinit action will create a $counter object, initialize it with a couple of variables to track “touches” by PHP and JSON, and serve up the object as JSON via the send_as_json() function. The updatedata action will take JSON from the $_POST array, decode it into the $counter object, increment the php_touches property, and serve up the modified object as JSON.

In the send_as_json() function, note the header() call that sets the Content-Type to application/json. Setting the content type correctly is good practice, and will sometimes avoid unexpected security issues.

On the client side, we’ll make a short HTML page with some embedded JavaScript to interact with our PHP service.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title>JSON PHP Example</title>
  <!-- Load the Google JS libs hosting API -->
  <script src="http://www.google.com/jsapi"></script>
  <!-- Load the newest jquery major version 1 from Google -->
  <script type="text/javascript" charset="utf-8">
    google.load("jquery", "1");
  </script>
  <!-- load the JSON2.js parser -->
  <script src="JSON2.js"></script>

  <script type="text/javascript" charset="utf-8">
    var counter;

    function processData(data, textStatus) {
      counter = JSON.parse(data);
      counter.js_touches++;
      $('#js-count').val( parseInt(counter.js_touches));
      $('#php-count').val( parseInt(counter.php_touches));
    }

    // when the DOM is ready, do this stuff
    $(document).ready( function() {
      $.get('jsonphp.php?action=getinit', processData, 'text');
      $('#increment-button').click( function() {
        counter.js_touches = parseInt( $('#js-count').val() );
        counter.php_touches = parseInt( $('#php-count').val() );
        var json = JSON.stringify(counter);
        $.post('jsonphp.php?action=updatedata', { 'counter':json }, processData, 'text');
      });
    });
  </script>

  <style type="text/css" media="screen">
    body, input {
      font-family: Baskerville, Georgia, "Times New Roman", serif;
    }
    table {
      border:1px solid #CCC;
      padding:.2em;
      margin: .2em;
    }
    td.label {
      text-align:right;
      font-weight:bold;
    }
  </style>
</head>
<body>
  <table>
    <tr>
      <td class="label">JavaScript Touches:</td>
      <td><input type="text" id="js-count" value="0" /></td>
    </tr>
    <tr>
      <td class="label">PHP Touches:</td>
      <td><input type="text" id="php-count" value="0" /></td>
    </tr>
  </table>
  <form>
    <input type="button" name="increment" value="Increment!" id="increment-button" />
  </form>
</body>
</html>

Rendered in the browser, the page will look something like this:

Screenshot

Note that we’re using the jQuery library (loaded from the Google JavaScript Libraries API) to handle DOM manipulation and Ajax calls. We’re also using the JSON2.js parser, available at JSON.org, to safely parse and create JSON. The default method for decoding JSON into a JavaScript object or array is eval(), but that leaves us open to all sorts of code injection issues.

Jumping into our JavaScript code, the $().ready() is the most interesting portion. The ready() method called on $(document) takes the anonymous function passed into it, and executes the function as soon as the document is “ready”—that is, when the DOM is completed and can be safely messed with. So, when the DOM is ready, two things will happen:

  • A GET request is made to jsonphp.php?action=getinit, and the results are passed as text to the processData() function

  • An event listener is assigned to the click event for the button with the id of increment-button. This listener will fire a function that:

    1. Grabs the values for the touch counts out of the form fields

    2. Assigns them to the counter object

    3. Encodes the counter object as JSON

    4. POSTs counter to the server

So, each time we click the “Increment!” button, the object is sent from the JavaScript application to the PHP application as JSON. Each side will increment its own counter in the object, and the JavaScript application will display those values to us in the page. If we want, we can even change the values, and the JavaScript application will bind the new values to the object before sending it to the server.

What’s It All Mean, Dave?

Metaphysically, I have no idea. But practically, JSON support in PHP means that our favorite server-side language is an even better glue language— something it’s been good at for a long time. Now, go forth and make the next mega-ajax-crowdsourced-mashup masterpiece.

Posted in JavaScript, jQuery, PHP by funkatron on 12/23 at 04:34 PM
Page 1 of 2 pages  1 2 >