Code

Adding Another Sidebar to Wordpress

Monday, January 5th, 2009

I'm using Wordpress 2.7 at the time of writing, but my theme is modified from the default theme of version 2.5 or something. My current sidebar uses the widgets feature with some manually added stuff, sort of a lazy way of customizing stuff. I keep adding stuff to it and now I need a second one, which will inevitably require a wider site but my analytics shows most people these days have more than the formerly standard 1024x780 screen resolution and so it should be fine.

So if you're in the same boat as me, hand me that paddle, I'll show you what I did.

In your theme folder open your functions.php file, and find the following code:

 
if ( function_exists('register_sidebar') )
register_sidebar(array(
'before_widget' => '
<li id="%1$s" class="widget %2$s">',
'after_widget' => '</li>
 
',
'before_title' => '
<h2 class="widgettitle">',
'after_title' => '</h2>
 
',
));
 

You may not have the above code, instead look for:

 
if ( function_exists('register_sidebar') )
register_sidebar();
 

In either case we want to replace it with the following:

 
if ( function_exists('register_sidebars') )
register_sidebars(2);
 

Note: changed sidebar to sidebars, and the number 2 indicates the total sidebars we want.

In your theme folder open your index.php file, and find the following code:

 
<?php get_sidebar(); ?>
 

Or depending on your theme:

 
<?php include(TEMPLATEPATH."/sidebar.php");?>
 

Since I want to add another right sidebar, add the following code below:

 
<?php get_sidebar('2'); ?>
 

Note: Anything between the ' ' is representative of the new file you have to create called in this case sidebar-2.php

Or in the later case for consistency you can instead add:

 
<?php include(TEMPLATEPATH."/sidebar-2.php");?>
 

The call for your sidebars in your index.php file should now look something like the following:

 
<div id="sidebar">
<?php get_sidebar(); ?>
<?php get_sidebar('2'); ?>
</div>
 

In my case since I already had a sidebar, the "sidebar" div was inside sidebar.php. As you can see from the code above, it needs to be in the index.php file. Change the div id in sidebar.php to "sidebar1", and in sidebar-2.php to "sidebar2".

Note: At this point you should see the two sidebars, and be able to add widgets or custom php. But it will likely appear below the other sidebar.

Since I have css rules for sidebar, and not sidebar1 or 2, I can just re-assign some of the rules to sidebar 1, create a similar set for sidebar two and adjust the overall body and content width. This all depends on your theme and where you want your new sidebar.


Flex 3-RegExp: Find Urls In Text And Html

Thursday, December 18th, 2008

There are a number of situations where you'd want to grab the urls from a block of text. For example you may be loading in some external or dynamic data and want to make the links clickable, or change their colour. Regular expressions are used in a multitude of languages; they define patterns that can be matched against a string, thus certain key characters used in defining a RegExp have to be escaped so they are interpreted as special characters like \d matches any digit. In Actionscript, you can define a RegExp by either wrapping it in double quotes "", or forward slashes//. In each case you would have to escape any characters that match the wrapping in addition to the characters that need to be escaped in the actual pattern. Further more Actionscript requires you to separate out the last part of the regular expression, called flags, and insert it as the second argument when defining a new RegExp object.

Here's how you find a url in text or html:

var str:String = new String('This is a url www.fightskillz.com, and this is another one: <a href="http://chalk-it-out.com">Chalk It Out</a>');
var reg:RegExp = new RegExp("\\b(((https?)://)|(www.))([a-z0-9-_.&=#/]+)", 'i');
var result:Object = reg.exec(str);
trace(result[0]);

First off if you're new to Flex/Actionscript you have to copy and paste this into a function and the variables created will only be accessable within that function while it's running as they are created and destroyed as it runs. If you wanted more permanence you'd just define the variables outside the function.

Now Let's break it down. The first \ is used as a character escape for Actionscript. In actionscript when defining a string within double quotes you'd escape a double that's part of the string like this "Look at this double quote \"". \b searches for a word boundary ie: a whitespace, or the beginning or end of a string.The next part ((https?)://)|(www.)) defines the first part of a 'word' that passes for a url. It's made up of two substrings, the first looks for http, the question mark deems the preceding character optional, so it'll match to https as well. It then looks to see if the protocol is followed by ://. The | character means OR, so if there is no protocol specified, it checks for (www.). Next we have [a-z0-9-_.&=#/] which is a list of characters a to z, 0 to 9, and various others commonly found in urls. This is followed by a + which instructs the pattern to match the preceding list of characters until it can't anymore. It can't anymore when it reaches whitespace, a single or double quote, brackets, or any other non-url character. Finally the RegExp flag i informs the pattern to be case insensitive.

reg.exec(str); executes the pattern on the specified string and returns the results as an array. Since the example is only designed to match the first url it encounters and then stop, the array will only have one result. The method reg.exec(str) is interchangable with str.match(reg)

Convert Milliseconds to Time (H:M:S)

Tuesday, December 9th, 2008

Converting milliseconds to a time string can be a pain, especially when you're measuring something dynamic. In most languages I've come accross the Date object is calculated by the number of milliseconds that have passed since Jan 1, 1970. Because the different parts of a date are based on different bases ie: 60 minutes in an hour, 24 hours in a day etc. It's a lot easier to get the milliseconds passed since Jan1, 1970 and work with that value. This only works if you want to get the difference between two dates. If you were to subtract two dates(expressed as milliseconds) and get 432000000 milliseconds(5 days), then convert that to a Date object, the code would interpret 432000000 as Jan 6, 1970.

In another scenario I was just writing a podcast player in Flex 3/AIR and wanted to convert the Sound.length and SoundChannel.position values, both of which are measured in milliseconds, and display the length and current position of the episode in formats that would make sense. So I wrote a generic function that accepts milliseconds as an argument and returns the formatted time string.

  /**    Milliseconds to Time String in Flex 3              **/
  /**    Author: Yoav Givati [http://fightskillz.com]       **/
 
public function fnMillisecondsToTimeCountUp(time:Number):String {
 
	//calculate playtime from milliseconds
	var h:Number = new Number(Math.floor(time/1000/60/60));
	//minutes left shows total minutes left plus hours, 1h5m = 65mins
	//so we subtract the amount of 60's added by the hours to get just minutes
	var m:Number = new Number(Math.floor(time/1000/60)-(h*60));
	//seconds left
	var s:Number = new Number(Math.floor(time/1000)-(m*60));
 
	//create string variables
	var hours:String;
	var minutes:String;
	var seconds:String
 
	//make sure minutes and seconds are always two digits
	if(m.toString().length == 1) {
		 minutes = "0"+m;
	} else {
		 minutes = m.toString();
	}
 
	if(s.toString().length == 1) {
		seconds = "0"+s;
	} else {
		seconds = s.toString();
	}
 
	//if hours or minutes are 0 we don't need to see them
	if(h == 0) {
		hours = '';
		if(m == 0) {
			minutes = '';
		} else {
			minutes = minutes+":";
		}
	} else {
		hours = h+":"
		minutes = minutes+":";
	}
 
	// after 1 hour passes the seconds become 4 digits long
	// the last two of those digits represent the actual seconds
	seconds = seconds.slice(seconds.length-2, seconds.length);
	return hours+minutes+seconds;
 
}

You'll notice that I'm using Math.floor(), it's crucial that you round down, because the way the hours are being calculated for example, rounding up would show one hour had passed after only a fraction of an hour, just rounding up the minutes or seconds would cause everything to be out of sync and the math would be concussed. For those of you who are confused I should clarify that Math.floor(1.8) would return a value of 1 and Math.ceil(1.3) would return a value of 2, the term 'round' is probably a misleading. If you were using this function to count down instead of up, you would use Math.ceil()(although still not for the hour value), you essentially want to stay on the 'other side' of the minute or second for as long as possible.

Simple Navigation Buttons in Flex 3

Thursday, December 4th, 2008

Say you have 3 linkbuttons, connected to a viewstack and you want to change the colour of the linkbutton that corresponds to the current view. In a simple scenario you don't want the user to be able to click linkbutton1 when they're staring at view1 because they're already there.

Step 1:

set the disabled colour of your linkbuttons, you can do this in design view, code view, or css.

Step 2:

give each linkbutton an id, for this example I'll use button1, button2, and button3.

Step 3:

add a ClickEventHandler to the linkbuttons should look something like the following in mxml

 

notice the argument being passed to the ClickEventHandler "button1", the function will use this to determine what button you clicked.

Step 4:

Write the function by opening a script tag like this

<!--[CDATA[
 
private function ClickEventHandler(str:String):void {
 
switch(str) {
 
     case 'button1':
          button2.enabled = false;
          button2.enabled = true;
          button3.enabled = true;
          break;
 
     case 'button2':
          button2.enabled = true;
          button2.enabled = false;
          button3.enabled = true;
          break;
 
     case 'button3':
          button2.enabled = true;
          button2.enabled = true;
          button3.enabled = false;
          break;
     }
}
]]-->

Passing a Multi-dimensional Array Between Javascript And Php.

Thursday, August 21st, 2008

Passing data between client and server is pretty straight forward, we use HTML structured forms and AJAX calls to put data up, and echo/print methods to bring it down. The data types transmitted are usually strings and numbers. Unfortunately Javascript and Php don't have built in conventions for you to pass arrays or objects between one another. This article shows you how to pass an array from server to client, and then from client to server. Looking around Google there are a number of other developers who've found ways to do this, but the methods they use tend to limit the number of tiers in the array being passed from client to server, use up unwarranted resources for multiple form items and variables to hold each array item, and limit your overall control of the task. This method focuses on getting your data from an array to a string and back again using 1 hidden input, 1 variable, and allows you to have as many tiers to your array as you have characters to use as delimiters.

Passing an array from Php to Javascript is quite simple, because our array starts in Php, and Php is parsed first by the server. The whole process can be done in one block of code. Loop through the array in Php echoing it into Javascript code, which when parsed by the clients browser will generate a Javascript array.

Say we have a Php array:

  1. <?php
  2. $Guitars = array (
  3. "Epiphone" => array("model" => "Prophecy Les Paul Ex", "neck" => "Mahogany"),
  4. "Fender" => array("model" => "Lite Ash Telecaster", "neck" => "Birdseye Maple" ),
  5. "Washburn" => array("model" => "Idol WI15", "neck" => "Rosewood")
  6. );
  7. ?>

On the page to be served add the following Php which will loop through the array generating the Javascript code to re-create the array on the client-side. You may also want to wrap the generated Javascript in a function if you don't want the array to be generated on page load, or want to be able to refresh/reset the array:

  1. <script type="text/javascript">
  2. var Guitars = new Array();
  3.  
  1. <?php
  2. foreach($Guitars as $row) {
  3. echo 'Guitars.push({"model":"'.$row['model'].'", "neck":"'.$row['neck'].'"});';
  4. }
  5. ?>
  1. </script>

That's it.

Now if you want to pass the array back from Javascript to Php it's a bit more complex. We'll use the Javascript array Guitars that we just created. First we'll need an HTML form:

  1.  
  2. <form id="form_Example" method="post" action="/example.php">
  3. <input type="hidden" id="arr_Guitars" name="arr_Guitars" />
  4. <input type="button" id="btn_Submit" value="Submit" onclick="fn_SubmitForm" />
  5. </form>
  6.  

Note the use of both id and name. Name will be assigned to the posted variables we'll need to pick up on the server, as for referring to the input in Javascript you could use the getElementByName(); but I find it to be less reliable and harder to keep track of which elements have a name and which have an id. Using id throughout your application is more uniform.

Anyway remember we still have the array Guitars from before, now we need to write the function called by the Submit button:

  1. <script type="text/javascript">
  2. function fn_SubmitForm() {
  3. arr_Guitars = document.getElementById('arr_Guitars'); //get the element
  4. arr_Guitars.value = ""; //make sure the value is empty in case the user double clicked
  5. //loop through the array Guitars concatenating the values into a formatted string
  6. for(var i in Guitars) {
  7. arr_Guitars.value += Guitars[i]['model'] + ':' + Guitars[i]['neck'];
  8. /*
  9.   //Nest this for(){} loop within itself for every tier of your array
  10.   //for each nesting move the delimiters over, if you used a ; next, the
  11.   //nested loop would look like the following:
  12.   for(var ii in Guitars[i]['avail_colours']) {
  13.   arr_Guitars.value += Guitars[i]['avail_colours'][ii]['colour'] + ';';
  14.   }
  15.  
  16.   //to add more array items to this Guitar[i] replace the last delimiter of
  17.   //the output of the last nested loop with that of the tier above it
  18.   arr_Guitars.value = arr_Guitars.value.replace(/;$/,":");
  19.   //or if you're finished with this Guitar[i] remove it
  20.   arr_Guitars.value = arr_Guitars.value.repalce(/;$/,"");
  21.   */
  22.  
  23. arr_Guitars.value += ',';
  24. //the preceding line could be added to the end of the first line of the
  25. //loop if you're only passing a two tiered array
  26. }
  27. //remove the last , from the formatted string
  28. arr_Guitars.value = arr_Guitars.value.replace(/,$/,"");
  29.  
  30. document.form_Decision.submit(); //submit the form
  31. }
  32. </script>

Note the formatted string uses the following structure model:neck,model:neck. Also for those new to regular expressions the expression used in the value.replace(); method in plain english means "the comma before the end of the string". Forward slashes mark the beginning and end of the expression, the comma represents a comma and the dollar sign represents the end of the string being analyzed.

Now on the server:

  1. <?php
  2. //get the formatted string
  3. $Guitars = mysql_real_escape_string($_POST['arr_Guitars']);
  4. //make sure the array being passed is not empty
  5. if($Guitars != ''){
  6. //Php's explode function breaks apart the string into an array of strings based on the delimiter
  7. //Here we break apart the string into it's sub-strings <em>model:neck</em>
  8. $Guitars = explode(",", $Guitars);
  9.  
  10. //for each exploded array item separate the model and neck values and elaborate the array
  11. foreach($Guitars as $key=>$row) {
  12. $row = explode(":",$row);
  13. $Guitars[$key] = array(
  14. "model" => $row[0],
  15. "neck" => $row[1]
  16. );
  17. }
  18. }
  19. ?>

And that's it, you now have $Guitars again on the server. This method of passing arrays is extensible in that each level of the array can have unlimited values, and the array itself can have unlimited dimensions. For every dimension added to the array you need a new delimiter and you have to run a variation on the second foreach() statement above based on that delimiter.

Embedding fonts in Flex 3

Friday, June 20th, 2008

Fonts are the creative content of the font designer or foundry, so if you don't have a collection of fonts you've paid for, and aren't planning on purchasing some, you should stick to free fonts. A good place to start is Google, you'll find plenty of foundries who make a few free fonts, and several sites like [http://www.fonts.com/]. You may choose to embed a particular font that came with your operating system for the sake of cross-platform uniformity as well, however you still need to make sure that it is either an OTF (Open Type Font) or TTF (True Type Font), as Flex works with these file types. There are ways to convert postscript and other font formats to OTF/TTF but it's tedious and you're better off finding a different compatible font

You can also load fonts as an external resource in your apps similar to just calling a system font, however embedding them is the way to go. Embedded fonts can be anti-aliased, take part in effects, and are handled as a true asset and thus with a higher regard in your application.

There are a number of ways to embed fonts in your Flex applications. If you're embedding a font that's active in your system you can specify the system name as in the following example:

@font-face {
src: local("Arial");
fontFamily: MyFont;
}

Likely however you'll not want to keep a whole bunch of fonts active or have to think about activating your project fonts every time you compile, in which case you can copy the font file to your project directory. In the example below the Arial font is in a 'fonts' sub-directory of my project:

@font-face {
src: url("/fonts/Arial.ttf");
fontFamily: MyFont;
}

Note: If you use spaces in the font family as in "My Font" you'll run into an issue where the font appears in Design View but isn't compiled with the app.

There are other options that can be specified to customize your font-face:

fontStyle: normal | italic | oblique;
fontWeight: normal | bold | heavy;
advancedAntiAliasing: true | false;

These style declarations are placed within the mxml <mx:Style> tag. The above code uses CSS, which is best for styling and skinning your application, but if you prefer you can do the same thing in actionscript.

For more information on how to, and why you should/shouldn't embed a font in your applications refer to [http://livedocs.adobe.com...fonts_09.html]

Keep in mind that font files can be quite large, in the 5-12MB+ range and that size will be added to the weight of your application. It's best to use lighter fonts when creating online apps, in which case try to find one's under 200KB.

Mootools 1.2 – Update any element with Ajax

Sunday, May 18th, 2008

Easily update any element's inner html with an ajax get request.

Simple get request

$('div_files').load('getfiles.php');

What it does is get the content of getfiles.php and uses it as the innerHtml for the div with id

'div_files'

Slightly more complex get request

var myHTMLRequest = new Request.HTML({url:'getfiles.php', update:'div_files'}).get({'user_id': 25});

In this get request, like the simple one you specify the location of the server side script, which happens to be in the same directory, and you specify the element who's innerHtml you want to update. After the

.get

you send a variable to the server, in this case

user_id

with the value 25.

Note: In the php file you'll need to use a

$_GET['user_id']

instead of

$_POST

Downloading a File with Flex 3

Sunday, May 18th, 2008

I stumbled over this when I was building the CCMCP Library app but I suppose history's due to repeat itself. The problem is this: downloading a file from flex just doesn't work; A dialogue pops up, you choose a place to save the file, but when you hit save no file gets downloaded.

If you're sure the url is correct and you haven't made any syntax errors, then the most likely cause is that you've declared the

'fileRef'

variable within the

'download();'

function. The following code will work.

private var fileRef:FileReference = new FileReference();
 
public function download():void
{
fileRef.download(new URLRequest('http://web-site/file-name'), 'simple filename');
}

The problem's also documented at Adobe and Lynch Consulting