Dead Ink Vinyl

Musings of David L Kinney

Archive for July 2008

Rules for Flash Indexing

I’ve been thinking a lot about the Ryan Stewart’s Flex SEO contest (also known as the “Fleximagically Searchable” contest). As I posted earlier, I believe the best and correct method for “making Flash indexable” is not to index Flash at all, but rather to index the data. I spent a lot of time thinking about how I could get Google to index my content but link to my Flex application and I finally found a mechanism to do this! However, upon very close reading of Ryan’s rules I see that he specifically does not want this solution—he wants the content to be indexed by Googlebot “interacting” with the application.

That’s just silly.

For data-driven sites—which would be most Web sites with Flex front-ends—this is an completely artificial restriction. The only place where this would make any sense is for applications that do not dynamically load content, but rather dynamically generate content, such as for client-side mash-ups. Additionally, according to Google “if your Flash file loads an HTML file, an XML file, another SWF file, etc., Google will separately index that resource, but it will not yet be considered to be part of the content in your Flash file.” That implies that dynamically loaded content must be RPC-based (and binary?) to be considered part of your SWF (as Ryan Stewart desires) instead of a separate resource. Yuck!

I will continue with my planned solution because demonstrating the technique and learning how well it works for SEO will provide valuable information for the community.

Finally, I’d like to announce that I’ve purchased the domain fleximagicallysearchable.com for this contest1. There is nothing there now, but I would like to turn it into a blog or user forum for discussing Flex SEO strategies and make it a resource that lives beyond this contest, continuing to be useful in the future by providing tutorials and covering the emerging best practices for Flash and Flex SEO.

1 Not to be confused with fleximagically-searchable.com, which is owned by zedia.net.

Written by dlkinney

July 14, 2008 at 11:33 pm

CouchDB on MacOSX Leopard

I got CouchDB up and running as a service on my MBP OSX Leopard this past Monday. It wasn’t as straight-forward as I’d hoped, so I thought I’d share my process for the benefit of others.

Installing CouchDB

I installed CouchDB from source. This requires the Leopard development tools (Xcode) and MacPorts. I expect all developers to have Xcode installed and most developers to have MacPorts installed, so I won’t detail those steps here.

First, install CouchDB’s dependencies using MacPorts:

sudo port install icu erlang spidermonkey

Download CouchDB and extract it. This is standard configure, make, make install territory here:

./configure
make && sudo make install

Wasn’t that easy?

Creating a couchdb System Account

Find a user number that is available. To see a list of what numbers are already in use, run:

dscl . -list /Users UniqueID | awk '{print $2}' | sort -n

Now find a group number that is available. To see a list of what numbers are already in use, run:

dscl . -list /Groups PrimaryGroupID | awk '{print $2}' | sort -n

On my system, number 103 was available for both a user number and a group number. The rest of this article assumes you are using 103 as well.

The following commands create the group and the user and set the user’s home directory to the CouchDB lib folder.

sudo dseditgroup -o create -i 103 -r "CouchDB Users" couchdb
sudu dscl . -create /Users/couchdb
sudu dscl . -create /Users/couchdb UniqueID 103
sudu dscl . -create /Users/couchdb UserShell /bin/bash
sudu dscl . -create /Users/couchdb RealName "CouchDB Administrator"
sudu dscl . -create /Users/couchdb NFSHomeDirectory \
        /usr/local/var/lib/couchdb
sudu dscl . -create /Users/couchdb PrimaryGroupID 103
sudu dscl . -create /Users/couchdb Password *

Finally, we give the couchdb user ownership of the CouchDB lib and log directories:

sudo chown -R couchdb:couchdb /usr/local/var/<strong>lib</strong>/couchdb
sudo chown -R couchdb:couchdb /usr/local/var/<strong>log</strong>/couchdb

DONE! Now you can launch CouchDB as the couchdb user instead of root.

sudo -u couchdb couchdb

Running as a Service

To control CouchDB using launchctl, I needed to add the appropriate PATH information to CouchDB’s Launch Daemon plist so that gawk is found. Unfortunately, I couldn’t find a solution to edit the plist in-place as a privileged user, so I copied the file to the /var/tmp directory without root privileges so that I could update the copy.

Creating a copy of the plist and opening it for editing is done by:

cp /usr/local/Library/LaunchDaemons/org.apache.couchdb.plist \
        /var/tmp/org.apache.couchdb.plist
open /var/tmp/org.apache.couchdb.plist

In the Property List Editor that opens, follow this steps:

  1. Open Root → EnvironmentVariables
  2. Click on Add Child
  3. Name: PATH
  4. Value: /bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/opt/local/bin:/opt/local/sbin
  5. File → Save
  6. Quit Property List Editor

Then copy the updated plist over the original plist:

sudo cp /var/tmp/org.apache.couchdb.plist \
        /usr/local/Library/LaunchDaemons/org.apache.couchdb.plist 

Now CouchDB can be controlled and monitored by the standard Leopard daemon manager:

sudo launchctl load \
        /usr/local/Library/LaunchDaemons/org.apache.couchdb.plist 

Launch CouchDB on Startup

To automatically launch on start up, run

sudo ln -s /usr/local/Library/LaunchDaemons/org.apache.couchdb.plist \
        /Library/LaunchDaemons/org.apache.couchdb.plist

Congratulations! You have CouchDB running as a system service that will start when you boot your Mac. Let the fun commence.

I’d Like to Thank the Academy…

I’d like to thank the following sites and resources for providing me enough information to piece together the process:

I particularly recommend the evang.eli.st article, as it explains the dscl command, which may be an unfamiliar account management tool.

I should point out that evang.eli.st also has a complete write-up on how to install CouchDB on OSX. That walk-through is almost a year old, though, and entails editing the Makefile—which doesn’t sit well with me. However, where Leopard departs from standard UNIX behavior, I cease being an aficionado, so his tweaks may be important in ways I haven’t yet discovered.

Written by dlkinney

July 12, 2008 at 9:39 pm

A Thought About Flash Indexing

It seems to me that thinking about the problem as “indexing Flash” is to approach the matter backward. We want the data to be indexed—the presentation is irrelevant. Take this blog as an example. It’s database-driven and generates documents with my content—these words you’re reading now—wrapped inside of some HTML garnish to make the reading experience pleasant. If you’re reading this in a feed reader, then the content is wrapped in Atom or RSS garnish. Do I care what garnish surrounds my content? Not particularly.

The same principle holds true for other Web applications, whether the garnish is Ajax, Flash, Flex, Silverlight, or—like this blog—good old fashioned dynamically generated HTML. It is the data that must be indexed, the presentation around that data is (conceptually) irrelevant for SEO purposes. I think the matter may be confused because for so long the data and the presentation were bundled together in HTML (like this blog). Now with Ajax and Flash/Flex, we are back to separating the user interface from the data. However, when the data isn’t part of the user interface document sent by the server, it’s harder for search engines to access and index.

So what’s the solution? Expose the data for indexing and detect when incoming links should launch the Flash/Flex app instead of responding with the raw information. Naturally, the Flash/Flex app would be launched to deep-linked directly to the relevant content. If you’re not sure how to make the data indexable, I’ll tell you that I take my guidance from RESTful Web Services. The magic in this solution is detecting when an incoming link should launch a deep-linked Flex application and when it should render the raw data. For the moment, I’ll punt on detailing an implementation—consider it to be an exercise for the reader.

An exercise for the reader that can lead to rich rewards! Ryan Stewart has announced the Flex SEO Contest to encourage the community to establish best practices for Flash/Flex indexing. The rules are straightforward and the top prize is CS4 Master Collection. I like the challenge and may try my hand creating an entry that meets the contest criteria just for the experience of it.

Written by dlkinney

July 8, 2008 at 12:14 pm