Archive for the 'Programming Languages' Category

Flickr Galleries for Drupal

Install the Flickr module. That’s going to require a Flickr API key, so follow the instructions to set that up. You’ll need to enable the following modules: Flickr, Flickr Filter, Flickr Sets. Then enable the “Flickr linker” filter under Input Formats.

Keep in mind that only “public” photos work with this.

That’s going to let you put something like

[flickr-photoset:id=72157610617588420,size=s]

in the body of your document. When you save and view this document, you should see little thumbnails from your photoset. If you click on one, it’s going to take you to Flickr. We’ll be replacing that with Highslide.

Okay, so that’s nice but that [flickr-] stuff is a little hard to deal with. So what we’re going to do is install flickrset. This is a plug in I wrote for WYSIWYG and TinyMCE. You place it in

/sites/all/modules/wysiwyg/plugins

Then, in Drupal, go to /admin/settings/wysiwyg and edit any input formats that use TinyMCE. This is probably just “Full HTML.” Under the “Buttons and plugins” section you should see a new checkbox at the end labeled “Flickrset.” Turn that on and save it.

Now when you create a new document, you should see a new button in the body. The new button is the Flickr icon. When you click it, you get a pop up with three fields. You paste the URL of your Flickr photoset in there. You pick the size of the thumbnails you want. You pick the size of the “full size” pictures that you want. You click add. It’s going to build that [flickr-] crap for you.

You’ll see there’s a new thing in there, and that’s “class=showsizen.” This is the parameter for the “full size” picture. This isn’t going to work, out of the box. You’re going to need to hack the Flickr module. *gasp* So open

/sites/all/modules/flickr/flickr.module

and find the theme_flickr_photoset function. Change

$output .= theme('flickr_photo', $photo, $size);

to

$output .= theme('flickr_photo', $photo, $size, NULL, $attribs);

This is important because we’re passing the attributes to the theme function. The attributes contain, among other things, the class parameter we set earlier.

The module will let you pick a number of photos to appear in photosets. That’s nice if all your photosets are going to use the same number of photos, but if you want each gallery to display a different number of photos, you’ll need to add some functionality. Here’s how to do that.

In modules/flickr/filter/flickr_filter.module find flickr_filter_callback_photoset()

// change this line
return theme('flickr_filter_photoset', $photoset, $photoset['owner'], $config['size'], $attribs);
// to this
return theme('flickr_filter_photoset', $photoset, $photoset['owner'], $config, $attribs);

In modules/flickr/sets/flickr_set.module replace flickr_set_load() with

function flickr_set_load($sid, $num = 0, $page = 1) {
  // TODO: Not sure why this called for /flickr and does not show for admin role
 
  if ($num == 0) $num = variable_get('flickr_photos_per_page', 20);
 
  if (is_numeric($sid)) {	
    return flickr_request('flickr.photosets.getPhotos',
    array(
      'photoset_id' => $sid,
      'page' => $page,
      'per_page' => $num,
    )
    );
  }
}

In modules/flickr/flickr.module find theme_flickr_photoset()

// change the first two lines to this
function theme_flickr_photoset($ps, $owner, $config, $attribs = NULL) {
  $size = $config['size'];
// then change this line
$photos = flickr_set_load($ps['id']);
// to this
$photos = flickr_set_load($ps['id'], $config['num']);

Okay, so now if we look at our saved document, we see all the thumbnails there. Each image should have the “showsizen” class we specified. It may be “showsizeb” if you chose that size instead- n is normal, b is large. (These are abbreviations from the Flickr module, I didn’t make them up.) It’s still not going to expand to the correct size, we haven’t gotten that far. Just make sure your images have that class when they get displayed.

The last thing is this jQuery. This is going to hijack the resulting HTML so that Highslide can handle the full sized images.

$(document).ready(function() {
  $('.flickr-photoset a').each(function() {
      // we need a slightly different version of the static image url
      var thumb_url = $(this).children('img').attr('src');
 
      var showsize = "";
      if ($(this).children('img').hasClass('showsizeb')) {
        showsize = "_b";
      }
      if ($(this).children('img').hasClass('showsizen')) {
        showsize = "";
      }
 
      var dotpos = thumb_url.indexOf('.jpg');
      thumb_url = thumb_url.substr(0, dotpos - 2) + showsize + ".jpg";
 
      // now replace the a.href with this
      $(this).attr('href', thumb_url);
 
      // and fix it up for highslide
      $(this).addClass('highslide');
 
      this.onclick = function() {  return hs.expand(this); }
  });
});

Mapping Ryan

Recently my brother got a SPOT emergency beacon. One of the features is a non-emergency “check in” feature. He hits a button and it logs his location. Turns out, that log has an RSS feed. So I built an application to take the feed and put the items in a database. Then I build a page with a Google Map. The map pulls coordinates from the database and puts little markers on the map. Each marker is clickable, and a little balloon pops up that says “At such and such a date and time, I was at some address.” The markers are connected chronologically by lines. The most recent marker is a different color, and the map centers on that location.

Simple jQuery Accordion

I spent an hour trying to get the jQuery UI accordion to work and it just wasn’t right. So I wrote my own. And then, the next day, I made it simpler.

Get the files here.

Automatic Highslide

Assumes you are familiar with jQuery and Highslide

// prep "a img" for highslide
$('a').each(function() {
  if ($(this).children('img').length > 0) {
    $(this).addClass('highslide');
    this.onclick = function() {	return hs.expand(this); }
  }
});

Making Blocks of Content on the Home Page Editable in Wordpress

A popular home page design is a sort of newspaper layout, with lots of little blocks of content. An example of that is this website we did for Gilda’s Club.

What we want to do is make the “Mission” block, in the middle right, editable through Wordpress. It’s actually pretty easy to do.

1. Create a new page. Call it something like Home Page: Mission. Copy/Paste the content in there.

2. If you have the kind of navigation that picks up pages automatically, you’re going to need to add the page id to an exclude list in your wp_list_pages() call. This may be the header navigation, sidebar, and/or footer.

3. Now we’re going to modify our template. Find the part where that block content is hardcoded into the template. Replace it with this:

  $page_id = 541; // change to your page id, obviously
  $post = get_page($page_id);
  setup_postdata($post);
  the_content();

And you’re done.

Google’s Chart API

The last few days I’ve been playing with Google’s Chart API. It’s much simpler than their other APIs. This is pretty close to dirt simple. My only “complaint” is that a lot of the variable names are a bit obscure. I’m unlikely to remember that chxl means chart axis labels. So I started writing a little class to help.

$chart = new googleChart($data, $title, $width, $height)
data should be an associative array
- your keys become the x axis
- your values become the y axis
title, width, and height are optional

$chart->title = ‘This is my title!’;
$chart->width = 400;
$chart->height = 400;

color is the color of the line
it must be a hex code
$chart->color = ‘ff8800′;

fill is the color of the space under the line
it must be a hex code
$chart->fill = ‘ffff80′;

then all you have to do is call
$url = $chart->getURL();

You can check out my “alpha release” here.

jQuery Logo Rotator/Slider

For a client’s site, we had some partner logos in the lower left corner. Rather than let them take up a lot of space, we decided to have them rotate. Here’s the HTML.

<div id="partners">
	<a href="http://www.nationalgrid.com" target="_blank"><img src="/wp-content/themes/CEG/images/footer_logos/botlogosNATGRID.gif" alt="National Grid" /></a>
	<br />
	<a href="http://www.nystar.state.ny.us/" target="_blank"><img src="/wp-content/themes/CEG/images/footer_logos/botlogosNYSTAR.gif" alt="NYSTAR" /></a>
	<br />
	<a href="http://www.mep.nist.gov/" target="_blank"><img src="/wp-content/themes/CEG/images/footer_logos/botlogosMEP.gif" alt="NIST/MEP" /></a>
	<br />
	<a href="http://www.nist.gov/" target="_blank"><img src="/wp-content/themes/CEG/images/footer_logos/botlogosNIST.gif" alt="NIST/MEP" /></a>
	<br />
</div>

And here’s the jQuery.

var imageFader;
 
$(document).ready(function() {
  // get the images in the lower left going
  $('#partners').each(function() {
    $(this).children('br').hide();
 
    var speed = 1500;
    var pause = 5000;
    var next = 1;
    var counter = 0;
 
    // how many images are there?
    var max = $(this).children('a').length;
 
    $(this).children('a:gt(0)').hide();
 
    function fadeImages() {
      if (counter >= max) counter = 0;
      next = counter + 1;
      if (next >= max) next = 0;
 
      $("#partners").children('a:eq(' + counter.toString() + ')').slideUp(speed, function() {
        $("#partners").children('a:eq(' + next.toString() + ')').slideDown(speed);
      });
 
      counter++;
    } // end function fadeImages
 
    imageFader = setInterval(fadeImages, pause); 
  });
});

image_import_zip For Drupal 6

I’m working on a project where we have a ton of images that we’ll need to import into image galleries in Drupal 6. There are a bunch of nice modules to do this, but they expect the end user to have the correct JRE installed, or fail to function with .htaccess authentication. We needed something simpler.

There’s a module called “image_import_zip” which allows you to upload a zip file full of images without using FTP. It extracts them, and then you can use “image_import” to turn them all into image nodes. Which sounds nice, except that “image_import_zip” is only for Drupal 5, and the people responsible tell you to go use something Flashy for Drupal 6.

So I went ahead and hacked the module to work with Drupal 6. Enjoy.

Parse CSV File

I’m using wp-table for a Wordpress project, and you can read in data from a csv file and it builds a table for you. At least, that’s the theory. In fact, it uses PHP’s built-in fgetcsv() function. Which blows.

fgetcsv() does a good job of parsing lines which are comma separated values, but it’s really profoundly retarded about understanding that the end of a line is the end of a record. If you read in 1000 bytes, you could have 10 records/line in there, but it mashes them all into one array.

So I wrote my own. It’s pretty basic, but it works.

function parse_csv_file($file, $columnheadings = false, $delimiter = ';', $enclosure = '"') {
 
	$row = 1;
	$rows = array();
 
	$file_contents = file_get_contents($file);
 
	// determine the line break character sequence
	$line_break = chr(13) . chr(10);
	$pos = strpos($file_contents, $line_break);
	if ($pos === false) { // didn't find that
		$line_break = chr(10);
		$pos = strpos($file_contents, $line_break);
		if ($pos === false) { // not that either
			$line_break = chr(13);
			$pos = strpos($file_contents, $line_break);
			if ($pos === false) { // uh oh
				// Cannot determine line break character sequence.
				exit;
			} else {
				// Line breaks on 13
			}
		} else {
			// Line breaks on 10
		}
	} else {
		// Line breaks on 13.10
	}
 
	$lines = split($line_break, file_get_contents($file));
	foreach ($lines as $line_num => $line) {
		$line = trim($line);
		if ($line == '') continue;
 
		$l = array();
		$enc = false;
		$v = '';
		for ($i = 0; $i < strlen($line); $i++) {
 
			$char = substr($line, $i, 1);
 
			if ($char == $enclosure) {
 
				if ($enc) {
					$enc = false;
				} else {
					$enc = true;
				}
 
			} else if ($char == $delimiter) {
 
				if ($enc) {
					$v .= $char;
				} else {
					$l[] = $v;
					$v = '';
				}
 
			} else {
				$v .= $char;
			}
 
		} // end foreach character in this line
 
		$rows[] = $l;
	}
 
	return $rows;
}

Show/Hide CSS For Three Levels Of Menu/Nav

Written with wordpress in mind, but you can adapt as necessary.

Often you have levels of pages. You’ll have top level pages, and some of them have child pages, and some of those child pages have grandchild pages. Usually what you want is for the menu/navigation/sidebar to limit what it’s displaying. You don’t want to see everything, only what’s under where you are now in the hierarchy.

Default case:
ONE
TWO
THREE
Case 2:
ONE (current page item)
- CHILDA
- CHILDB
- CHILDC
TWO
THREE
Case 3:
ONE (current page parent, current page ancestor)
- CHILDA (current page item)
- - GRANDCHILD
- CHILDB
- CHILDC
TWO
THREE
Case 4
ONE (current page ancestor)
- CHILDA (current page parent)
- - GRANDCHILD (current page item)
- CHILDB
- CHILDC
TWO
THREE

Alright, so here’s the CSS to make this happen:

#menu ul li ul {
	display: none;
}
#menu ul li.current_page_ancestor ul {
	display: block;
}
#menu ul li.current_page_ancestor ul li ul {
	display: none;
}
#menu ul li.current_page_ancestor ul li.current_page_parent ul {
	display: block;
}
#menu ul li.current_page_parent ul li.current_page_item ul {
	display: block;
}
#menu ul li.current_page_parent ul li.current_page_item ul li ul {
	display: none;
}
#menu ul li.current_page_item ul {
	display: block;
}
#menu ul li.current_page_item ul li ul {
	display: none;
}