feedback
Jan 26 2010

Optimizing CSS with Base64 Embedded Images (with Bonus Utility!)

by John Dyer

 

As I design a new site (current site | early demo of new site), I am working through what combination of technologies (CDN, sprites, caching, gzipping, etc.) we want to use to optimize it. One tool I’m looking at is embedding images in CSS with base64 strings. Instead of the browser needing to make several calls, one for the CSS file and then one for each image, base64 embedding means that all of the images are embedded within the CSS file itself.

It’s great for small images or images that only show up on :hover or mouseover and you don't want there to be any delay in the image appearing. Here’s what it looks like:

Normal CSS

.myclass {
width: 45px;
background: transparent url(myimage.jpg) top left no-repeat;
}

CSS with Base64 Embedded Image

.myclass {
width: 45px;
background: transparent url(data:image/png;base64,LONG-STRING-OF-BASE64-TEXT) top left no-repeat;
}

Problems with Base64

  1. Works in all browsers except IE6 and IE7. Solution: use a conditional comments to give IE6/7 a stylesheet that still references the images.
  2. Base64 is bigger than real images: In my tests a base64 encoded string image is somewhere around 150% the size of a regular image. This means it’s unusable for large images.
  3. Hard to manage: If you change the image, you’ll need to reembed the base64 string. You also have to maitain a separate IE stylesheet.

How to manage it

To help figure out which images were worth embedded and help manage it, I developed a small utility that analyzes a CSS file and allows you to select which images you want to embed. You can also preselect them by adding a comment somewhere within your CSS declaration that says /*embed*/

What It Does

  • Finds all image URLs in your CSS file (note: no CSS3 multiples or borders)
  • Shows the size difference between the image and the base64 string
  • Shows the final size output size and the GZipped size for comparison to the original
  • Removes comments and whitespace if you want
  • Creates a new base64 stylesheet and a IE6/7 stylesheet with references to the original image

Download

Nov 19 2009

Refactoring the JavaScript Color Picker - Step 1: Clean up the HTML and CSS

by John Dyer

On of the most popular posts on this blog was a color picker (demo) I created about 4 years ago and then released 2 years ago. It was based on the Prototype library which at the time was the only major mega-JavaScript library. Since then, others have ported the color picker to jQuery, MooTools, YUI, and other libraries, and it's popularity can be seen by searching for "javascript color picker" on Google.

The Original Color Picker (mimics Photoshop)

Color Picker Example

Rebuilding Goals

If the original color picker was popular, it was because of it's functionality, not so much pretty code. So, I'd like to rebuild the color picker with a few goals in mind:

  1. Be library independent - I'll have to add a little bit of extra code for things like event management, but this will allow it to work for everyone.
  2. Small and fast - The original JavaScript isn't too slow, but the color picker uses lots of separate images (27!). Originally, I hid these inside a <div> so that the browser would keep them cached, but I'd like to combine them into a few sprites to speed up the load time.
  3. Clean up the HTML/CSS - The original has a lot of inline styles and unnecessary complexity, making it ugly and unwieldy.
  4. Clean up the JavaScript - The original code separated out some functionality which makes it harder to figure out what's going on. I plan bring these together, so that I have one class for color conversion, one class for slider functionality, and one class for the color picker. The new code will also include code to function as a plugin to the major existing libraries (jQuery, Prototype, Mootools, YUI, etc.).

The first big step is to clean up the HTML and CSS. To get a feel for the old HTML/CSS, check out the version 1 example page. Here's what I've come up with so far:

Color Picker CSS

.color-picker
    { border: 0; padding: 0; margin: 0; font-family: Tahoma; font-size: 12px;}
.color-picker table, .color-picker td
    { border: 0; margin: 0; padding: 0; vertical-align: top;}   
.color-picker label
    { margin: 4px 0; display: block;}
.cp-container
    { position: relative; float: left; border: solid 1px #000; padding: 0px; }
.cp-layer1, .cp-layer2, .cp-layer3, .cp-layer4
    { display: block; position: absolute; top: 0px; left: 0px; }   
.cp-map
    { width: 256px; height: 256px; margin: 0px; }
.cp-map div
    { width: 256px; height: 256px; position: absolute; top: 0; left: 0; background: transparent url(maps.png) 0px 0px no-repeat;}
.cp-bar
    { width: 20px; height: 256px; margin: 0px 9px;}
.cp-bar div
    { width: 20px; height: 256px; position: absolute; top: 0; left: 0; background: transparent url(bars.png) 0px 0px no-repeat;}
.cp-preview
    { width: 60px; height: 60px; padding: 0px; margin: 0px; border: solid 1px #000; }
.cp-hsv, .cp-rgb
    { width: 40px; }
.cp-hex
    { width: 55px; }
.cp-map-arrow
    { background: transparent url(map-arrow.gif) 0px 0px no-repeat; width: 40px; height: 9px; position: absolute;}
.cp-bar-arrow
    { background: transparent url(bar-arrow.gif) 0px 0px no-repeat; width: 15px; height: 15px; position: absolute;}

Color Picker HTML

<div id="cp1" class="color-picker">
    <table cellpadding="0">
    <tbody><tr>
        <td>
            <div class="cp-container cp-map">
                <div class="cp-layer1"></div>
                <div class="cp-layer2"></div>       
            </div>
        </td>
        <td>
            <div class="cp-container cp-bar">
                <div class="cp-layer1"></div>
                <div class="cp-layer2"></div>
                <div class="cp-layer3"></div>
                <div class="cp-layer4"></div>                   
            </div>
        </td>
        <td valign="top">
            <table><tbody>
            <tr>
                <td colspan="3">
                    <div class="cp-preview"></div>
                </td>
            </tr>
            <tr>
                <td><input type="radio" /></td>
                <td><label>H:</label></td>
                <td><input class="cp-hsv" type="text" /> &#176;</td>
            </tr>
            <tr>
                <td><input type="radio" /></td>
                <td><label>S:</label></td>
                <td><input class="cp-hsv" type="text" /> %</td>
            </tr>
            <tr>
                <td><input type="radio" /></td>
                <td><label>B:</label></td>
                <td><input class="cp-hsv" type="text" /> %</td>
            </tr>
            <tr>
                <td><input type="radio" /></td>
                <td><label>R:</label></td>
                <td><input class="cp-rgb" type="text" /></td>
            </tr>
            <tr>
                <td><input type="radio" /></td>
                <td><label>G:</label></td>
                <td><input class="cp-rgb" type="text" /></td>
            </tr>
            <tr>
                <td><input type="radio" /></td>
                <td><label>B:</label></td>
                <td><input class="cp-rgb" type="text" /></td>
            </tr>
            <tr>
                <td>#</td>
                <td colspan="2">
                    <input class="cp-hex" type="text" />
                </td>
            </tr>
        </tbody></table>
        </td>
    </tr></tbody>
    <div class="cp-map-arrow"></div>
    <div class="cp-slider-arrow"></div>
</div>

Cleanup Comments

To make it more readable, I've removed all the id attributes except for the single id on the containing div, taken out all inline styles, and moved the CSS to a separate file. I also changed the layers to <div> tags with background images instead of <img> tags. This may present some problems with IE6 opacity down the road, so I might need to change it back. I've also removed z-index values from the CSS to prevent problems with other JavaScript controls on the page. I was not careful with DOCTYPE in the past, but the new HTML and CSS should work in any DOCTYPE (I'll be using the HTML5 DOCTYPE in all the examples). Finally, the arrows are created using <div> that are inside the main block, which will make it easer to show and hide the entire color picker.

Bar Sprite

As a preview, I'm including the sprite for the value bar of the color picker. This combines 14 different bars into one 1.77KB file. Next time, we'll talk about memory consumption and sprites and see if the sprite usage is actually helpful.

new color bars sprite

Jul 21 2009

HTML5 (XHTML5) Validation Schema and Intellisense for Visual Studio 2008

by John Dyer

I've been playing around with HTML5 (nice intro at Smashing Magazine) for a side project, and I wanted Visual Studio 2008 to stop telling me the new elements were not valid. So I created a new Validation Schema for Visual Studio 2008 that implements much of the HTML5 spec. I found some hints on how to do this in Visual Studio 2005 and went from there. Here's a pic of it in action giving you the attributes of of the new <source> tag under a new <video> tag:

Readme.txt

  • There is a lot of confusion about HTML, XHTML, and mime-types. I've chose to go with a stricter XML-like syntax of closed tags and quoted attributes, rather than the looser HTML, so I called it "XHTML 5" although that doesn't really make it offically XHTML 5 until you do the rest of the research, work, and fun.
  • This is not a 100% perfect implementation. There are bound to be different interpretations of what's "correct" HTML5 and you have until 2022 to get it right, so please don't worry about it too much.

What's Finished

  • All the new elements in HTML5 have been added in the follow groupings
    • structure: article, aside, footer, header, nav, section
    • media: audio, video, source
    • other: bb, canvas, command, datagrid, datalist, details, dialog, eventsource, figure, hgroup, keygen, mark, menu, meter, output, progress, time
  • When new elements have custom attributes (such as height and width for video, I've tried to add those)
  • I've also changed a few things like not requiring the type attribute on script blocks and allowing meta tags to have a charset attribute
  • I've begun adding HTML5 events (ondrag, onplay, etc.) but have not completed all of them
  • I am not sure how to add HTML5 style data- attributes, so those won't validate yet.

How to Use it

  1. Download XHTML Validation Schema for Visual Studio 2008
  2. Save it to C:\Program Files\Microsoft Visual Studio 9.0\Common7\Packages\schemas\html\
  3. Add the following to the Registry:
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Packages\{1B437D20-F8FE-11D2-A6AE-00104BCC7269}\Schemas\Schema 23]
    "Friendly Name"="XHTML 5"
    "URI"="http://schemas.microsoft.com/intellisense/xhtml5"
    "File"="html\\xhtml5.xsd"

    Note that you might need to change "Schema 23" to something else if you already have other non-default schemas installed. You just need to use the next available number in the list.

I hope you find it helpful. Please let me know if you end up using it and feel free to suggest updates or corrections.

Mar 11 2009

MVC Edit View Template Upgrades

by John Dyer

I’m building a new LMS using ASP.NET MVC and I am making heavy use of the View templates added in RC1. (see: T4 Templates: A Quick-Start Guide for ASP.NET MVC Developers)

I made a few changes to the default template to allow (1) table rows and cells instead of <p> tags, (2)add spaced to “ProperyName” so it looks like “Property Name”, and (3) use reflection to determine the <input> type generated by the Html helper. For all string Properties, a normal <input type=”text” /> is still generated, but for Int32, I am generating a <select> and for Booleans, a <input type=”checkbox” /> since these are the normal fields I use for forms.

For an object that looks like this

public class Person {
public string FullName { get; set; }
public bool IsActive { get; set; }
}

The default Edit View looks like this:

<p>
<label for="FullName">FullName:</label>
<%= Html.TextBox("FullName") %>
<%= Html.ValidationMessage("FullName", "*") %>
</p>
<p>
<label for="CampusID">IsActive:</label>
<%= Html.TextBox("IsActive") %>
<%= Html.ValidationMessage("IsActive", "*") %>
</p>

Here's what I wanted the Edit View to look like:

<tr>
<td class="form-title"><label for="FullName">Full Name</label></td>
<td class="form-input"><%= Html.TextBox("FullName") %></td>
<td class="form-val"><%= Html.ValidationMessage("FullName", "*") %></td>
</tr>
<tr>
<td class="form-title"><label for="Password">Is Active</label></td>
<td class="form-input"><%= Html.CheckBox("IsActive") %></td>
<td class="form-val"><%= Html.ValidationMessage("IsActive", "*") %></td>
</tr>

Here’s how I handled the different property types

Property Type Html Helper Output
String (and others) Html.TextBox <input type="text" />
Boolean Html.CheckBox <input type="checkbox" />
Int32 Html.DropDownList <select>

You can modify this easily in the code below to put whatever controls you want for each property type. To use the template, just create a folder in your project called CodeTemplates\AddView:

image

Here is my are the parts of Edit.tt file that I updated:

<#
    
if(!String.IsNullOrEmpty(mvcHost.ViewDataTypeGenericString)) {
List<PropertyInfo> properties = new List<PropertyInfo>();
FilterProperties(mvcHost.ViewDataType, properties);
#>
<%= Html.ValidationSummary() %> <% using (Html.BeginForm()) {%>


<table class="form-admin">
<#
foreach(PropertyInfo pi in properties) {
#>
<tr>
<td class="form-title"><label for="<#= pi.Name #>"><#= FormatLabel(pi.Name) #></label></td>
<td class="form-input"><%= Html.<#= GetInputType(pi) #>("<#= pi.Name #>") %></td>
<td class="form-val"><%= Html.ValidationMessage("<#= pi.Name #>", "*") %></td>
</tr>
<#
}
#>
</table>
<input type="submit" value="Save" />
<% } %>


<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>
<#+
public string FormatLabel(string label) {
return System.Text.RegularExpressions.Regex.Replace(label, "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", "$1 ");
}


public string GetInputType(PropertyInfo pi) {
switch (pi.PropertyType.ToString()) {
case "System.Int32":
case "System.Int64":
return "DropDownList";
case "System.Boolean":
return "CheckBox";
case "System.String":
default:
return "TextBox";
}
}



public void FilterProperties(Type type, List<PropertyInfo> properties) { if(type != null) {
PropertyInfo[] publicProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);


foreach (PropertyInfo pi in publicProperties)
{
if (IsBindableType(pi.PropertyType) && pi.CanRead && pi.CanWrite)
{
properties.Add(pi);
}
}
}
}
#>

Hope this is helpful to you!

Feb 20 2009

iTunesU Manager App Source Released

by John Dyer

A while back, I created an iTunesU Manager application for DTS's iTunesU site, and I finally got around to putting up the source code and executables. Below is a screenshot of the app and links to the Google code repository. The app requires .NET 2.0 (it's written in C#) and an iTunesU administrative account.

iTunesU Manager
Jan 16 2009

Nested Comments for BlogEngine.NET

by John Dyer

There are some great changes coming for BlogEngine.NET 1.5.0.0, and one of them is nested comments! I checked in the changes to Codeplex just last night, and I’ve implemented them here as a demo while we hammer out the final details.

Nested (or threaded) comments have been added to a lot of blog platforms lately (including WordPress 2.7), and it is a major feature of comment plugins like Disqus and Intense Debate. I personally think threaded comments make longer posts with lots of comments make a lot more sense.

Here’s an example of how a the comments in a recent post of mine make a lot more sense after turning on nesting. Since I responded in bursts to comments, they were out of order, but with nesting you can see that my comment (in dark brown) are now contextually nested and make much more sense. (Note: To make this work, I had to go back and manually add the “parentid” attribute to my comments to make them nested.)

Before (not nested)

After (nested)

Not nested Not Nested

 

If you want to try it out, you can try it on this post or download the latest check-in from Codeplex. Just be warned that this isn’t the final release. There may be some quirks in the JavaScript.

To add nesting to your existing themes, you’ll need to add the following code (marked by HTML comments) from the Standard Theme:

<div id="id_<%=Comment.Id %>" class="vcard comment<%= Post.Author.Equals(Comment.Author, StringComparison.OrdinalIgnoreCase) ? " self" : "" %>">
<p class="date"><%= Comment.DateCreated %> <a href="#id_<%=Comment.Id %>">#</a></p>
<p class="gravatar"><%= Gravatar(80)%></p>
<p class="content"><%= Text %></p>
<p class="author"> <%= Comment.Website != null ? "<a href=\"" + Comment.Website + "\" class=\"url fn\">" + Comment.Author + "</a>" : "<span class=\"fn\">" +Comment.Author + "</span>" %>
<%= Flag %>
<%= ((BlogEngine.Core.BlogSettings.Instance.IsCommentNestingEnabled && Comment.IsApproved) ? " | " : "") %>
<%= ReplyToLink %> <!—- add this for reply to links –>
<%= AdminLinks %>
</p> </div>
<!—- Start: threading –>
<div class="comment-replies" id="replies_<%=Comment.Id %>" <%= (Comment.Comments.Count == 0) ? " style=\"display:none;\"" : "" %>>
<asp:PlaceHolder ID="phSubComments" runat="server" />
</div>
<!—- End: threading –>

Hope you like it, and let me know if you implement it on your site!

Dec 8 2008

Everyone’s Going “HD” (Sort of)

by John Dyer

Last week, YouTube made big news by introducing “HD” video, thought it’s unclear what YouTube’s definition of “HD” is. The video is certainly higher definition, but it’s certainly not 720p or 1080p which is technically what HD is supposed to be. It might be 480p which is what Hulu.com does for their high quality streams (and is also what the Wii ouputs).

At DTS, we also recently revamped our videos to be “HD” (in the higher definition sense), moving to 480p in most cases.

We’ve also changed the player quite a bit. The old player had a lot of “chrome” around it and this new one is chromeless (ala Vimeo) and has the option to popout (similar to Hulu). Compare the old player below, with the new player showing two recent profiles, one of an alumnus and the other of a currents student who is also an NFL player.

Old player

image

New Embedded Player Samples

Some Technical Information

This player needed to be able to play both MP4s for video and MP3s for audio. Unfortunately, Flash’s built-in video controls like PlayButton and Seekbar only work for video, and there is no way to use them for audio. I wrote a some wrapper classes that can handle both MP4/FLVs and MP3s and normalizes the event model so they can both be hooked to the same control UI. If we move back to streaming it should be easy to write another class for that and have it all “just work.”

If anyone is interested in the source code, I’d be happy to publish it as an example of a Flash IDE AS3 video player that can also handle MP3s.

Dec 8 2008

Technology Blog

by John Dyer

I would like to keep this blog focused on technical developments and code samples, but a few recent posts have been showing I am growing in my interest for the philosophy behind technology. To keep the two interests separate, I’ve started a separate blog called

www.donteatthefruit.com

It will be aimed at discussing the influence of technology on society and human relationships. Right now, I’m looking at Neil Postman’s “Five Things You Need to Know about Technological Change” as related to churches.

Stay tuned to this blog for more technical developments!

Dec 2 2008

PNG transparency in IE6 (without JavaScript)

by John Dyer

As most of us know IE6 does not support PNGs with alpha transparency. We recently updated DTS’s site with some popups that have a drop shadow using PNG-24 images with alpha transparency. Here’s how it looks in IE6 compared to any modern browser (FF, IE7, Opera, Safari, Chrome, etc.). Notice the nasty blue border.

PNG-32 (problems in IE6)

IE6
image

Correct Display
image

I wish we could ignore IE6 users, but around 20% of our traffic still hasn’t upgraded, so we have to make it work for them. There are tons of JavaScript and CSS hacks out there to get IE6 to display PNGs with alpha transparency correctly, but we’re trying to avoid hacks whenever possible so as to not break things in the future. Also IE6’s filter technology can cause other problems. To fix this, I found a sweet “non-hack” solution on sitepoint which recommends using PNG-8 instead of PNG-24.

To summarize the article on PNG-8 and PNG-32.

PNG-32 PNG-8
16.7 million colors (like a JPEG) 256 colors (like a GIF)
alpha transparency, not just indexed (like GIF) alpha transparency (just like PNG-32)
doesn’t work in IE6 works in IE6 like a GIF (indexed transparency)

 

PNG-8 with alpha transparency (IE6 works, pretty much)

Here’s what the PNG8 looks like in IE6 on our site. Notice that the drop shadow is missing, but the transparency still remains.

IE6
 image

Correct Display
image

Everything “works” for IE6 users even thought it’s a slightly downgraded experience since the shadow is missing. For us, this is preferable to using JavaScript or CSS hacks that could cause other problems with animation. Since this is a image that only needs 256 colors, the PNG-8 is the perfect solution that is win-win-win.

How to make Alpha PNG-8 Images

The problem with all of this is that there is only one program that can make this specific kind of PNG-8 – Adobe Fireworks. Photoshop can’t do it, and I’m not sure if any other graphics programs can either. Here’s a step by step for making the PNG-8

1. Open the PNG-32 (or photoshop file)

image

2. Change the Image Type to “PNG 8”

image

3. Change to “Alpha Transparency”, then click the “Rebuild” button

Now you will see the new color palette with alpha colors. IE6 will only display the solid colors, not the fully transparent (upper left) or semi-transparent (the three with inset clear boxes).

image 

image

4. Chose File-Export to save the PNG-8

image

And that’s it. It takes a little more time but has made our development easier and provides a more stable experience for users.

Sources

Sep 15 2008

Wii + Flash + Papervision3D + C# = Alumni World Map

by John Dyer

The 2008 class gift for Dallas Seminary is supposed to be a large flat screen with a 3D world that shows where in the world DTS alumni are serving. The requirements were:

  1. The target OS is still unknown and I haven't done much native Windows or Mac 3D programming. This leads me to use Papervision in Flash which I know and is very easy to use.
  2. The data needs to be easily updatable. Rather than use a database, I built a flat file using a quick C# app that plots alumni by state and country and geocodes their location.
  3. At DTS, the Admissions and Alumni offices are nearby, so the application needs to be interesting to Admissions. Ever since my sweet wife got me a Nintendo Wii a few months ago, I've wanted an excuse to program with it. For this project I thought, What's more fun and interesting than controlling the globe with a Nintendo Wii controller?

Video Demo

Here is a (low quality) video of an early version of the project that gives you an idea of what it's supposed to accomplish and look like. The first few seconds use mouse navigation, then it switches to WiiMote navigation.

wiiflashworld
This video requires Adobe Flash player

Live Demo

To see a live demo, click the following image. If you want to control using a WiiMote, do the following. (1) connect your WiiMote to a PC via bluetooth. (2) Download the WiiFlash 0.4 package (3) run the included WiiFlash Server, (4) refresh the demo page page, (5) click the "Home" button the WiiMote to toggle controlling via mouse or WiiMote.

Alumni World Globe

 

Libraries Used

All the tools for this project have been around for almost a year, so nothing is particularly cutting edge, but the mashup and purpose are pretty unique and really fun. Hopefully, playing with the WiiMote will be as fun as actually viewing the map, making the entire experience for prospective students really positive.

Aug 20 2008

Papervision3D Bookshelf

by John Dyer

I recently completed a website that catalogs books and in the development I wanted to make something really new. The backend is all ASP.NET, implementing UrlRewriter.NET and AJAX.NET libraries. The frontend uses several JavaScript libraries including Prototype, Scriptaculous, and Tablesort.

The one really unique feature of the site is the 3D bookshelf built using Papervision3D. Just yesterday it was featured in blog Daily PV3D as Papervision showcase.

You can check out the book shelf here:

http://www.bestcommentaries.com/category/proverbs/

Screenshots

Plain bookshelf:

image

Mouse over the third book from the left:

image 

Book clicked:

image

How it works

Using Papervision, it's relatively easy to make a 6 sided polygon (cube) and then wrap images around it. I use the physical dimensions of the actual book to size the cube. Then, for the cover, I use an image of the book and wrap the last pixel around the side since I don't have spin images. I tried using System.Drawing code to write the author's name on the spine, but I could never get it to look just right, so I left it out. The only real catch was that I needed to place the shelf on a different Papervision scene to prevent clipping problems. The bookshelf also interacts with an HTML table down below via Flash's JavaScript ExternalInterface.

Since developing this 3D bookshelf, I found one site that does something somewhat similar, but they have the spine images which I can't afford to find for 1000s of books. Also, I think that the JavaScript interaction on mine might give it an edge.

Aug 18 2008

Podcast on Technology

by John Dyer

A few weeks ago, I was invited to speak on a podcast with the best possible name of all time:

www.pontificast.com

image

Joey and Ryan (two smart, funny, creative guys) had me on for three episodes to discuss the effect of technology on people. I've been reading quite a few books and articles in this area lately, and concurrently such considerations have begun to move out of the academy and into the mainstream with articles such as Nicholas Carr's article "Is Google Making Us Stupid?"

Here are links to the three episodes:

Hope you enjoy!

Jul 22 2008

Show Commenter's Latest Post: BlogEngine.NET Extension

by John Dyer

Background

Over the past few weeks, I've seen a few WordPress blogs that pull in the last post from a commenter's website. I also saw a post from Mads about how to find semantic links on a webpage.

So, I mashed his code together with some code from the BlogRoll control and created an extension that goes out and looks for RSS feeds at the commenter's website and then pulls in the latest post. [side note: I wish I could say, "a half hour later ... ", but it actually took me a while to get it to work...]

It all happens asynchronously, so if you comment on this post, it'll take a few seconds for it to show up. Then it will keep checking every so often for new posts.

Example

Last year, I posted a JavaScript color picker and the post now has over 100 comments. Here's what it looks like with the extension running:

 Comments with Recent Posts

Download & Installation

  • Download Commenter's Latest Post Extension
  • The last post is wrapped in the following class so you can style it:
    <span class="commenterslastpost"></span>
  • Sometimes the ResolveLinks extension interferes with this, so you might want to add the following code around the foreach loop:
    if (e.Body.IndexOf("href=\"" + match.Value + "\"") == -1) { ... }

Add a comment to this post to see it in action...

Jul 18 2008

iTunesU Site Utility in C# (.NET)

by John Dyer

In the process of moving Dallas Seminary's content to iTunesU, I created a very simple application to edit site details via the Web Service API. It currently has the following functions:

  • Add/Edit/Delete Sections
  • Add/Edit/Delete Courses
  • Add/Edit/Delete Groups
  • Upload/Edit/Delete Tracks

There are a lot of things it doesn't do, like let you edit themes or add images to courses, but it is really helping us get started. Here's a screenshot:image

You just enter your shared secret and domain name, press "Load Site Tree" and then right click on the various items to add/edit/delete.

And here's what it looks like in iTunes.image

Download & Installation

Links

  • iTunesU Support Site - Here's where I started
  • iTunesU Java Library - this is much more fully featured and documented than my code.
  • Woolamaloo - Rich Wolf's Mac tool which is much more fully featured than this tool. He also has a Windows app, but as far as I can tell it only lets you login.

My source code is very rough, but it someone needs it, I'm happy to provide it. Also, our iTunes U site is not yet public, but it will be in a few weeks.

Jul 17 2008

Programming History

by John Dyer

From Keyvan Nayyari and Janko to Mads Kristensen and now to me comes a challenge to tell how I got into programming...

How old were you when you started programming?

I think I was around 14 or 15.

How did you get started in programming?

My friend and I made text adventure games.

What was your first language?

It was some form of BASIC.

What was the first real program you wrote?

By "text adventure game", I really mean lame spaghetti-coded ASCII choose your own adventure "games." My friend had most of the funny ideas and I did most of the programming. He's now in a crazy band in Austin, TX called Natchet Taylor, and I work at a seminary!

What languages have you used since?

ASP, PHP, C#, ActionScript, SQL, X/HTML, JavaScript, CSS, and all the rest...

What was your first professional programming gig?

When I graduated from college, I took a job as a youth pastor. I needed extra cash, so I got a job as as ASP programmer for http://www.texags.com/. At that point, all I had really done was build a personal webpage in college (with animated flaming gifs!), so I just learned everything on the job. It was great fun. In those days, I'd write everything for IE, and then fix it for Netscape. Funny how things change.

If you knew then what you know now, would you have started programming?

Totally. There's always good work, and it really frees me up to be anywhere. I've made it through an entire masters degree since I could work whenever and wherever, and still be involved with friends and in ministry.

What is the one thing you would tell new developers?

I'll cheat and go with two:

  1. Always, always, always have a signed contract with everything spelled out in detail and a 25-50% payment before writing a single line of code.
  2. Release as much code as you can (to a blog or whatever). If your code is worth publishing, it means you probably did a good job, and would be something you won't hate to go back and modify later.

What’s the most fun you’ve ever had … programming?

I would have to say programming online education stuff with foreign language support. I have no idea what any of it says, but it's really fun to develop stuff that is used in a home in Dallas, a tent in the deserts of Iraq, in the Packers lockerroom, and in an underground church in China - and all of it not just to make a buck, but to make a difference in the world. That's rock-star coding.

Okay, I'm passing this on to Nathan Smith, Chris Merritt, and John Saddington. Have fun guys.

Web Statistics