 |
|
Thursday, May 8. 2008
Via Jono Smith, Director of Marketing for Network for Good:
Do you know a talented Web strategist or developer interested in coming up with new ways to use the Web for social good? Network for Good & the Case Foundation are sponsoring two $10,000 prizes for Web developers who do just that.
We are challenging developers to mash-up the Network for Good online donation processing API with another Web service to either (a) enhance the online donor experience or (b) revolutionize a nonprofit's ability to fundraise online. As if changing the world was not enough, the two winners will each receive a $10,000 prize.
For more information, you can check out the information page: http://www.netsquared.org/mashup/donatenowchallenge
Seeing as we've built our own little API for the CARMA site, I could envision something that let you look up local power plant emissions and then buy carbon offsets for the typical American's yearly usage. EULA: If you use this idea and win, you have to buy me a beer with the $10,000. And I get to pick which beer.
Wednesday, April 30. 2008
Looking at some recent licensing boo-boos, we came up with a nifty little tool to help you find the right license for your open source software. Any feedback would be appreciated, whether involving data correction or other features / categories you'd like added.
Wednesday, April 16. 2008
Languages are tricky, quickly evolving systems, but almost all of them in their current form predate computers. Indeed, most predate typesetting. So there are a ton of writing systems out there that are designed for writing with a trained human hand, and not optimised for discrete mechanical reproduction. Those languages persist, and computers are finally getting powerful enough to reproduce them elegantly. So how do we deal with them? First, get familiar with Unicode. Once you've done that, you'll find that regular web applications need a little more to work properly. For instance, what if you want to use full-text indexing on a script that isn't derived from Latin? Fortunately, MySQL as of version 4.1.1 makes that a lot easier...but there are some tricks. You'll need to learn about collations in MySQL. It is entirely possible in PHP to set everything you're doing to UTF-8 and have a site that can accept and reproduce lots of different scripts, but the database is storing them as something else. However, you give up a lot. First, your database dumps will be unrecoverable gibberish. Second, functions that depend on MySQL understanding how the underlying data behaves, such as full text indexes, will fail. MySQL out of the box to have latin1_swedish_ci be the default collation, which I find an extremely odd choice. OK, so they're fighting Amerocentrism, but they're not exactly promoting international standardization. So unless you specify that you want the database storing information as utf8_unicode_ci (which I've found to be the most hassle-free for the widest range of character sets), you'll need to specify that your database and all its tables and rows use the utf8_unicode_ci collation, which will also cause them to store everything as UTF-8. But wait--you're not done. You'll also need to make sure your connection defaults to UTF-8. That's right, you have to have a clean UTF-8 path through your whole application. Just one place where UTF-8 isn't respected will turn everything to unreadable gibberish or a string of question marks. You can have your application issue 'SET NAMES utf8' for every request. The best option is to make sure you have an environment where you can control the MySQL configuration until they come up with some better defaults. Once you do this, and providing you do all the things you need to do in HTML and PHP (or the scripting language of your choice) to make them UTF-8-clean as well, you should be able to do all the things you're used to in other languages.
Tuesday, April 1. 2008
At least, I hope its not an April Fool's joke. It looks more like someone's lawyers go up to 11. From the Slideshare API Terms of Service. (iii) use the SlideShare APIs to operate nuclear facilities, life
support, or other mission critical application where human life or
property may be at stake. You understand that the SlideShare APIs are
not designed for such purposes and that their failure in such cases
could lead to death, personal injury, or severe property or
environmental damage for which SlideShare is not responsible;
Friday, March 21. 2008
Jeff Vodel provides tips for writing more comprehensible code, in a very humoruous article. They don't just apply to solo coders, people who inherit or update your code down the line will also thank you. Even though they're written for C programmers, his advice applies to any programming language. For web programmers, #5 should be heeded, as we've learned that the code we run on the server typically contributes only a fraction towards how long users must wait to see your web page. You get more bang for the buck by reducing how much data browsers have to download (file sizes) and how many connection it must make (hits to download css, images, javascript files, etc...).
This means that, if I make a stinky mess, I'm doing it in my own nest. When I'm chasing down a bug at 3 a.m., staring at a nightmare cloud of spaghetti code, and I say, "Dear God, what idiot child of married cousins wrote this garbage?", the answer to that question is "Me."
I've written previously my own set of tips to write readable php code.
Friday, March 21. 2008
There is an excellent case study in NY Times on how Zen's ultra simple camcorder the Flip has grabbed 13% of the camcorder market and been the best-selling camcorder on Amazon.com. It did this not by offering every feature and tech acronym buzzword under the sun, but by making it trivially easy to use. David Poque says,
Instead, the Flip has been reduced to the purest essence of video capture. You turn it on, and it's ready to start filming in two seconds. You press the red button once to record (press hard -- it's a little balky) and once to stop. You press Play to review the video, and the Trash button to delete a clip. There it is: the entire user's manual.
"But Oscar, we don't make camcorders or gadgets. Whats your point?" The success of the Zen lies in getting out of the way of users who want to record a video clip. User's don't need to adjust a million settings, don't have the option of adding special effects, zooming in and out, and so on. They just point and record. Next time you're building out a new web site, section of your web site, or any point where you're asking users to interacts with you - fill out a form, post a comment, make a donation - try to eliminate as much cruft as possible and reduce the interaction to its barest essence. Ideally, and I'm probably a bit of an idealist for writing this, this would mean an email newsletter subscription form that, shocker, has only one field for the user's email address, and no more. Or a donation form that is simply the amount to donate and fields required to process payment. The less hoops you make users jump through, the more users may jump through your hoops.
Friday, March 21. 2008
Google Analytics releases a new feature two weeks ago, allowing sites to anonymously share data with comparable sites. Benchmarking site traffic has been something we've suggested to clients in the past, and in a few cases have facilitated it on a small scale. But now, you can compare how your blog, online community, association, or non-profit's website compares to peers who also use GA. I'd stress that you're comparing yourself to other peers who use the service and choose to share the data so there is some selection bias, and its up to Google to decide who you are compared with. Still, it makes available data that would otherwise be expensive or impossible to get, and as more sites otp to share their traffic, it can get better. You can learn how to enable this and what you can compare over at googlesystem.
The system is very beta at the moment, and the "Verticals" used to categorize sites are few at the moment. It can still help answer questions like:
- What are overall traffic patterns in my sector?
- Is my traffic growth/decline part of an overall traffic growth/decline or unique to my site?
- What's an "average" site like mine get in Page Visits/Visitors/Bounce Rate/New Vistors, and how do I compare?
Technorati Tags: Google Analytics, nptech
Wednesday, March 19. 2008
Within just the last several years, concern over climate change has grown significantly.
Interestingly enough, environmentally-focused online user engagement is an idea that remains largely untapped.
For the first time in human history, we are faced with a problem that needs worldwide cooperation to overcome. Scientific studies are showing time and time again that global warming is a very real problem. The effects from this unnatural global acceleration rate are already noticeable, and the media outlets aren't hesitating to scare us as much as possible.
The media, much like the web of the old, broadcasts an impersonal message to a collective whole. It speaks of climate change as if it's an inevitable fate. They speak of this problem as one of tremendous scope, and one that would require more than a goliath effort to undertake. Most people want to make a difference, but are intimidated by the size of the problem, given no direction, and are shown no clear community for which they can participate.
Web2.0 is personal. This "new media" can inspire awe through stories of overcoming obstacles. It can bring about one's inner determination using public disclosure to shock and sicken. It can also simply provide tools to allow users to build their own connections. Interactive media and public disclosure can cause people to want to act, but it's not always enough. Some of us need a personal trainer, not just a nudge. We need to narrow the scope of the problem so we can see exactly what difference we're making at a personal or community level. As this Yahoo CO2 calculator demonstrates, people need to see that even tiny lifestyle changes can make a difference. There needs to be a way of showing progress, a way of clarifying that their "baby steps" are being taken by countless others too -- adding up to an enormous leap forward.
There are some great web projects devoted towards reducing carbon emissions at the individual/community level, but the playing field is still very much open.
Tuesday, February 26. 2008
After doing some poking around on how to optimize databases for quicker reads I came across a rather simple approach called Vertical Partitioning. This approach is rather useful in taking advantage of the Query Cache as you will ultimately reduce the frequency in which the Query Cache is invalidated (blown away!). Before going further let me explain what the query cache does. It simply stores the text of a SELECT statement along with its result set sent to the client/user upon request. For identical queries the server retrieves the results from the query cache oppose to re-parsing the request and executing the statement resulting in quicker reads. For tables that contain static (unchanging) and dynamic (changing) data you could take advantage of vertical partitioning. Simply put, instead of creating one table that contains static and dynamic data you can use two tables that contain the static data and another that contains the dynamic data with a foreign key from the static data table. Lets look at the following example! | Un-Partitioned | Partitioned |
CREATE TABLE Users ( user_id
INT NOT NULL AUTO_INCREMENT,
email VARCHAR(80) NOT NULL,
display_name VARCHAR(50) NOT NULL,
password CHAR(41) NOT NULL,
first_name VARCHAR(25) NOT NULL,
last_name VARCHAR(25) NOT NULL,
address VARCHAR(80) NOT NULL,
city VARCHAR(30) NOT NULL,
province CHAR(2) NOT NULL,
postcode CHAR(7) NOT NULL,
interests TEXT NULL,
bio TEXT NULL,
signature TEXT NULL,
skills TEXT NULL,
PRIMARY KEY (user_id),
UNIQUE INDEX (email))
ENGINE=InnoDB;
|
CREATE TABLE Users ( user_id
INT NOT NULL AUTO_INCREMENT,
email VARCHAR(80) NOT NULL,
display_name VARCHAR(50) NOT NULL,
password CHAR(41) NOT NULL,
PRIMARY KEY (user_id),
UNIQUE INDEX (email)) ENGINE = InnoDB;
CREATE TABLE UserExtra ( user_id
INT NOT NULL,
first_name VARCHAR(25) NOT NULL,
last_name VARCHAR(25) NOT NULL,
address VARCHAR(80) NOT NULL,
city VARCHAR(30) NOT NULL,
province CHAR(2) NOT NULL,
postcode CHAR(7) NOT NULL,
interests TEXT NULL,
bio TEXT NULL,
signature TEXT NULL,
skills TEXT NULL,
PRIMARY KEY (user_id)) ENGINE=InnoDB;
|
As a result of the extra user information being partitioned out to its own 'UserExtra' table the frequent updates will not cause the reads for the unchanging data in 'Users' table to slow down keeping the query cache invalidation for 'Users' down to a significant minimum hence consistently faster reads.
Monday, February 18. 2008
Once you've been using Subversion when you and and your colleagues are working on a project, you're bound to find useful ways to exploit Subversion's hook system. We use the sample commit-email.pl script to send all commits to an email list for ad-hoc peer-review. I found and enabled Ian Christian's pre-commit script to check PHP syntax when checking in code.
The latest piece of the puzzle was to restrict commits to a project's branch to a few users, which has been harder to figure out than I expected. The most common script for access control is svnperms, which has a rich syntax for configuring access. Unfortunately, svnperms seems to work best with a repository with the following repository layout:
Our repository is laid out as:
I was trying to restrict access to Project1's stable branch (project1/branches/stable), and this didn't seem to be possible under svnperms, no matter how many regular expressions I tried. Subversion provides another access control script, commit-access-control.pl script, but having been burned by svnperms, I was reluctant to spend too much time trying to configure it and get it to work.
Since hooks are just shell scripts, its easy to write your own, which is what I did in this case. The place to check commit access is before the transaciton is created, in the start-commit hook. Being more comfortable in PHP, I whipped up the following command line script and saved it as check_commit_privs.php
#!/usr/bin/php
<?php
/*
CHECKS IF A USER CAN COMMIT TO THE REPOSITORY
Oscar Merida <omerida@forumone.com>
*/
// SVN passes two arguments, the repository path and user for the commit
$repo_path = $_SERVER['argv'][1];
$commit_user = $_SERVER['argv'][2];
// You can use array to define user groups
$qa_group = array('bob', 'roger', 'amanda'');
$contractors = array('marco', 'dawn', 'bill');
// CONFIGURATION
//
// array key is a path in SVN repository or a regular expression that will match a path.
// value is an array of usernames that can commit to that path
// first path match that limits access will prevent commits.
// This script assumes you only need to lock down certain
// parts of your repository.
$allowed = array(
// only contractors can commit to widgets project
'/widgets/' => $contractors,
// only qa_group can commit to any project's testing branch
'/.*\/branch\/testing/' => $qa_group,
// only bill can commit to his project
'/bills_project/' => array('bill')
);
foreach ($allowed as $regexp => $group)
{
if (preg_match($regexp, $repo_path)
&& !in_array($commit_user, $group))
{
exit(1);
}
}
To enable this script, create or add a file named 'start-commit' to your repository's hooks/ folder with the following. If there is a file named start-commit.tmpl, copy that as a starting point. You'll also have to make sure that both start-commit and check_commit_privs.php are executable by your SVN users.
REPOS="$1"
USER="$2"
# basic permissions check
/path/to/check_commit_privs.php "$REPOS" "$USER" || exit 1
Friday, February 15. 2008
While reading some code, I came across a pleasantly surprising snippet that a coworker had added, and it went something like this:
Calling functions through variables
function display_output()
{
return 'This is the output text!';
}
$variable = 'display_output';
echo $variable();
Result: $variable() = 'This is the output text!';
With closer inspection, this is a pretty cool feature in PHP. It allows you to dynamically call a function by treating a variable like a function. When parentheses are after the variable name, PHP calls the function whose name equals the variable's value. Ex: if $foo = 'bar', then doing $foo() will try calling a function named bar(). Sure, the same result can be achieved using IF loops, but in PHP, it's always good to at least know of the alternatives.
Variable variables
$charlie = 'delta';
$delta = 'oscar';
echo $$charlie;
Result: $$charlie = 'oscar';
My coworker, Oscar, also informed me about "variable variables". These buggers have that extra dollar sign. In the previous example, PHP looks at the value of $charlie, which is 'delta'. It then returns the value of $delta, which is 'oscar'.
Creating variables dynamically
$when = 'future';
$variable_past = 'Welcome to the past';
${'variable_' . $when} = 'Welcome to the ' . $when;
Result: $variable_future is created, and $variable_future = 'Welcome to the future'
This is helpful for when you need to create numerous variables on the fly, such as within a FOR loop. However, it may end up making more sense to create an associative array, depending on how much data you need stored. Ex: $container_array['dynamic_name'] = 'some_value'; Again, this all depends on your given situation.
| |