feedback
Mar 3 2010

Purple CMS - Super Early Alpha (0.1)

by John Dyer

A few years ago, I built a CMS for Dallas Theological Seminary that has served us pretty well. It has some features we really wanted, but to get them I had to hack up the ASP.NET 2.0 page life cycle to get it to work. With ASP.NET 4.0, a lot of what I did is much easier and can be done "normally" instead of with things that felt like hacks. 

Project Requirements

Different projects require different kinds of CMS packages, but here were my requirements:

  • Extensionless URLs (no .aspx on the end of URLs) - this was harder in ASP.NET 2.0, but in ASP.NET 4.0 especially on IIS7 this is much easier.
  • Normal Masterpages - I don't want a special, proprietary template engine. I just want to use normal ASP.NET features so that people can work on the site without learning an new language and use Visual Studio if they want.
  • WebForms and *.ascx Controls - I love using MVC on certain projects, but for a site with lots of pages (DTS has around 1000 pages), I need to be able to use simple *.ascx controls. We have lots of pages with various repeaters and forms to fill out and using MVC controllers for each it too much to maintain. Personally I like <script runat="server"> rather than codebehind or codebeside so we can keep a site agile.
  • Not require <form runat="server"> - A lot of pages with plain HTML or just a <asp:repeater> don't need viewstate, so there is no need to have ASP.NET form on every page. The CMS is smart enough to wrap content in <form runat="server"> if needed, but not otherwise.
  • No takeover - The CMS can't take over the entire site and not allow other normal ASP.NET functionality like pages (*.aspx) and handlers (*.ashx).
  • In page editing - This isn't really a requirement, but I like being able to edit a page in place rather than have to go to a separate admin area. 
    Click "edit" and then you go to:
  • Page versioning - Of course we need to be able to rollback to a previous version. Nothing too complex, just a list of revisions with dates.
  • XML or SQL - A nice CMS shouldn't have to use SQL for a 10 pages site. For now, XML is the default.
  • Permissions - We don't need a complex workflow, but we need to be able to specify a role for super admin and a role for users who can be assigned edit access to special pages. It needs to work with ASP.NET Membership and Roles.
  • Redirects - A small feature, but we use a lot of vanity URLs in print advertisements that need to go somewhere else (www.dts.edu/thm -> www.dts.edu/admissions/degrees/thm)
  • Complex URL handling - I also want to be able to create a page that has wildcard handling for all sub pages. For example, I want a page that lists a faculty (www.dts.edu/about/faculty) but can also handle and sub pages and show an individual faculty member (www.dts.edu/about/faculty/dbock). This also allows things like blogs or forums if someone wanted to make those.

Download Purple CMS 0.1

I've put up a very rough demo you can try out. The permissions, redirects, and "complex URL handling" are not yet finished in this build, but the main ability to use masterpages, controls, and edit pages with HTML is in the demo. It looks just like the default ASP.NET site and allows you to login and edit pages.

To use it, you'll need Visual Studio .NET 2010 RC and .NET 4.0 RC. Just unzip the file, run the solution, and hit "Debug" or point your local IIS to the website folder and select "ASP.NET 4.0" it's Application Pool.

Let me know what you think.

Feb 27 2010

Experimenting with Web SQL databases

by John Dyer

What is Web SQL?

Web SQL (http://www.w3.org/TR/webdatabase/) is proposed technology that allows a small SQL database to reside inside a browser. Instead of making AJAX calls back and forth from server to client whenever any information is needed, the data is stored locally in the browser so it can be quickly queried and used. Web SQL is not technically part of HTML5, but it is part of a group of technology suggestions for the future of the web.

Currently, Web SQL is only implemented in WebKit based browsers (Safari, Chrome, iPhone) and beta versions of Opera. Google Gears also had a local database implementation, but Google Gears is being discontinued in favor of HTML5.

How Does Web SQL Work?

HTML5 Doctor has a great article on using Web SQL, so I'll only repeat a small code sample.

 

// create/open database
var db = openDatabase('mydb', '1.0', 'my first database', 2 * 1024 * 1024);

// start transaction, create table, insert data
db.transaction(function (tx) {
  tx.executeSql('CREATE TABLE IF NOT EXISTS foo (id unique, text)');
  tx.executeSql('INSERT INTO foo (id, text) VALUES (1, "synergies")');
});

// query the data
db.transaction(function (tx) {
  tx.executeSql('SELECT * FROM foo', [], function (tx, results) {
    var len = results.rows.length, i;
    for (i = 0; i < len; i++) {
      alert(results.rows.item(i).text);
    }
  });
});

 

A Giant Web SQL example

Web SQL is great for small amounts of data. The Webkit team has a sample which creates and stores notes (http://webkit.org/demos/sticky-notes/index.html), while HTML5 doctor stores recent tweets (http://html5demos.com/database).

I wanted to load a lot more data to see what the performance would be, so I decided to load the entire Greek New Testament which is around 170,000 words along with its morphology information (part of speech, declension, etc.). It attempts to load entire books at a time and then allow you to pull up a chapter. You can also click on a word and see every time it is use in the Greek Bible. Once the database is loaded, you can come back to the site at any time and never have to reload the database. It will always be there in your browser. 

Try it out:

The Greek New Testament in Web SQL

Gotchas: The database is a little over 5MB which breaks the limit in Google Chrome. Safari will ask you if you want to increase the storage, but it will also stop the loading processing while it waits for the user to respond. If you use Safari, you can click the "Toggle DB Admin" then click "Delete all" and then "Load all" to clear out and then reload the entire database.

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...

Web Statistics