Archive for May, 2010

Class YouTube API

Monday, May 31st, 2010

Package:
Class YouTube API
Summary:
Manage and get information from YouTube videos
Groups:
PHP 5, Video, Web services
Author:
sandip
Description:
This class can be used to manage and get information from YouTube videos.

It can send HTTP requests to the YouTube Web services API to perform several types of operations.

Currently it can create play lists, add or remove videos from a play list, get play lists and their video thumbnails, upload videos, get the uploaded videos and get videos of a subscription.


Tags: ,
Posted in Classes | No Comments »

Dreamhost API

Monday, May 31st, 2010

Package:
Dreamhost API
Summary:
Manage hosting accounts using the Dreamhost API
Groups:
Hosting, PHP 5, Web services
Author:
Tom Carlson
Description:
This class can be use to manage hosting accounts using the Dreamhost API.

It can send HTTP POST, GET and DELETE requests to the Dreamhost API Web server to execute several types of operations to manipulate Dreamhost hosting accounts like: accounts, announcement lists, domains, DNS records, MySQL databases, mail filters, user accounts, processes, applications and services.

The class returns the request response in XML format.


Tags: ,
Posted in Classes | No Comments »

[Free] New Free, Open Source, Royalty-Free Font

Monday, May 31st, 2010

The STIX fonts, a set of free, open source, royalty-free fonts for engineering, mathematical and scientific documents, has been added to the Free Fonts page. Besides the usual characters found in most fonts, these additionally contain the symbols needed in engineering and scientific documents but are not usually found in the standard fonts. Incidentally, if you don't need a font with such an extensive support for scientific symbols, there are also numerous other free fonts found on that page, including fancy ones (eg, if you want something to adorn your images on your website).

Tags:
Posted in Uncategorized | No Comments »

Your First WordPress Plugin: Simple Optimization

Monday, May 31st, 2010


WordPress is the largest blogging platform available on the internet today; and with the official release of version three just around the corner, it’s only going to get bigger. As such, over the next few self-contained tuts, we’re going to learn the ins and outs of WordPress plugin development, starting with the creation of our first simple plugin, “Simple Optimization.”


Step 0 Before we Begin

This tutorial is going to assume that you have at least a beginner’s understanding of PHP and the WordPress syntax. Though we’ll be covering everything, some knowledge beforehand will help you grasp the concepts much more easily. I’ll also assumes that you have a WP blog setup and ready to go.


Step 1. What our Plugin Does

The very first step, when writing a WP plugin, is to determine everything you want it to do. Since this is our first plugin, we won’t do anything too drastic. Let’s create something which will speed up our blog; our pages will render faster, and we’ll also do a little SEO to improve our search rank and findability.

“Always create a list of what you want your plugin to actually do before you write any code!”

Remove useless meta tags:

Remove unnecessary filters:

SEO:


Step 2. Laying the Groundwork

To start, navigate to your plugins folder (“/wp-content/plugins/”), and create a new folder. We’ll call ours “simple-optimization.” Next, inside of this folder we’re going to need to create two files. The first will be the actual plugin file (named “main.php”), and the second will be the mandatory README (“readme.txt”). We’re going to leave readme.txt empty for the time being; so open main.php in your preferred text-editor and copy in the code below.

    <?php
/*
Plugin Name: Name Of The Plugin
Plugin URI: http://URI_Of_Page_Describing_Plugin_and_Updates
Description: A brief description of the Plugin.
Version: The Plugin's Version Number, e.g.: 1.0
Author: Name Of The Plugin Author
Author URI: http://URI_Of_The_Plugin_Author
License: A "Slug" license name e.g. GPL2
.
Any other notes about the plugin go here
.
*/
?>

This text is the bare-bones minimum needed for a plugin to appear in the WordPress plugin directory. You’ll obviously need to fill each part as you see fit.


Step 3. Adding Features

The first two features we’re going to implement will also be the simplest. By default, WordPress adds several meta-tags to the <head> section of your blog, but the simple fact of the matter is that these meta-tags have absolutely no value at all; so we’re simply going to stop WordPress from adding them. Anytime WordPress performs an action, it’s either called a filter or an action, and we can either remove or manipulate these filters and actions (you can find a list of all the filters here, and all the actions here). In this case, we want to remove the various actions that add those meta-tags.

To do so, we use a very simple function called “remove_action(‘action’,'function’)”. This function will remove the function declared in the second parameter from the action, the first parameter.

// Clean up wp_head
// Remove Really simple discovery link
remove_action('wp_head', 'rsd_link');
// Remove Windows Live Writer link
remove_action('wp_head', 'wlwmanifest_link');
// Remove the version number
remove_action('wp_head', 'wp_generator');

The same exact same principle applies to the two filters we’re going to remove:

// Remove curly quotes
remove_filter('the_content', 'wptexturize');
remove_filter('comment_text', 'wptexturize');

// Allow HTML in user profiles
remove_filter('pre_user_description', 'wp_filter_kses');

Step 4. SEO

Now that we’ve cut out that bloat, let’s ensure our blog has some basic SEO; meaning, let’s make sure we have keywords per-page, which correspond to that page and change the description to match more with the article. For our keywords, we’re going to grab the tags of the current page/post. This is made super simple by the function “wp_get_post_tags()”. wp_get_post_tags will return an array of tags from the current post. We can then easily format this array into a string and place it within our header (inside the function “wp_head()”, that every theme should have in it already) by attaching our function to the wp_head action.

Let’s start out by creating a new function, tags_to_keywords(), and, inside of this function, we’ll write a simple if statement, which checks to see if the current page is a single post or page (using the WP functions: is_single() and is_page()). Next, we’ll create a variable inside this if statement, named $tags, and set its content to the function wp_get_post_tags(); however, in order for this function to work, we need to pass in a parameter of “post_id”. The easiest way for us to obtain that is to globalize the WP variable $post which contains the post ID ($post->ID, $post is an object which is why we’re calling its values like so).

// SEO
// add tags as keywords
function tags_to_keywords(){
    global $post;
    if(is_single() || is_page()){
        $tags = wp_get_post_tags($post->ID);
    }
}

Next, we’ll use a foreach to filter through the $tags data, and create a new array with only the information we want ($tag_array). Following that, we’ll implode the array into a string and separate each item from the array with a comma and space ($tag_string). Then, we’ll create another if statement that checks to see if $tag_string has a value (meaning, do we have any tags for the post) and if it does, echo out the final HTML.

function tags_to_keywords(){
    global $post;
    if(is_single() || is_page()){
        $tags = wp_get_post_tags($post->ID);
        foreach($tags as $tag){
            $tag_array[] = $tag->name;
        }
        $tag_string = implode(', ',$tag_array);
        if($tag_string !== ''){
            echo "<meta name='keywords' content='".$tag_string."' />\r\n";
        }
    }
}

The last thing we need to do now is attach our new function with the wp_head action. To do this, we’re going to call add_action(‘action’,'function’), and pass it the parameters “wp_head” and “tags_to_keywords” (in that order).

add_action('wp_head','tags_to_keywords');

To further increase our SEO, we’re going to add our description meta-data to the header as well, using the same method as the keywords. Once we have the if statement rewritten, we’re going to create a new variable $all_post_content and fill it using the WP function wp_get_single_post() (and pass the parameter of $post->ID). This will give us an object full of all the data about our post. With this variable, we can create a description using the actual content of the post, but we’re going to shorten it down to one hundred characters using the function substr ($excerpt). And then, we’ll just echo out the HTML with the excerpt written in. (Optionally, you can also add an else statement, and echo your blog description using the function get_bloginfo(‘description’).)

// add except as description
function excerpt_to_description(){
    global $post;
    if(is_single() || is_page()){
        $all_post_content = wp_get_single_post($post->ID);
        $excerpt = substr($all_post_content->post_content, 0, 100).' [...]';
        echo "<meta name='description' content='".$excerpt."' />\r\n";
    }
    else{
        echo "<meta name='description' content='".get_bloginfo('description')."' />\r\n";
    }
}
add_action('wp_head','excerpt_to_description');

Step 5. Optimizing the Database

The final feature for our plugin is going to optimize our database tables by removing overhead (useless/excess data in a SQL table created by manipulating the database). To begin, we’ll create a new function (optimize_database), and inside of it, we’re going to call the global WPDB variable ($wpdb). That way, we can interact with the database, without having to re-enter our authentication details. $wpdb has several methods you can use to interact with and retrieve information from the database (Full list here), but we’re only going to be using one, get_results. Using get_results with the parameters of “SHOW TABLES” and “ARRAY_A” will return to us an associative array of all the table names in the database. At that point, we can use a foreach to loop through each of the array values (using array_values to get the table name, because of how it’s layered by the function) and use another $wpdb method, query to run the optimize command (“OPTIMIZE TABLE _____”).

//Optimize Database
function optimize_database(){
    global $wpdb;
    $all_tables = $wpdb->get_results('SHOW TABLES',ARRAY_A);
    foreach ($all_tables as $tables){
        $table = array_values($tables);
        $wpdb->query("OPTIMIZE TABLE ".$table[0]);
    }
}

While this function works, it will never actually run because WordPress has no way to know to run it. Luckily, WordPress has a feature called cron, which schedules functions to run at specific intervals (daily, weekly, etc…); this is perfect for us, since we want to frequently optimize our database. To use Cron, we’re going to create a new function (simple_optimization_cron_on), and fill it with another function call to wp_schedule_event(). To work, wp_schedule_event needs three things: a time to run, an interval between each run, and a function to call; so we’ll pass it the parameters: ‘time()’ (we’ll assume that whenever the cron event is created is a good time to call the function), ‘daily’, ‘optimize_database’ in that order.

function simple_optimization_cron_on(){
    wp_schedule_event(time(), 'daily', 'optimize_database');
}

Great, now we have our optimize_database function being added to the WP cron list, or we would if we were to call the simple_optimization_cron_on function. It’s really unsafe and is a bad practice to call your own event addition functions, because through some arbitrary system of events, it could cause the function to be called multiple times. WordPress happens to have a set of specific hooks for plugins to solve this problem: register_activation_hook and register_deactivation_hook. These functions are called when a plugin is turned on (activated) and turned off (deactivated). This way, our cron function can only be added once. Now, we have the ability to remove the cron event if the plugin stops being used. To work, these functions need two pieces of information: the url to the file that has the activation and deactivation functions (99% of the time “__FILE__” will work perfectly here), and the name of the activation and deactivation function. We’ll also create a new function (simple_optimization_cron_off), and fill it with a call to another function (wp_clear_scheduled_hook(‘optimize_database’)) to delete our cron event.

function simple_optimization_cron_off(){
    wp_clear_scheduled_hook('optimize_database');
}
register_activation_hook(__FILE__,'simple_optimization_cron_on');
register_deactivation_hook(__FILE__,'simple_optimization_cron_off');

Step 6. Filling out the ReadMe

The last thing we need to do for our new plugin is fill in the readme.txt file. The readme.txt file is used by the WordPress Plugin directory to display all the information you provide it about your plugin. The best way to learn how to write an effective readme.txt file is to download the default from WP, and alter it accordingly to fit your plugin. Since ours was so simplistic, this is what I personally ended up with:

=== Simple Optimization ===
Contributors: Jonathan Wolfe
Plugin link: http://net.tutsplus.com/
Tags: simple, optimization, keywords, tags, description, SEO, optimize, database
Requires at least: 2.5.1
Tested up to: 2.9.2
Stable tag: trunk

Silently adds several optimizing functions to the WordPress back-end to make your blog or site run faster.

== Description ==

Simple Optimization adds several functions to WordPress that help trim the fat from the system and also clean up after itself a little bit all leading to a faster loading time for your blog or website.

**Features**
_Remove useless meta tags:_
* "rsd_link" - Really Simple Discovery Link
* "wlwmanifest_link" - Windows Live Writer link
* "wp_generator" - WordPress version number
_Remove useless filters:_
* "wptexturize" - currly quotes
* "wp_filter_kses" - HTML in user profiles
_SEO:_
* Insert post tags into <head> as keywords
_Routinely optimize the database_


== Installation ==

1. Download, unzip and upload to your WordPress plugins directory
2. activate the plugin within you WordPress Administration

That’s it!

You just successfully wrote your first WordPress plugin, which is working and ready for the WP Plugins Directory. Along the way, you learned about filters and actions, using WP global objects, a lot about the WordPress nomencalture, how to interact with the database, cron events, and activation/deactivation hooks. If you have any questions, please leave a comment and I’ll respond as soon as I can.

The final code:

<?php
/*
Plugin Name: Simple Optimization
Plugin URI: http://net.tutsplus.com
Description: A super-simple plugin to improve your blog
Version: 1.0
Author: Jonathan Wolfe
Author URI: http://fire-studios.com
License: GPL2
.
This plugin written for NETTUTS at http://net.tutsplus.com
.
*/

// Clean up wp_head
// Remove Really simple discovery link
remove_action('wp_head', 'rsd_link');
// Remove Windows Live Writer link
remove_action('wp_head', 'wlwmanifest_link');
// Remove the version number
remove_action('wp_head', 'wp_generator');

// Remove curly quotes
remove_filter('the_content', 'wptexturize');
remove_filter('comment_text', 'wptexturize');

// Allow HTML in user profiles
remove_filter('pre_user_description', 'wp_filter_kses');

// SEO
// add tags as keywords
function tags_to_keywords(){
    global $post; // Get access to the $post object
    if(is_single() || is_page()){ // only run on posts or pages
        $tags = wp_get_post_tags($post->ID); // get post tags
        foreach($tags as $tag){ // loop through each tag
            $tag_array[] = $tag->name; // create new array with only tag names
        }
        $tag_string = implode(', ',$tag_array); // convert array into comma seperated string
        if($tag_string !== ''){ // it we have tags
            echo "<meta name='keywords' content='".$tag_string."' />\r\n"; // add meta tag to <head>
        }
    }
}
add_action('wp_head','tags_to_keywords'); // Add tags_to_keywords to wp_head function
// add except as description
function excerpt_to_description(){
    global $post; // get access to the $post object
    if(is_single() || is_page()){ // only run on posts or pages
        $all_post_content = wp_get_single_post($post->ID); // get all content from the post/page
        $excerpt = substr($all_post_content->post_content, 0, 100).' [...]'; // get first 100 characters and append "[...]" to the end
        echo "<meta name='description' content='".$excerpt."' />\r\n"; // add meta tag to <head>
    }
    else{ // only run if not a post or page
        echo "<meta name='description' content='".get_bloginfo('description')."' />\r\n"; // add meta tag to <head>
    }
}
add_action('wp_head','excerpt_to_description'); // add excerpt_to_description to wp_head function

//Optimize Database
function optimize_database(){
    global $wpdb; // get access to $wpdb object
    $all_tables = $wpdb->get_results('SHOW TABLES',ARRAY_A); // get all table names
    foreach ($all_tables as $tables){ // loop through every table name
        $table = array_values($tables); // get table name out of array
        $wpdb->query("OPTIMIZE TABLE ".$table[0]); // run the optimize SQL command on the table
    }
}
function simple_optimization_cron_on(){
    wp_schedule_event(time(), 'daily', 'optimize_database'); // rdd optimize_database to wp cron events
}
function simple_optimization_cron_off(){
    wp_clear_scheduled_hook('optimize_database'); // remove optimize_database from wp cron events
}
register_activation_hook(__FILE__,'simple_optimization_cron_on'); // run simple_optimization_cron_on at plugin activation
register_deactivation_hook(__FILE__,'simple_optimization_cron_off'); // run simple_optimization_cron_off at plugin deactivation
?>

Tags: , , ,
Posted in PHP Tutorials | No Comments »

HTML5 Globals and You

Monday, May 31st, 2010


Much has been written on the big ticket changes in HTML5, like forms, semantics, and media, but information on the less splashy changes is sparse. While global attributes aren’t the most sexy change of HTML5, they are the change that you will be using over and over and over as you migrate to the new specification.


Introduction: What is a Global Attribute?

While the term attribute relating to HTML might be a bit fuzzy to you, you certainly use them with almost every element that you write. HTML attributes give elements meaning. They also give context. They are both the adjective and verb for an element, if you think of the element as the noun. For instance:

    <div></div>

Doesn’t really have much meaning. It’s a division of the page, and that’s it. When we add an attribute though, it does have meaning:

    <div id="foo" class="bar" style="color: red" title="FooBar To The Rescue"  dir="rtl" lang="en-US" tabindex="1" accesskey="F"></div>

We now have a division that is “Foo” with a class of “Bar”, which has a color of red, a title of “FooBar to the Rescue”, is displayed right to left, is to be read in US English, and when you press the tab button or “F”, it’s the first element to have focus. It’s basic, I know. The attributes are all those things that give elements meaning. The difference in HTML 5 from previous versions of the specification is there are attributes that can be used on any HTML element. These are now global attributes. Beyond the ones illustrated in the example above, there are some new ones that are global as well which will expand the possibilities beyond just boring peanut butter.

“HTML attributes give elements meaning. They also give context. They are both the adjective and verb for an element, if you think of the element as the noun.”


Common Attributes: Which Ones Are Now Global?

This is a relatively minor change in HTML 5. The attributes id, class, style, title, dir, lang, accesskey and tabindex are now valid attributes to have on any HTML element. You want to give a meta tag an id, that’s valid now. It’s even valid to give that same meta element a direction, language, class or any global attribute for that matter. While they might not have meaning at first blush, it’s perfectly valid to define them in any tag that you feel necessary.

    <meta name="description" content="FooBar, making me feel like it is actually FUBAR." id="foo" class="bar" style="color: red" title="FooBar To The Rescue"  dir="rtl" lang="en-US" tabindex="1" accesskey="F">

The above example is perfectly valid in HTML5. That said, where there is no reason to use an attribute, and it looks silly, perhaps the best course of action is to not use that global attribute. A tabindex on a head element might not be the best use of time and energy. The important part to understand is not the odd case of putting a global attribute in something that doesn’t quite make sense, but rather the fact that they are available in any element.

Each of these was common attributes in the past, and while their use were restricted somewhat in the past, you probably already thought of them as global. I actually had to look up id, because I couldn’t think of an element that you couldn’t use it (base, head, html, meta, script, style, title). The old common attributes are just half of the new global attributes though.


Edit Inline: The Contenteditable and Spellcheck Attributes

The first of the new attributes to look at are contenteditable and spellcheck. They are not mutually exclusive and you can use one without the other, but for the purposes of illustration, it makes sense to look at them at the same time. Both of these attributes do what their names imply; they allow an element to be editable (contenteditable) or allows / disallows spellcheck on content. Let’s start with contenteditable:

Let’s look at number handling first:

    <article id="id">
        <p>You can not edit this paragraph.  I am happy, and and just sit here with no regrets.</p>
        <p contenteditable="true">This paragraph you can edit.</p>
    </article>

In this snippet, we have one paragraph which is not editable, and one that is. When you click on the non-editable paragraph, it works as you would expect by highlighting a word, etc:

However, when you click in the editable portion a whole new world opens:

The paragraph now becomes editable simply by adding the contenteditable attribute. It gets even cooler when we start using the contenteditable with multiple elements. Let’s look at a larger snippet and see what happens.

    <article id="edit_test"  contenteditable="true">
        <header>
            <hgroup>
                <h1>Let's See What Happens</h1>
                <h3>Does every element become editable?</h3>
            </hgroup>
        </header>
        <p>You can edit this paragraph now.</p>
        <p>You can edit this paragraph as well.</p>
    </article>

We start with something that looks like this:

When we focus the article element though, we have the entire span editable:

Furthermore, we can style the box (for lack of better term) using the CSS3 pseudo class of :focus

    #edit_test:focus { background: #eee; padding: 1%; }

and it will look something like this:

>

Final notes about contenteditable: there are three basic conditions that it takes: true, false, inherit. You can nest contenteditable conditions with nested tags. For instance, if we do something like:

    <article id="edit_test"  contenteditable="true">
        <header>
            <hgroup contenteditable="false">
                <h1>Let's See What Happens</h1>
                <h3>Does every element become editable?</h3>
            </hgroup>
        </header>
        <p>You can edit this paragraph now.</p>
        <p>You can edit this paragraph as well.</p>
    </article>

We would be able to edit the paragraphs in the article, but not the header group. Since this is a global attribute, you could theoretically add contenteditable to your body element, and then pick and chose the elements which are not editable in the document.

The spellcheck attribute goes along with the contenteditable, but it also can be used where your user might interact with your document, for instance, with forms. The spellcheck attribute is assumed on, unless you say otherwise:

    <article id="edit_test">
        <header>
            <hgroup>
                <h1>Let's See What Happens</h1>
                <h3>Does spellcheck work?</h3>
            </hgroup>
        </header>
        <p spellcheck="false" contenteditable="true">Spell check off.</p>
        <p spellcheck="true" contenteditable="true">Spell check is on.</p>
    </article>

As you can see, when we have the spellcheck set to false, we do not get an indication of a misspelled word, but with it set to true, we do. It’s a very simple, but helpful functionality. From my tests, browser implementation is a bit raw, but it does work now.


Adding Behavior: The Hidden Attribute

Another new global attribute is hidden. It basically does the same job as “display: hidden” does with CSS, but within an element. The advantage to this, it gives a semantical meaning to the element that it is not relevant at this moment in time. Therefore, screen readers, etc., would not mention the element in the hidden state when it would with a style of “display: hidden,” since that is dealing with its presentation. It is a boolean attribute, therefore, false is the assumed state and you only need to add the attribute name to the element that you wish to hide.

    <article id="hide_test">
        <header>
            <hgroup>
                <h1>Let's See What Happens</h1>
                <h3>Can we hide elements?</h3>
            </hgroup>
        </header>
        <p>We can see this paragraph</p>
        <p hidden>We can't see this paragraph</p>
    </article>

Dragging Elements: The Draggable Attribute

HTML5 implements a new “Drag and Drop” API. While the specifics of the API are a bit out of the scope of this tutorial, the attribute to allow something to be dragged is not. Any element that has draggable set to true, can be dragged:

    <article id="drag_test">
        <header>
            <hgroup>
                <h1>Let's See What Happens</h1>
                <h3>Can we drag elements?</h3>
            </hgroup>
        </header>
        <p draggable="true">We can drag this paragraph.</p>
        <p draggable="false">We can't drag this paragraph</p>
    </article>

Without any JavaScript, you can see the difference in browsers that support draggable. When set to false, if you mousedown over the element it will begin to highlight the text; however, when set to true it does not. In Chrome you get the drag icon, whereas in Firefox you just don’t get the highlight of the element. Either way, the browsers are trying to do something with these elements.


Saving Space With Menus: The contextmenu Attribute

The contextmenu attribute allows you to display a menu without taking up valuable UI space for the menu. It is a menu which fires on events, such as mouseup or keyup providing a bubble menu which provides options and actions based on those selections.

    <article id="contextmenu_test">
        <header>
            <hgroup>
                <h1>Let's See What Happens</h1>
                <h3>Can we give a context menu?</h3>
            </hgroup>
        </header>
        <p contextmenu="foo">This paragraph has a context menu called "foo" attached.</p>
    </article>
    <menu id="foo">
        <command label="Step 1: Write Tutorial" onclick="doSomething();">
        <command label="Step 2: Edit Tutorial" onclick="doSomethingElse();">
        <command label="Step 3: ..." onclick="youGetTheDrift();">
    </menu>

In this example, there are a few more things going on with contextmenu that are new. For instance, a menu must be defined, so that the contextmenu knows where to point. In the example above, we are saying, when there is a mouse event (depending on browser implementation), go out and find the menu “foo” in the DOM, and display its commands. The syntax is relatively simple after that. We have a menu label which will display the attribute text, and we have an onclick event which will do whatever we have defined.


The Catch-All: The data-* Attribute

When you add ambiguity to a specification, it tends to be misused, when there are better options available.

I have saved the most controversial global attribute for last. I have mixed feelings with this new one. On one hand, I am looking forward to the ability to connect my logic layer with my behavior layer without going through too many hoops, or using attributes and elements outside of their design specs. On the other hand, I know that when you add ambiguity to a specification, it tends to be overused and misused when there are better options available.

What this attribute is, is a catch-all. Basically, the specification is stating that we can not ever think of all of the use-cases for attributes, therefore we will leave you to your own to make them up. The logic in me feels a specification should give us a set of rules to play with, and leave it at that, but the innovator in me loves having the power to define new attributes. I just know from experience when there is a chance to do something not quite right, but easier, that path generally bites you in the behind. All that said, let’s keep it positive and look at a couple of possible cases.

I think this attribute will be a wonderful addition for microformats, and might be the thing that puts them in the forefront of development. I can also see some uses where on the backend, I want to provide some bread crumbs to my behaivor layer in JavaScript to close some gaps. Another idea where you might use this attribute is to provide a location for where you are when you post an article. That might look something like this:

    <article id="data_test" data-latitude="38.254" data-longitude="85.72">
        <header>
            <hgroup>
                <h1>Post From Louisville, KY</h1>
                <h3>Waterfront Park Concert</h3>
            </hgroup>
        </header>
        <p>I've just attached a post from Waterfront Park in Louisville, KY.</p>
    </article>

I can now take those data-* attributes and do something via JavaScript or another API, such as post a map, from attributes from my application layer. It ends up opening a ton of possibilities, but don’t forget the immortal words of Ben Parker: “With great power, comes great responsibility.”


Conclusion

Like most things in HTML5 at the moment, the browser support for these changes are spotty at best. Some new attributes are supported. some are incorrectly implemented, some have no support at all at the moment! That said, they all appear to degrade nicely without much hoopla involved, so there isn’t a compelling case to not begin experimenting and implementing. The specification changes are slowing, so more than likely, what you see is what you will get…at some point. Thanks for reading!

Tags: , , ,
Posted in PHP Tutorials | No Comments »

Singapore NRIC

Sunday, May 30th, 2010

Package:
Singapore NRIC
Summary:
Verify the validity of a Singapore identity number
Groups:
Singapore, Validation
Author:
Gary Tay
Description:
This class can be used to verify the validity of a Singapore identity number.

It parses a given Singapore National Registration Card Identity number (NRIC) and determines the verification digit to check whether the number is valid.


Tags: ,
Posted in Classes | No Comments »

Easy ODS Read

Sunday, May 30th, 2010

Package:
Easy ODS Read
Summary:
Retrieve data from OpenOffice spreadsheet files
Groups:
Files and Folders, PHP 5
Author:
Ovidiu Mihalas
Description:
This class can be used to retrieve data from OpenOffice spreadsheet files.

It can open a given file in the ODS format, extract its contents and parse the spreadsheet data.

The class can extract a given range of spreadsheet rows into an array.


Tags: ,
Posted in Classes | No Comments »

Eazy ODS Read

Sunday, May 30th, 2010

Package:
Eazy ODS Read
Summary:
Retrieve data from OpenOffice spreadsheet files
Groups:
Files and Folders, PHP 5
Author:
Ovidiu Mihalas
Description:
This class can be used to retrieve data from OpenOffice spreadsheet files.

It can open a given file in the ODS format, extract its contents and parse the spreadsheet data.

The class can extract a given range of spreadsheet rows into an array.


Tags: ,
Posted in Classes | No Comments »

Esteem Radio

Sunday, May 30th, 2010

Youth Radio Station in Milton Keynes, Buckinghamshire

Tags:
Posted in Free PHP Scripts | No Comments »

PHP 5 IMAP Class

Saturday, May 29th, 2010

Package:
PHP 5 IMAP Class
Summary:
Retrieve messages from an IMAP server
Groups:
Email
Author:
Chris Nizz
Description:
This class can be used to retrieve messages from an IMAP server.

It uses the PHP IMAP extension to access to a given IMAP server and can execute several operations to retrieve different parts of the available messages.

Currently it can retrieve information of the mail box, retrieve message headers, retrieve the message data and attachments.


Tags: ,
Posted in Classes | No Comments »