Thursday, June 25, 2009

DreamHost Winning Entry: DreamBot

Two days ago I got word that I won the Grand Prize in the DreamHost API contest for my entry called DreamBot. Entries can be found here:

http://blog.dreamhost.com/2009/06/22/big-boy-time-is-up/

Dreambot is a secure Instant Messenger (IM) robot that runs on your Dreamhost server and performs possibly any server related tasks for you on demand. Dreambot’s core uses the XMPP protocol currently with Jabber Google Talk. Dreambot is fully customizable in that you can configure your Dreambot to respond to your specific set of commands sent to it. Dreambot is open source, object oriented, built in PHP5 and licensed under MIT.

More information on DreamBot can be found here:
http://dreambot.openovate.com/

Wednesday, June 24, 2009

How to Drupal 6 Right

First of all Drupal is lame. I think the Drupal code base should be thrown out. I am though, a fan of CCK and Views (only conceptually). Unfortunately Drupal has won the hearts of many novice programmers and corporations alike. This is why in this industry it's important to know how to Drupal. In my experience working with others on a Drupal project, the chances of your project correctly implementing Drupal is very slim. Infact, 90% of Drupal projects end up hacking the Drupal core, or hacking downloaded modules. That means 90% of Drupal projects cannot be updated.

And that's the thing. How do you Drupal right? Currently, I am very fortunate to lead a fresh project where the client wanted to use a fresh version of Drupal to build a private community site. We started actually developing the requirements on June 15, 2009. As of today June 24, 2009, from my point of view we are about 65% complete even when we received the final comps 3 days ago and we are way ahead of schedule. The great thing about it is that we never touched any of the core files or contributed modules and we came up with a system of process that generically solves most situations dealing with detail or listing views. Here is the process we do:

  1. Create a View to get data from DB. (Style should be "unformatted")
  2. Create a Drupal block that calls the view
  3. Create template file block-block-{BLOCK_ID}.tpl.php
  4. Create template file views-view-unformatted-{VIEW_NAME}.tpl.php
  5. Create template file views-view-fields-{VIEW_NAME}.tpl.php

Okay, before I go into more detail, lets first give a problem specification.

Problem Specification:
Home page needs a list of stories.

1. Create a View to get data from DB. (Style should be "unformatted")
So for this step you should be familiar with how to make a view. When creating a view give it a very easy to remember name and title. This is also where a standard naming convention will make the process easier to remember. (ie. Sash Story List, Main Story Detail etc.)

2. Create a Drupal block that calls the view
So remember that naming convention? When we create a new Drupal block we should also name the block (in the description field) with the view that it will be using. (ie. Sash Story List, Main Story Detail etc.) There might be other blocks here that might not be using a view, this is why I append something to tell us that this block is using a view (ie. Sash Story List[PHP + View]).



In the Block Body is where we call our view. We do it here mainly to set the arguments if there are any and to keep the logic in data formation away from the template. This is an example of what I would put in the Block Body given this problem specification.


?php
//CALL THE VIEW
$view = views_get_view('sash_story_list');

//SET THE ARGUMENT IF ANY
//in this case if there is a "type" flag
//lets filter the view by "type"
if(isset($_GET['type']) && $_GET['type']) {
set_arguments(array($_GET['type']));
}

//PUSH IT BACK INTO THE THEME
echo $view->execute_display('page_1');
?>



3. Create template file block-block-{BLOCK_ID}.tpl.php
This is where you can control the wrapper HTML for the output. "$block" will be available to use. If you have comps, the best thing to do is to strip out all the HTML to make styling easier. I normally just do this


< ? print $block->content;?>


or even this..


< class="block">
< ? print $block->content;?>
< /div>


4. Create template file views-view-unformatted-{VIEW_NAME}.tpl.php
This is where you can control the wrapper HTML for each row. "$rows" will be available to use. If you are using a detail view, I just use the following to strip out all the tags.


?php
foreach ($rows as $id => $row) {
php print $row;
}
?>


5. Create template file views-view-fields-{VIEW_NAME}.tpl.php
And this is where you can control how the detail HTML should look like for each column.



And that's pretty much it. Rinse Dry Repeat. Create function overrides and your custom functions in template.php when necessary. This is the process we have been doing and is pretty much solid and hopefully we will have an early turn around date.

Enjoy!

Thursday, March 19, 2009

iframe proxy natively and with jQuery

So one caveat with AJAX is the fact that you cannot AJAX files. At SolutionSet we adopted a solution called an iframe proxy or as Grady Khunline would call it "FAJAX". It involves injecting an iframe in the document and setting a form to target that iframe whenever it is submitted. Using a proxy has another advantage over AJAX in that we can also retrieve data accross servers and is a native solution where AJAX is unavailable. One main caveat when using an iframe proxy is that you cannot get response headers which depending on your project may or may not be important.

I found that when dealing with browsers there is infact a specific way to implement this. Before I go into details an example can be found at http://projects.blanquera.com/proxy/ . It has been tested in IE6+7, FF2+3, Safari, Opera and Google Chrome. The general solution I will provide will be explained using native JavaScript.

1. Create an iframe.
var frame = document.createElement('div');
frame.innerHTML = '<iframe id="frame_proxy" name="frame_proxy" src="blank.html"></iframe>';
frame = frame.getElementsByTagName('iframe')[0];
frame.style.display = 'none';

What this does is create an iframe wrapper and set the innerHTML to a string version of an iframe. In IE6+7, creating an iframe using the DOM builder (document.createElement) does not correctly register the iframe to windows.frames. Setting an innerHTML however does. Pretty wierd. The last valuable thing about this is src="blank.html". FF3, Safari, Opera and Google Chrome require this to be set for frame.onload to work properly. At this point there are 2 paths you can take.

2. Change target of an existing form to the id of the iframe.
document.getElementById('myFormId').setAttribute('target', 'frame_proxy')

Cross browser this should work. If you do not have a form and wish to just manually post to a page you will need to create a form dynamically. Don't fret, here's the implementation.
var form = document.createElement('form');
form.setAttribute('method', 'post');
form.setAttribute('action', 'server.php');
form.setAttribute('target', 'frame_proxy');
var params = unserialize('name=Joe&age=24');
for(var key in params)
{
input = document.createElement('input');
input.setAttribute('type', 'hidden');
input.setAttribute('name', key);
input.setAttribute('value', params[key]);
form.appendChild(input);
}

So what I'm trying to accomplish is convert a serialized set of parameters into a set of hidden fields. To do this we must first convert that string into a parsable object. I use my handy unserialize() function to accomplish this. From this code you can probally figure out how to make it dynamic for your project.
function unserialize(serial) {
var keyValue, unserial = {};
serial = serial.split('&');
for(var i = 0, length = serial.length; i < length; i++)
{
keyValue = serial[i].split('=');
if(keyValue.length == 2)
{
unserial[keyValue[0]] = keyValue[1];
}
}
return unserial;
};


3. Listen to iframe onload
frame.onload = function() {
var response = frame.contentWindow.document.body.innerHTML;
//////////////
//Do something with the response
//////////////
frame.parentNode.removeChild(frame);
}

This would be the area you would add your custom functionality in. Across all browsers, frame.contentWindow.document.body.innerHTML is the perferred way to get the contents of an iframe and it does not matter if the result is in HTML or not this way will still get the raw data. The last part of this is removing the iframe and possible the form from the document however you want. If you dynamically created the form from the last step you want add form.parentNode.removeChild(form); below frame.parentNode.removeChild(frame);

4. Add the frame to the document
document.body.appendChild(frame);

If you dynamically created the form from step 2 then you also want to invoke form.submit(); after this. It's important to know that you can use the same iframe for every proxy call however in jQuery, do not use $(document.body).append(iframe); because this will first clone the iframe then append it. You will find yourself with multiple iframes in your document.

The example at http://projects.blanquera.com/proxy/ is written in jQuery. I called my plugin "proxy". Here's how you would use it:
$.proxy({
url: 'server.php',
form: form,
success: function(response) {
form.replaceWith('<div>'+response+'</div>');
}
});


I hope this was informative. If you have any questions please comment and I will get back to you as soon as possible. Enjoy!

Saturday, March 07, 2009

JavaScript: Namespace - Setters, Getters, Issetters and Unsetters

So I heard this thing about conserving global namespaces is really important. I agree, but why stop at global? What about conserving namespaces in each and every object? Below are my 4 ultimate namespace functions which I have been known to use in almost every JavaScript project I'm in. It's good to have an easy access namespacer maker doodad.

Usage:

  • namespace.get(object, string[, string..]) - returns the value given the name space path within the given object

  • namespace.get(string[, string..]) - returns the value given the name space path within the global namespace registry

  • namespace.set(object, string[, string..], variable) - sets the value given the name space path within the given object to the last argument value

  • namespace.set(string[, string..], variable) - sets the value given the name space path within the global namespace registry to the last argument value

  • namespace.unset(object, string[, string..]) - unsets the value given the name space path within the given object

  • namespace.unset(string[, string..]) - unsets the value given the name space path within the global namespace registry

  • namespace.isset(object, string[, string..]) - checks to see if the name space path is set in the given object

  • namespace.isset(string[, string..]) - checks to see if the name space path is set within the global namespace registry



Definition:
namespace.js
/**
* @file namespace.js
**/
var namespace = {
//the name space registry
registry: {},

/**
* @method get
* @return var
* @notes returns the value of the
* name space given the path
* @usage
* namespace.get(object, string[, string..]) - returns the
* value given the name space path within the given object
* namespace.get(string[, string..]) - returns the value given
* the name space path within the global namespace registry
* @examples
* namespace.get({id:1, attr:{type:'custom'}}, 'attr', 'type') - For this
* case it would return 'custom'
* namespace.get('_definitions', 'node') - for this case it would return
* null if no definitions or no node are definied
**/
get: function get() {
//convert args to array format
var args = Array.prototype.slice.apply(arguments);

//what object are we looking into?
//if the first argument is not an object
//use namespace's registry
var reg = typeof args[0] == 'object' ? args.shift() : this.registry;

if(args.length > 0)
{
var result;
//foreach argument
for(var i = 0, length = args.length; i < length; i++)
{
//this is the last item
if((i+1) == length)
{
//assign it to result
//exit loop
result = reg[args[i]];
break;
}
//the name does not exist
if(!reg[args[i]])
{
//assign result to null
//exit loop
result = null;
break;
}

//walk the object
reg = reg[args[i]];
}
return result;
}

//if no arguments
//return the whole object
return reg;
},

/**
* @method set
* @return this
* @notes creates the name space
* given the space and sets the
* value given the last parameter
* @usage
* namespace.set(object, string[, string..], variable) - sets the
* value given the name space path within the given object
* to the last argument value
* namespace.set(string[, string..], variable) - sets the
* value given the name space path within the global namespace
* registry to the last argument value
* @examples
* namespace.set({id:1, attr:{type:'custom'}}, 'attr', 'valid', true) - For this
* case it would alter the object to {id:1, attr:{type:'custom', valid: true}}
* namespace.set('_definitions', 'node', function(){}) - for this case it would
* alter the registry setting a new name space 'node' after '_definitions'
* and assign it an empty function
**/
set: function set() {
//convert args to array format
var args = Array.prototype.slice.apply(arguments);

//what object are we looking into?
//if the first argument is not an object
//use namespace's registry
var reg = typeof args[0] == 'object' ? args.shift() : this.registry;

if(args.length > 1)
{
var last, index;
//foreach argument
for(var i = 0, length = args.length; i < length; i++)
{
//this is the last item
if((i+1) == length)
{
//set it to the value
//exit loop
last[index] = args[i];
break;
}
//the name does not exist
if(!reg[args[i]])
{
//lets create the name
reg[args[i]] = {};
}

//walk the object
last = reg;
index = args[i];
reg = reg[args[i]];
}
}

//allow chainability
return this;
},

/**
* @method unset
* @return this
* @notes unset a name space
* @usage
* namespace.unset(object, string[, string..]) - unsets the
* value given the name space path within the given object
* namespace.unset(string[, string..]) - unsets the
* value given the name space path within the global namespace
* registry
* @examples
* namespace.unset({id:1, attr:{type:'custom'}}, 'attr') - For this
* case it would alter the object to {id:1}
* namespace.unset('_definitions') - for this case it would
* alter the registry deleting all information about '_definitions'
**/
unset: function unset() {
//convert args to array format
var args = Array.prototype.slice.apply(arguments);

//what object are we looking into?
//if the first argument is not an object
//use namespace's registry
var reg = typeof args[0] == 'object' ? args.shift() : this.registry;

if(args.length > 0)
{
//foreach argument
for(var i = 0, length = args.length; i < length; i++)
{
//this is the last item
if((i+1) == length)
{
//delete it
//exit loop
delete reg[args[i]];
break;
}

//walk the object
reg = reg[args[i]];
}
}

//allow chainability
return this;
},

/**
* @method isset
* @return bool
* @notes checks to see if a name is taken
* @usage
* namespace.isset(object, string[, string..]) - checks
* to see if the name space path is set in the given
* object
* namespace.isset(string[, string..]) - checks
* to see if the name space path is set within the
* global namespace registry
* @examples
* namespace.isset({id:1, attr:{type:'custom'}}, 'attr', 'valid') - For this
* case it would return false
* namespace.isset('_definitions'') - for this case it would
* return true
**/
isset: function isset() {
//convert args to array format
var args = Array.prototype.slice.apply(arguments);

//what object are we looking into?
//if the first argument is not an object
//use namespace's registry
var reg = typeof args[0] == 'object' ? args.shift() : this.registry;

if(args.length > 0)
{
//foreach argument
for(var i = 0, length = args.length; i < length; i++)
{
//the name does not exist
if(!reg[args[i]])
{
//exit loop
//false will be returned
return false;
}

//walk the object
reg = reg[args[i]];
}

return true;
}

//if no arguments
//then return false
return false;
}
};


Examples:
To set a namespace:
//given an object
var object = {id: 0, attr: {type: 'custom'}};
namespace.set(object, 'attr', 'value', 20);
//using the namespace registry
namespace.set('some', 'random', 'namespace', 20);
To get a namespace:
//given an object
var object = {id: 0, attr: {type: 'custom'}};
namespace.get(object, 'attr', 'type'); //returns 'custom'
//using the namespace registry
namespace.get('some', 'random', 'namespace'); //returns 20
To unset a namespace:
//given an object
var object = {id: 0, attr: {type: 'custom'}};
namespace.get(object, 'attr'); //object would equal {id: 0}
//using the namespace registry
namespace.get('some', 'random'); //registry would equal {some:{}}
To check if a namespace exists:
//given an object
var object = {id: 0, attr: {type: 'custom'}};
namespace.get(object, 'attr2'); //returns false
//using the namespace registry
namespace.get('some'); //returns true


A live example of the usage can be found here

JavaScript: Class Templates Files

So every senior JavaScript developer should have a quick copy paste class template file in their library collection. I really think companies and program libraries should be more proactive in using these because it enforces a specific coding standard. jQuery is a good example of how their coding standards are not only enforced but also implied **slap on the butt to John**. Can you imagine if some methods in jQuery didn't return this? The following are 3 of my most commonly used templates.

1. Standard Class Definition Template standard.js
/**
* @file
* @author
**/
function myClass() {
/* Constructor
-------------------------------------------*/
this.init = function init() {
//-------------------------------//
// 1. Step One
};

/* Public
-------------------------------------------*/
/**
* @method protected
* @return obj|null
* @notes gives access
* to protected methods
**/
this.protected = function(name) {
//validate
if(!arguments.callee.caller || !name || !this[name] ||
arguments.callee.caller != this[name])
{
return null;
}

return protected;
};

/* Protected
-------------------------------------------*/
var protected = {/*Your protected stuff*/};


/* Private
-------------------------------------------*/
/**
* @method
* @return
* @notes
**/
function method3() {
//my private method
};

/* Destructor
-------------------------------------------*/
this.destroy = function destroy() {};

/* Call the initializer
-------------------------------------------*/
var _this = this;
this.init(Array.prototype.slice.apply(arguments));
}


2. Singleton Class Definition Template singleton.js
/**
* @file
* @author
**/
var myClass = new function() {
/* Properties
-------------------------------------------*/
/* Constructor
-------------------------------------------*/
this.init = function init() {
//-------------------------------//
// 1. Step One
};

/* Public Methods
-------------------------------------------*/
/**
* @method
* @return
* @notes
**/
this.method1 = function method1() {
//my public method
};

/* Private Methods
-------------------------------------------*/
/**
* @method
* @return
* @notes
**/
function method3() {
//my private method
};

/* Destructor
-------------------------------------------*/
this.destroy = function destroy() {};

/* Call the initializer
-------------------------------------------*/
var _this = this;
this.init(Array.prototype.slice.apply(arguments));
};


3. Prototype Definition Template prototype.js
/**
* @file
* @author
**/
var myClass = {
/* Properties
-------------------------------------------*/
/* Constructor
-------------------------------------------*/
init: function init() {
//-------------------------------//
// 1. Step One
},

/* Methods
-------------------------------------------*/
/**
* @method
* @return
* @notes
**/
method1: function method1() {
//my public method
},

/* Destructor
-------------------------------------------*/
destroy: function destroy() {}
};

Friday, March 06, 2009

Javascript: Protected Methods and Properties Now Available

With no introduction here's the JavaScript Protected Method Pattern.

In standard class form:
function YOURCLASS() {
//privilaged
this.protected = function(name) {
//validate
if(!arguments.callee.caller || !name || !this[name] ||
arguments.callee.caller != this[name])
{
return null;
}

return protected;
};

var protected = {/*Your protected stuff*/};
}


Here's an example implementation: See the example
//1. Create the class
function myClass() {
//public
this.property = 60;;
this.method1 = function() {
//in the initial definieiton of the
//class access protected directly
return protected.method();
};

//protected
this.protected = function(name) {
//validate
if(!arguments.callee.caller || !name || !this[name] ||
arguments.callee.caller != this[name])
{
return null;
}

return protected;
};

//private
//retain the public scope for
//the protected methods
var public = this;
var protected = {
property: 15,
//an example on how to
//call public methods
method: function() {
return public.property;
}
};
}

//2. Extend the class
myClass.prototype.method2 = function() {
//use the protected method
//to get the protected stuff
var protected = this.protected('method2');

//an example of changing the protected stuff
protected.property += 25;

return this;
};

myClass.prototype.method3 = function() {
//use the protected method
//to get the protected stuff
var protected = this.protected('method3');

//call public method1
var value = this.method1();

//now use the protecred stuff
return protected.property + value;

};

//3. use the class
var myNewClass = new myClass();

var results = myNewClass.method2().method3(); //returns 100;

//what just happened:
//Public method2() added 25 to the protected property (Now it's 40)
//Public method3() called public method1()
//which called the protected method()
//which returned the public property (Which is 60)
//Public method3() then returns the sum
//of the value of public method1()
//and the protected value (Which is 100)
alert(results);


Here's some key features:

  1. The protected object is still available after extending.

  2. The protected object is not available outside of the class.

  3. Very small overhead.



And with no summary or explanation, Enjoy!

Thursday, August 21, 2008

WAMP Server with SVN

Been looking around for a tutorial on this. I have a great idea of creating a secure mp3 repository only I have access to update all my computers (1 desktop and 3 laptops)

Note: If any links are broken consider this post depricated.




** Download Svn1ClickSetup-1.3.3.exe
** Execute “WampServer2.0c.exe” - When you get to the “Select Destination Location” Step remember the location (ie. C:\wamp). This will bee the {WampServer2.0c.exe install directory} in this instructions

** Download WampServer2.0c
** Execute “SvnClickSetup-1.3.3.exe” - When you get to the “Repository Location” Step remember the location (ie. C:\svnrepos). This will be the {Repository Location} in this instructions

** Download mod_dav_svn.so
** Download mod_authz_svn.so
** Copy “mod_dav_svn.so” and “mod_authz_svn.so” to {WampServer2.0c.exe install directory}\bin\apache\apache2.2.8\modules\

** Download libdb44.dll
** Download intl3_svn.dll
** Copy “libdb44.dll” and “intl3_svn.dll” to {WampServer2.0c.exe install directory}\bin\apache\apache2.2.8\bin\

** Execute {WampServer2.0c.exe install directory}\wamp\wampmanager.exe (a white half circle will show up on the right side of the task bar)

** Left click the white half circle -> Apache -> httpd.conf (this opens the file)

** Find:
#LoadModule dav_module modules/mod_dav.so
#LoadModule dav_fs_module modules/mod_dav_fs.so

** and add in new line after:
#LoadModule dav_svn_module modules/mod_dav_svn.so
#LoadModule authz_svn_module modules/mod_authz_svn.so

** Right click the white half circle -> Exit

** Execute {WampServer2.0c.exe install directory}\wamp\wampmanager.exe (a white half circle will show up on the right side of the task bar)

** Left click the white half circle -> Apache -> Apache Module -> dav_module
** Left click the white half circle -> Apache -> Apache Module -> dav_fs_module
** Left click the white half circle -> Apache -> Apache Module -> dav_svn_module
** Left click the white half circle -> Apache -> Apache Module -> authz_svn_module

** run cmd (Start -> run: cmd )
** run in cmd
C:\{WampServer2.0c.exe install directory}\bin\apache\apache2.2.8\bin\htpasswd.exe -c C:\{WampServer2.0c.exe install directory}\bin\apache\apache2.2.8\passwd {Whatever username you want (ie. myuser)}

** It will ask you for a “New Password”: Make up your own
** It will ask you to “Re-type new password”: repeat

** Left click the white half circle -> Apache -> httpd.conf (this opens the file)

** Find:
</IfModule>

Include

** and add in new line after:
<Location /svn>
DAV svn
SVNPath C:/{Repository Location}
Order allow,deny
Allow from all
AuthType Basic
AuthUserFile passwd
AuthName “Internal area”
require valid-user
</Location>

** Left click the white half circle -> Restart All Services