Archive for December, 2009
Happy New Year!
Thursday, December 31st, 2009
Where I live, it’ll be 2010 in six hours. Wow – 2010! And that means, in five years, we’ll be in flying cars where the postal service isn’t as efficient as the weather. (First person who names that movie reference will be sent a web dev book.)
As the year comes to a close, I want to take a moment to thank all of you so much. While my job is to edit and create tutorials, I can promise that I’ve learned far more from the comments of these postings, and I’m grateful for that. I also would like to go over what I have planned for 2010…
More Design
Especially in the last few months, we’ve managed to focus almost exclusively on development-style tutorials. I can only post what is submitted, and we truthfully haven’t received many articles focused on design. That’ll be changing in 2010 – and I encourage you to submit your ideas to me at nettuts@tutsplus.com.
- Advanced CSS tutorials
- The process of designing a website
- How to build advanced menus
- Combining CSS and JavaScript
- Etc.
If you’re a successful ThemeForest author, or have some amazing design skills, please do contact me about writing tutorials, and even recording a screencast for our site. Please remember that compensation for Plus tutorials can go as high as $600, depending on the quality of the final product.
Broader Topics
Additionally, we’ll be focusing more on Air apps, as well as Ruby/Rails tutorials. If there’s anything that we don’t cover on Nettuts+, be sure to let me know within the comments. I promise to consider it!
Redesign
I can’t say much, but I’m fairly certain that the design of all the Tuts site will receive another evolutionary “remodeling,” so to speak. Going with the great design that we currently have, Collis and Derek will refine the layout further, as well as add some neat new features/categories.
Happy New Year!
So let’s meet back here in the next decade! Allie is giving me the evil eye right now – which means I have to close the computer for the night. Bye!

- Follow us on Twitter, or subscribe to the Nettuts+ RSS Feed for the best web development tutorials on the web. Ready
Write a Plus Tutorial
Did you know that you can earn up to $600 for writing a PLUS tutorial and/or screencast for us? We’re looking for in depth and well-written tutorials on HTML, CSS, PHP, and JavaScript. If you’re of the ability, please contact Jeffrey at nettuts@tutsplus.com.
Please note that actual compensation will be dependent upon the quality of the final tutorial and screencast.

learn, php, rss, tutorials
PHP Tutorials | No Comments »
Create an In-Place Editing System: One Step Further
Thursday, December 31st, 2009
A few months ago, you learned how to create an in-place editing system. Today, we’ll take things a step further as we create a simple backend, which will allow our website to remember the changes that we’ve made.
A Word From the Author
With all the buzz around Web 2.0, ease of use is now much more important than ever. Being able to edit some content without having to go to another page is something a lot of users really crave. A lot of big names are already using this pattern to great effect. If you’ve used Flickr, you’ve probably seen this in action.
Today, we are going to improve on the earlier version: weeding out some bugs, adding some features, and, more importantly, saving all the data to an actual database for retention. Interested? Let’s get started right away!
Prepping the Database
First up, we need a database to pull in the information from and then, when required, update the data it holds. For the sake of this exercise, let us setup a table with some random data.
I already had a database named inplace with a table called data on my development server. For our use we’ll add another table.

I typically prefer using phpMyAdmin for running my SQL queries. Click on the SQL tab and paste in the following query:
CREATE TABLE IF NOT EXISTS `inplace` (
`field` varchar(120) NOT NULL,
`value` text NOT NULL,
PRIMARY KEY (`field`)
) ENGINE=MyISAM;
INSERT INTO `inplace` (`field`, `value`) VALUES
('name', 'am Siddharth'),
('passion', 'love working with the web'),
('profession', 'am a freelancer'),
('work', 'write for Net Tuts'),
('url', 'can be found at www.ssiddharth.com'),
('punch', 'will never let you down or give you up
'),
('design', 'Get design approval from Yusuf'),
('invoice', 'Send an invoice to Drew'),
('research', 'Start research on Pallav\'s project'),
('discuss', 'Speak with Harnish about new ideas'),
('debug', 'Check Aditya\'s site for rendering bugs'),
('meet', 'Meet with Clintson to discuss new project');

If everything worked out as it should you should get the following screen:

A closer look at the table:

Since I explicitly wanted to keep the simplicity of the demo and just add the back end people requested, I am keeping the table structure very simple. Feel free to modify and extend it in your projects.
Now that the sample table has been created and pre populated with some test data, we can move on to the actual back end.
Setting up a Database Config File
Since we’ll be accessing the database often either to read data or to update the data it contains, it’s prudent to create a config file which holds the relevant data. Create a file called db.php and paste the following in it.
<?php
DEFINE ('DB_USER', 'sid');
DEFINE ('DB_PASSWORD', 'somerandompassword');
DEFINE ('DB_HOST', 'localhost');
DEFINE ('DB_NAME', inplace);
$connection = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD) or
die('Connection to the specified database couldn\'t be established');
mysql_select_db(DB_NAME) or
die ('Specified database couldn\'t be selected');
?>
Nothing special here. We define all the relevant details, connect to the host using the given username/password combination and then select the relevant database for manipulation down the road.
The Editor

The editor takes care of reading from the database and outputting the data in a specific format so it is easy for us to send relevant details back to the server informing which record to update. We’ll talk about it more in a second.
The code doesn’t change significantly from the static HTML only code from the earlier version. We do, however, need to make the data dynamic. So in the original HTML code, this:
<li class="editable">am Siddharth</li> <li class="editable">love working with the web</li> <li class="editable">am a freelancer</li> <li class="editable">write for Net Tuts</li> <li class="editable">can be found at <a href="http://www.ssiddharth.com">www.ssiddharth.com</a></li> <li class="editable">will never let you down or give you up</li>
<li class="editable">Get design approval from Deacon</li> <li class="editable">Send an invoice to Albert </li> <li class="editable">Start work on Dwight's project</li> <li class="editable">Talk with Sarah about new ideas</li> <li class="editable">Check Seth's site for rendering bugs</li> <li class="editable">Meet with Clintson to discuss project</li>
is replaced by:
<?php
$query = "SELECT * FROM inplace LIMIT 0, 6";
$result = mysql_query($query) or die ('Query couldn\'t be executed');
while ($row = mysql_fetch_assoc($result)) {
echo '<li class="editable" id="'.$row['field'].'">'.$row['value'].'</li>';
}
?>
<?php
$query = "SELECT * FROM inplace LIMIT 6, 6";
$result = mysql_query($query) or die ('Query couldn\'t be executed');
while ($row = mysql_fetch_assoc($result)) {
echo '<li class="editable" id="'.$row['field'].'">'.$row['value'].'</li>';
}
?>
Since the table is small, we’ll just select everything from the table but ask it to return only the first 6 elements. Next, I just iterate through and print out the li elements. Take special note of the fact that each li elements gets its id attribute set to the name of field it obtains its value from. This will be used later in the data sent back to the server to denote which record needs to be updated.
I am aware exposing the name of the field like this may pose a security threat but on a properly secured environment, I don’t think this will instigate any troubles. Else you could just use aliases here and do a reverse lookup on the server side. Let your creative juices flow there. For a very straight forward demo, it seemed rather overkill.
Also, don’t forget to include the db.php file we created earlier to the editor. This line will take care of that.
<?php require("db.php"); ?>
After making the edits, remember to save the file with a .php extension.
The Handler
The handler is where the page posts the details to. This takes care of checking whether data was actually sent to the page, and if so, sanitizes the sent data and then updates the relevant values.
Create a file named handler.php and paste in the following:
<?php
require("db.php");
if (isset($_POST['field']) && isset($_POST['value'])) {
$value = mysql_real_escape_string($_POST['value']);
$field = mysql_real_escape_string($_POST['field']);
$query = "UPDATE inplace SET value ='$value' WHERE field='$field'";
$result = mysql_query($query) or die ('Query couldn\'t be executed');
if ($result) {echo 1;}
}
?>
A pretty straightforward affair. Let me explain each step in detail.
Since we’ll need to manipulate the database, we first include the db.php file we created earlier.
Next, we check whether both our required variables, field- value which tells us which field to update and value – the value to update to, are sent as POST variables to the handler. If so, we can proceed to the actual work. If not, nothing happens.
Once, we’ve verified that the variables were sent, we can go on sanitizing the data for insertion into the database. To keep it as simple as possible, we’ll use the mysql_real_escape_string function to sanitize our data. This function escapes the special characters present in the passed string. If passed in un sanitized, our code is subject to SQL injection attacks.
Now that we’ve made sure the data is safe, we can update the relevant record. I am assuming this part needs no explanation since it is very simple SQL. In layman’s terms, in the inplace table, change field’s corresponding value to value.
If everything goes on according to plan, return a value of 1 which’ll be captured by our script to determine the outcome of the transaction so it can proceed accordingly. I’ll elaborate more later below. Please do note that in this case, I merely report whether the attempt succeeded or failed. In your project, you may want to return much more detailed info in case any error occurs. You are not limited to my extremely simple implementation.
The JavaScript
Now that the back end has been constructed, it’s time to edit the front end part of the project to let it communicate with the server. We’ll also look at implementing a new feature along the way.
Cleaning up the Old Code
One of the complaints of the old version was data corruption when certain actions were performed in a specific order. This was due to my extreme need for simplicity and conciseness which ultimately led me to overlook that specific scenario. Never the less, we’ll rectify that today.
I’m assuming you have the old JavaScript code nearby to compare with and edit.
Getting Rid of Global Variables
The first version used global variables to hold the original data which led to unexpected results in certain case. We’ll rectify this first.
The easiest way to rectify this would be to just add a hidden input next to the original input and use it as a buffer. Since it is created and destroyed on the fly and is specific to that element alone, we can edit/save/discard as many elements as possible as many time as possible without any hiccups.
The old replaceHTML function gets updated to:
function replaceHTML()
{
var buffer = $(this).html()
.replace(/"/g, """);
$(this).addClass("noPad")
.html("")
.html("<form class=\"editor\">
<input type=\"text\" name=\"value\" class=\"editBox\" value=\"" + buffer + "\" />
<input type=\"hidden\" name=\"buffer\" class=\"buffer\" value=\"" + buffer + "\" />
</form>
<a href=\"#\" class=\"btnSave\">Save changes</a>
<a href=\"#\" class=\"btnDiscard\">Discard changes</a>")
.unbind('dblclick', replaceHTML);
}
Not a big edit here. First we create an internal variable called buffer to hold the original value. We then purge the HTML content of the parent element and inject our own. In addition to the original snippet, we add a hidden text box which retains the original value. Nothing else is changed here.
Creating a Unified Handler
The earlier iteration binded similar but separate functions for each of the functional links. We’ll unify them here.
function handler()
{
var selector;
if ($(this).hasClass("btnSave"))
{
selector = "editBox"
}
else
{
selector = "buffer"
}
$(this).parent()
.html($(this).siblings("form")
.children("."+selector)
.val())
.removeClass("noPad editHover")
.bind("dblclick", replaceHTML);
return false;
}
Instead of using anonymous functions like last time, we are going to use a normal function. We are only going to edit small parts of the function to make it handle both save and discard requests.
We first declare a variable named selector which holds the selector to use whilst updating the li elements. editBox is the class assigned the visible text box and buffer is the class assigned to the hidden text box which holds the original value.
Since we are unifying the event handlers, we need to check which link was clicked. We first see whether the clicked link has a class of btnSave. If so, then the user wants to save the edits and so we assign the value of editBox to the selector variable. If not, buffer is assigned.
The rest of the handler remains the same as the old version except that the selector is injected dynamically based on the action instead of it being hard coded into the function. If you seem lost here, look at the first part of the series to understand what the last block does. Essentially, we inject the selected text box’s value into the parent li element and rebind the original event handler.
Don’t forget to update the event handlers for each link. The following one liner takes care of that:
$(".btnSave, .btnDiscard").live("click", handler);
If you are wondering why I used the live function here, please refer to the earlier article.
Adding AJAX Capabilities
With all the bugs squashed out and the code generally tightened up a little, we can start working on implementing the actual functionality.
Prepping the HTML
Before we can send the data to the server, we need to find a way to send relevant details back to the server. In this case, we need 2 details to make a successful edit.
- The value itself
- The name of the field to be updated
The first part is rather straightforward since we have an actual text box holding the values to be sent to the server. The second part needs a little work.
Whilst creating the editor, remember that we used the primary ID of the table as id attributes to each li element? We are going to make use of it here. We’ll just create another hidden text box which’ll hold the value which can be then posted back to the server.
function replaceHTML()
{
var buffer = $(this).html()
.replace(/"/g, """);
$(this).addClass("noPad")
.html("")
.html("<form class=\"editor\">
<input type=\"text\" name=\"value\" class=\"editBox\" value=\"" + buffer + "\" />
<input type=\"hidden\" name=\"buffer\" class=\"buffer\" value=\"" + buffer + "\" />
<input type=\"hidden\" name=\"field\" class=\"record\" value=\"" + $(this).attr("id") + "\" />
</form>
<a href=\"#\" class=\"btnSave\">Save changes</a>
<a href=\"#\" class=\"btnDiscard\">Discard changes</a>")
.unbind('dblclick', replaceHTML);
}
The replaceHTML function has to be updated like so. The only difference is the addition of hidden text box with the name field. We use jQuery’s attr function to access the li element’s ID attribute and use it as the text box’s value.
The AJAX Implementation
On to the AJAX implementation then. We are going to use jQuery’s standard ajax function here.
function handler()
{
// Previous code
if ($(this).hasClass("btnSave"))
{
var selector = "editBox";
var str = $(this).siblings("form").serialize();
$.ajax({
type: "POST",
async: false,
timeout: 100,
url: "handler.php",
data: str,
success: function(msg){code = msg;}, });
if(code == 1)
{
alert ("Success");
}
else
{
alert ("Failure");
}
}
// Rest of the code
}
Since we only need to send the data to the server when the user has clicked the relevant link, we encapsulate all the code within the if block we created earlier to check which link was clicked.
I make use of the ajax function since I find it to be the most robust. First up, I serialize the data the parent form holds so it can be posted to the server. Next, I call the ajax function setting all relevant details as necessary which includes the type of request to make – POST and the URL to post to. We also specify that the data we serialized earlier should be sent to the server.
Usually, you’d use the inbuilt success and error callbacks to make further changes but I’ve chosen not to do so here. Instead, I am just capturing the text sent back by the server. If it returns 1, a value we configured our handler to return if everything happened correctly, we alert the user to let him know.
Implementing a Status Bar

Alerts are a pretty rudimentary way to update the user with the status of the action. With that in mind, we are going to scrap the alert system and instead implement a simple status bar at the bottom which reflect these changes.
The Markup
We don’t need anything special here. We just need a simple div element which we can manipulate. We are just going to have to add that directly in the editor.
<div id="status"></div>
Make note of the id attribute. We’ll use it later.
The Helper Function
In the interest of code reusability, we’ll create a helper function which updates the status bar as needed.
function UI(state)
{
var status = {};
status.Ready = "Ready";
status.Post = "Saving your data. Please wait...";
status.Success = "Success! Your edits have been saved.";
status.Failure = "Attempts to save data failed. Please retry.";
var background = {};
background.Ready = "#E8F3FF";
background.Post = "#FAD054";
background.Success = "#B6FF6C";
background.Failure = "#FF5353";
$("#status").animate({opacity: 0}, 200, function (){$("#status").html(status[state]).css({background: background[state]}).animate({opacity: 1}, 200)});
}
The function, which we’ve named, UI, takes the state of the status bar as its parameter. Inside the function, we create two objects: status holds the relevant text and background holds the background colors of the status bar.
We could just directly update the status bar’s text and background color but here at Net Tuts, that’s not how we roll. ![]()
We are going to make use of jQuery’s animate function to gracefully animate the status bar. First, we animate its opacity to zero. Next, we update its text and background color and then animate it back to full visibility.
Take special note of the fact that the logic used to update the values are enclosed within an anonymous function and passed as the callback to the original animation. This way the bar will animate to zero opacity and then everything is updated. If the animations are chained, the text and background colors will be updated just after the initial animation starts which leads to a very jarring effect.
Adding it to UI
Adding it to the UI and updating the status bar now is a piece of cake. Instead of the alerts we used earlier, we need to use the UI function.
The earlier block which succeeded the ajax call can now be replaced by:
if(code == 1)
{
UI("Success");
}
else
{
UI("Failure");
}
Also, don’t forget to add UI(“Ready”); when the page loads so the user knows the system is ready for manipulation and UI(“Post”); when the data is being posted to the server.
When you are adding your own states to the task bar, make special note of the fact that the string we send as the parameter to the function maps directly to the property of the object.
Proper Data Persistence
The last thing we need to look at is the fact that if the attempt to save the data failed, the updated text is still retained. This seems rather counter intuitive. If the attempt to save the data fails, we need to make sure the original text is placed back so the user knows the data hasn’t been saved.
In order to rectify this, we’ll need to change the selector variable in case we encounter an error.
if(code == 1)
{
UI("Success");
selector = "editBox";
}
else
{
UI("Failure");
selector = "buffer";
}
If the value was edited successfully, we change the the relevant variable’s value to editBox. But if the attempt ended in failure, we need to swap out the new value with the old value. So we assign buffer to the variable so that value will revert back to its original value.
Conclusion
And there you have it. How to add a user friendly functionality to your projects. Hopefully you’ve found this tutorial interesting and this has been useful to you. Feel free to reuse this code elsewhere in your projects and chime in here if you are running into difficulties.
Please do keep in mind that this system was designed with the primary intention of teaching the techniques associated with this, not as a production system designed to drop in into existing systems. This is more of a foundation that I encourage people to build upon and improve.
Questions? Nice things to say? Criticisms? Hit the comments section and leave me a comment. Happy coding!
- Follow us on Twitter, or subscribe to the Nettuts+ RSS Feed for the best web development tutorials on the web. Ready
Write a Plus Tutorial
Did you know that you can earn up to $600 for writing a PLUS tutorial and/or screencast for us? We’re looking for in depth and well-written tutorials on HTML, CSS, PHP, and JavaScript. If you’re of the ability, please contact Jeffrey at nettuts@tutsplus.com.
Please note that actual compensation will be dependent upon the quality of the final tutorial and screencast.

learn, php, rss, tutorials
PHP Tutorials | No Comments »
Win a Three-month Plus Membership – 12 for 2010, Day Eleven
Thursday, December 31st, 2009
As part of the eleventh day of 12 for 2010, we’re giving away a free 3-month membership to Plus;. Entries are open to everybody – Plus members and non-Plus members alike. Entering only takes a few seconds, since all you’ve got to do is leave a comment. Too easy.
Meet Derek Herman

Derek is the Tuts+ WordPress master and the guy who turns Collis’s designs into a reality. He makes WordPress do things Matt Mullenweg has never even dreamed of. In fact, we’re pretty sure Matt could learn a thing or two from Derek!
Meet Fred Wu

Fred is Envato’s only PHP developer, valiantly holding the fort against the Ruby dev team who consider their development language to be superior. We couldn’t have picked a better representative for the PHP community. In his spare time, Fred indulges in his country-specific domain name addiction while continuing to amass a vast knowledge of anything and everything to do with technology. Whether you want to know which Mac app will help you categorize your taxidermy collection, or which Firefox plug-in you should use to initiate global thermonuclear war in the guise of a computer game, Fred has you covered.
Win a 3-Month Membership to Plus
Joining Plus; gives you access to an exclusive members area chocked-full of our best tutorials, plus hundreds of source files. You get the best teaching on Photoshop and graphic design, motion graphics, vector illustration, web development and audio production and mixing.
For the chance to win the 3-month Plus membership, all you need to do is comment. Make sure to include your correct email address with your comment so that we can contact you. This giveaway is open worldwide, but make sure to get your comment in before midnight on New Year’s Eve, Pacific Eastern Standard Time.
To increase your chances of winning, make sure to enter again once on each Tuts+ site. There are 8 giveaways going on right now, each with another chance to win.
If you don’t want to leave it to chance, you can begin your Plus membership for only $9.
Please note: Envato staff and people who have written more than two tutorials/articles for a Tuts+ site are not eligible to enter.
learn, php, rss, tutorials
PHP Tutorials | No Comments »
A Video Crash-Course in Raphael: New Plus Tutorial
Wednesday, December 30th, 2009
Raphaël is a JavaScript library that provides you with extreme flexibility when working with animations. If you’re unfamiliar with this library, you’ll be amazed when you view some of the demos, and find that no Flash has been used.
Perhaps the reason why this library hasn’t become as widely used as it should be is because there aren’t enough quality tutorials available around the web. Hopefully, this Plus tutorial will help! Join Plus!
Join Tuts Plus

For those unfamiliar, the family of TUTS sites runs a premium membership service called “TUTSPLUS”. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from Nettuts+, Psdtuts+, Aetuts+, Audiotuts+, and Vectortuts+! For the price of a pizza, you’ll learn from some of the best minds in the business. Join Plus!
- Follow us on Twitter, or subscribe to the Nettuts+ RSS Feed for the best web development tutorials on the web. Ready
Write a Plus Tutorial
Did you know that you can earn up to $600 for writing a PLUS tutorial and/or screencast for us? We’re looking for in depth and well-written tutorials on HTML, CSS, PHP, and JavaScript. If you’re of the ability, please contact Jeffrey at nettuts@tutsplus.com.
Please note that actual compensation will be dependent upon the quality of the final tutorial and screencast.

learn, php, rss, tutorials
PHP Tutorials | No Comments »
JavaScript from Null: Chapter 4
Wednesday, December 30th, 2009
JavaScript University continues today as we learn about methods of the Array object, how to return values from functions, scope, and even your first animation.
Remember – though each new chapter builds upon the previous ones, you can still follow along perfectly well if you haven’t watched the other entries in the series!
Catch Up
- Chapter 1: Hello World
- Chapter 2: Data Types
- Chapter 3: Conditional Statements
- Chapter 4: Arrays, Functions, and your First Animation
In this Screencast, you’ll Learn:
- Methods of the Array object: push, pop, unshift, shift
- Pull values outside of functions
- Reducing your “global footprint” by creating an object
- SetInterval
- Create your first animation
- Methods of the String object.
Chapter 4: Arrays, Functions, and your First Animation
Other Viewing Options
- Follow us on Twitter, or subscribe to the Nettuts+ RSS Feed for the best web development tutorials on the web. Ready
Ready to take your skills to the next level, and start profiting from your scripts and components? Check out our sister marketplace, CodeCanyon.
learn, php, rss, tutorials
PHP Tutorials | No Comments »
Win a $50 Amazon Gift Card – 12 for 2010, Day Ten
Wednesday, December 30th, 2009
As part of the tenth day of 12 for 2010, we’re giving away a $50 Amazon.com Gift Card to spend on whatever you like! Entering only takes a few seconds, since all you’ve got to do is leave a comment. Too easy.
Meet David Appleyard

David loves photography and Macs – and especially loves doing photography with the help of Macs! As such, he’s the editor of Phototuts+ and Mac.AppStorm. Aside from these sites, he manages four other design related websites. When we create Multitaskingtuts+ David will probably edit that too.
Win a $50 Amazon Gift Card

About the Prize
3D artists all over the world need to stay inspired. This gift card will help you to buy whatever it takes to keep the creative juices on tap – whether that’s great music, DVDs, books, art supplies, electronics… the choice is yours!
How to Enter in 10 Seconds or Less
For the chance to win a $50 Amazon Gift Card, all you need to do is comment. Make sure to include your correct email address with your comment so that we can contact you. This giveaway is open worldwide, but make sure to get your comment in before midnight on New Year’s Eve, Pacific Eastern Standard Time.
To increase your chances of winning something, make sure to enter again once on each Tuts+ site. There are 8 giveaways going on right now, each with another chance to win.
Please note: Envato staff and people who have written more than two tutorials/articles for a Tuts+ site are not eligible to enter.
learn, php, rss, tutorials
PHP Tutorials | No Comments »
Testing, Performance Analysis, and jQuery 1.4
Tuesday, December 29th, 2009
John Resig recently gave a three-part lecture on JavaScript for YUI Theater, which I found to be extremely informative. Over the course of ninety minutes or so, he goes over unit testing, as well as some of the changes the jQuery team have made in the upcoming jQuery 1.4. It’s well worth the watch!
- Follow us on Twitter, or subscribe to the Nettuts+ RSS Feed for the best web development tutorials on the web. Ready
Ready to take your skills to the next level, and start profiting from your scripts and components? Check out our sister marketplace, CodeCanyon.
learn, php, rss, tutorials
PHP Tutorials | No Comments »
WordPress 2.9.1 Release Candidate 1
Tuesday, December 29th, 2009
Thanks to everyone who tested 2.9.1 Beta 1. We’re following that up with Release Candidate 1. RC1 contains a few more fixes, bringing the number of fixed tickets up to 23. If you are already running Beta 1, visit Tools->Upgrade in your blog’s admin to get RC1. You can also download the RC1 package and install manually. If all goes well, 2.9.1 will be here soon.
rss
Uncategorized | No Comments »
F3::PHP Fat-Free Framework
Tuesday, December 29th, 2009
F3::PHP is a single-file PHP 5.3+ Web development framework with a fast template engine, HTML forms processor and an easy-to-use SQL handler for databases. All that in one tiny package! rss
Free PHP Scripts | No Comments »
Active Search!
Tuesday, December 29th, 2009
gamw with search engine


