So last week I mentioned that after figuring out how to display comment counts on syndicated posts, the next hurdle was to figure out how to display the most recent comments across a whole collection of syndicated blogs/posts.
The dilemma lies in the fact that while there is an RSS feed for each post’s comments, that feed needs to be essentially “exploded” and then all of the exploded feeds need to be aggregated together in order to get a view of comments across all of the syndicated blogs. I wasn’t sure how we were going to do that within WordPress/FeedWordPress. As you can imagine, as the content for ds106 grows, there are more and more posts being aggregated. EACH of those posts has an associated comment feed, and each of those feeds could have any number of comments. Potentially, we could be talking about thousands of comments, in the end. That’s a big feed to both construct and parse.
On Tuesday it occurred to me that maybe I could tackle this in Yahoo! Pipes, so I took a stab at it and I’ve been sort of successful.
Here’s the pipe’s process:
Step One: Fetch the feed out of ds106.us. We’re already off to a tough start. Right now Jim is syndicating the last 600 posts on the blog. That’s so that as students joined the class this spring and subscribed to the feed, they could get a backlog of everything that had come before. Keep in mind that there are almost 900 syndicated posts on the site, and, um, we’re in the third week of class. So, I’m already not starting with everything on my plate. Theoretically, if you go leave a comment on the very first post that was syndicated into the site, I can’t capture any information about it.
But, we’ll forge ahead.
Step Two: I’m going to pull out one element of the feed: the wfw:commentRSS property which I’ve already determined is pretty universal (esp. on WordPress blogs) and contains the URL of the post’s comment feed.
Step Three: Now I’m going to run through a loop that basically fetches the data contained in those comment feeds that I just pulled out of the site feed. For some reason, I had to use this function on Yahoo! Pipes as opposed to the Fetch Feed function again. I don’t know why. I’m not that smart. Whatever it finds in those comment feeds is then emitted into a new feed.
Steps Four & Five: Now I have to do some kind of klugey stuff. I know I need to filter out items that are empty — I have empty items because not every comment feed has contents (because no one has commented on those posts yet). But for some reason, the Filter function in Yahoo! Pipes doesn’t work when I put in a regular expression to try and match, say, the item title to a null value. However, I can use the Regex function to replace a null item title with a string — in this case “XXX.” And then, I can filter out all of the titles that are equal to “XXX.” It’s stupid, but it works.
Step Six: Now I truncate the feed to the last 10 items, because that’s all I want to display on the course site in the sidebar (and I’m trying to limit the amount of parsing WordPress needs to do).
If I’m lucky, all the pieces fit together and I get a widget on the ds106 sidebar of the last 10 or so comments.
But sometimes, I just get a feed error. Probably because the whole thing is pretty intensive. So, now I ned to figure out if there is a better way. I’m thinking I need some way to cache this data as it’s compiled. I mean, it’s not going to be changing a lot and there’s no reason to repeat the parsing of every feed every time. But, I admit, I’m not sure what steps to try next.
Ultimately, I’d like to get this to a Yahoo! Pipe that we could clone anytime we’re running a course blog so that we can include recent comments all the time.
As always, ideas, thoughts, and reactions are welcome!!
So here’s something neat that I figured out how to do on Jim’s DS106 class (soon to be available on my own course site). As you may know, both sites are syndicating in feeds from students’ blogs using the amazing FeedWordPress plugin. We use this plugin all over UMW Blogs to allow faculty to manage course “mother” blogs into which students’ blogs are fed.
When we feed blogs using FWP, we almost always have the post on the mother blog link to the original posts on each individual blog. That’s a decision that reflects our belief that we need to encourage students to develop a sense of agency about their sites — each blog is not merely a cog in the greater course engine. Rather, it is a node that represents the real presence of a person in the class. We want readers of the course blog to make their way to the students’ blog and leave comments in that space — where each individual student can monitor and reply on his/her commenters.
However, one of the drawbacks has always been that on the course blog there is no way to witness the conversation that is developing around the posts that are syndicated into the site. Since the post on the course blog is never actually viewed or commented upon, the site always suggests that there are “No Comments” for the post — when, in actuality, if you click the link and go to the individual student’s blog, there may indeed be rich commentary there.
When DS106 was starting up, Jim mused that it would be very cool to finally crack this nut — how can we have information about the comments on each post trickle up into the course blog?
I decided to try and tackle this challenge this week, and, at first, I thought it was going to be fairly complicated. I know that in WordPress, at least, every post has an individual comment feed associated with it. But I wasn’t sure if the URL structure for those feeds would be easy to program. I’ve got the permalink for the post coming in when the post is syndicated, but depending on the permalink structure on the site, the actual feed URL may vary. In addition, not everyone in the class is using WordPress — how to handle folks in other systems?
I started by simply trying to solve the WordPress post comment challenge and leave the other systems for later. But, sure enough, when I simply tried to append what I thought the rest of the feed URL would be to the permalink URL, the code broke.
At that point, I noticed something interesting. Whenever FeedWordPress syndicates a post, it pushes some data from the RSS feed into custom fields. It seems like with each new version of FWP, more and more data has been getting pushed into these fields. While I was trying to figure out what to do with the post comment feed URL problem, I noticed that many (if not most) of the posts in the system had a custom field associated with them that was labeled “wfw:commentRSS”. Sure enough, the value of that field was the URL of the post comment feed!
(A bit of research turned up that “wfw:commentRSS” comes from the Well Formed Web project, and WP seems to use it in the creation of feeds by default. I admit I’m clueless when it comes to RSS format and namespaces, so if anyone wants to educate me on all of this, please do so.)
The bottom line is that I was able to fairly easily hack some code using a built-in WP function called “fetch_feed.” All this function does is parse a feed and then allow you to spit it back out in parts. I don’t actually have to do any spitting out — I’m just counting the number of items in the feed and building the little notation at the bottom of the post that indicates how many comments there are on the post. But, in this case, the link on that notation goes to the comment space of the original post (this URL, as it turns out, is also passed in a custom field when you pull a WP feed in using FeedWordpress).
Here’s the code I hacked into the Twenty-Ten child theme we’re using for the DS106 blog (FYI, I’m using a heavily modified loop for this site). Basically, you want to replace everything that is typically in the <span class=”comments-link”></span> with the following:
<span class=”comments-link”>
<?php if (is_syndicated()) { // this just tests to see if the post is a syndicated post ?>
<?php if (get_post_meta($post->ID, 'wfw:commentRSS')) { // this tests to see if the custom field we're looking for actually exists
$comments_url = get_post_meta($post->ID, 'wfw:commentRSS', true); // this passes the posts comments feed URL into a variable
$comments_link = get_post_meta($post->ID, 'rss:comments', true); // this passes the link to the comments section of the post into a variable
$comments_rss = fetch_feed($comments_url); //this parses the feed variable into its parts
if (!is_wp_error( $comments_rss ) ) { // this tests to see if the parsed feed is viable
$maxitems = $comments_rss->get_item_quantity(); //counts the number of items in the feed
if ($maxitems !== 0) { // tests to see if there are more than 0 items
echo '<a href="'; // the next couple of lines spit out the HTML to display the comment count.
echo $comments_link;
echo '">';
echo $maxitems;
echo ' comments. </a>';
} else { // if there are no comments the next few lines are displayed (with a link to leave a comment).
echo '<a href="';
echo $comments_link;
echo '"> Leave a comment</a>';
};
};
}
} else { // if it's not a syndicated post, just do the regular bit for comments?>
<?php comments_popup_link( __( 'Leave a comment', 'twentyten' ), __( '1 Comment', 'twentyten' ), __( '% Comments', 'twentyten' ) ); ?>
<?php } ?>
</span>
Honestly, we’ve been talking about wanting this bit when we use FeedWordPress for ages in DTLT, and it’s almost embarrassing how easy this was in the end.
There are still some bugs to figure out — the comment count is getting stuck on some posts, and I think that’s a caching issue with the parse function that I need to solve. Also, I’m not sure yet what’s happening with all the non-WordPress sites. Some aren’t working (resulting in nothing being displayed), but I need to track this down.
UPDATE: The incorrect comment count does, indeed, seem to be the cache on fetch_feed. The fix (which I found here) is to add the following to your functions.php file (The “600” represents the number of seconds to cache the feed for. So, this means I’ve set it for 10 minutes. I’m not sure if that’s going to be too much of a load on the server. We’ll see):
CC: Some rights reserved by medea_material on Flickr
Jim’s already done a pretty good job of summarizing the approach I took to building a tool for his online DS106 class which allows visitors to submit assignments. But I figured I’d go ahead and detail the process a bit more fully. To be honest, I’m doing this as much for me as for anyone else. I seriously doubt that it’s going to be that useful to many people, but there’s a really good chance that I’ll forget the circuitous steps that I had to take to make this work.
To summarize, the goal was to create a form on the course site that would allow people to submit assignments for the course (this need developed, in part, as the blog- and Twitter-based conversation before the course even started revealed all the great assignment ideas that people were coming up with). Jim had six general categories that he wanted people to submit digital story assignment ideas for: visual, design, audio, video, mashup, fanfic. Once the ideas were submitted, we wanted a way to then display them on the course site so that anyone could choose one to work on.
It’s a pretty simple idea, and there a probably a lot of ways to achieve it. One way I didn’t explore was to create a custom post type that would allow registered users of the blogs to create a post. I’m sure it’s possible, but I wasn’t really up for figuring out the solution to opening up a post editor on the front-end for non-standard roles.
Instead, I decided to hack a solution using a Google Spreadsheet. Here’s the basic process:
Create a Google Spreadsheet/Form based on the info we wanted to collect.
Hack the form to embed it directly into a custom WP page template.
On the spreadsheet, do some additional manipulations to the incoming data.
Utilize the Spreadsheet feed (available once it’s made public) to suck the data back into posts on the course blog using FeedWordPress.
Develop another custom WP template to display the syndicated posts.
I have to admit that it’s a pretty Rube Goldberg solution. I also have to admit that my favorite solutions these days are Goldberg-esque. I’m not sure why. I realize that taking this approach introduces more points of failure. I recognize that it’s all held together with the digital equivalent of shoelaces, paperclips, and duct tape. But, bottom line, I find incredible satisfaction in finding a way to make these different pieces work together like some kind of machine I’d build in the garage. To me, this approach is incredibly elegant. That said, I recognize that it’s actually the exact opposite of elegant. If someone can help me understand why my definition of elegance seems to be in direct opposition to the real definition of elegance, that’d be awesome.
So, I’m going to give a more detailed breakdown of exactly how I did this. But, please be forewarned, I’m not going to document every tiny step. It’s just too complex, and, frankly, too specific to my particular project. If you care to attempt something similar, you should be able to come away from this with an 80-85% understanding of what you’ll need to do. The rest is up to you. 🙂
1. Create a Google Spreadsheet/Form based on the info we wanted to collect.
This is the easiest step, but it’s still really important. All you need to do is set up a basic Google Form. But be aware that the rest of your project is going to depend on this form. It’s in your best interest to get this form exactly how you want it before proceeding. Otherwise, you’ll find the following steps harder.
2. Hack the form to embed it directly into a custom WP page template.
I can’t take any credit for figuring this next bit out. I learned all of it at Morning Copy’s Web site. <– That link will take you to a series of tutorials written by MC that explain how to truly embed a Google form on your site. Please note, you don’t have to do this. Google Forms come with standard embed code that you can use, but this code uses an iFrame, so there’s no way for you to control the styling of the form on your site. It’s going to look the way Google makes it look. I’m a control freak, so that’s just not cool for me.
The great thing about those Morning Copy tutorials is that they keep updating them to keep up with new features. So you’ll find code to redirect to your own confirmation page as well as to use jQuery to do some basic form validation.
I used the tutorials to embed the code in WordPress template that I then applied to this page.
3. On the spreadsheet, do some additional manipulations to the incoming data.
The form we embeded in step two will dump data into a Google spreadsheet just like a regular Google form. If I was happy with using just the data I’d collected on the course site, I could skip this next step.
However, for our purposes, I wanted to create a custom category associated with the assignments. I wanted this for two reasons: First I wanted to be able to sort/order the incoming posts based on the assignment category people chose when they filled out the form. Second, I wanted to be able to provide a tag that people could use when completing the assignment. This would make it possible to easily aggregate the submissions and display them with the assignment. I thought that would be cool.
In order to do any manipulations on Google Form data, you have to copy it. While you can put formulas directly into the worksheet where the data is dumped, each time the form is submitted, those forumlas get overwritten.
The trick is to create a second worksheet and then use cell references to copy the data into the new sheet. Then, you can add formulas into the columns on the right to manipulate the data. In our case, I created three formulas:
The first one just assigned a unique ID number to the assignment. I did this by putting the following formula in the first cell of the
column:
The second formula takes the category that was assigned to the entry and concatenates it with the word “Assignment.” The result is something like “DesignAssignment.” I then wanted to wrap that in some special HTML (more on this later) Here’s that formula:=ArrayFormula( IF( ROW(‘From Form’!A:A)=1 ; “Category Two”;
IF(LEN(‘From Form’!A:A),”<a rel=’tag’>”&’From Form’!D:D&
“Assignments”&”</a>”; IFERROR(1/0))))
The third formula concatenate the results of the first formula with those of the second formula, so I get something like “DesignAssignment1.” Again, I wanted this wrapped in some special HTML, too. Here’s the third formula:=ArrayFormula( IF( ROW(‘From Form’!A:A)=1 ; “Category Two”;
IF(LEN(‘From Form’!A:A),”<a rel=’tag’>”&’From Form’!D:D&”
Assignments”&”</a>”; IFERROR(1/0))))
Okay, now a word about these formulas. I didn’t write them. I did write some formulas (that were a lot simpler) and they basically worked except for a weird bug that I encountered. When I generated the copied data on the second sheet through cell references, I found that new entries weren’t iterating properly. Basically, cell references were incrementing upwards so that they are out of sync with the original spreadsheet.
My next step was to search the Google Spreadsheet help forum, and sure enough I found out a bunch of people were having similar problems (although the problem seems to be inconsistent). So, I went ahead and asked for some help. When I put up the post, I followed the example of others on the forum and made my spreadsheet public and editable. (Not really an issue since there was no sensitive data and I could always revert.)
Within about 20 minutes, a user named ahab had edited my spreadsheet with the proper formulas. That was basically amazing. I’m pretty sure I could have NEVER solved this problem, but I had an answer in under 30 minutes. How’s that for the power of openly sharing (and asking for help)?
So at this point, I had my original data as well as my newly generated fields.
4. Utilize the Spreadsheet feed to suck the data back into the course blog using FeedWordPress.
You may not know this, but once you make a Google Spreadsheet public, you can get an RSS or Atom feed for updates. In previous projects, I had played with this so I knew that it was possible to syndicate this feed into a WordPress blog using FeedWordpress. Each item can then become a new post on your blog.
If you click on the Share button on a Spreadsheet and choose “Publish as a Web Page” you’ll find the interface to retrieve all kind of versions of your data, including an RSS or Atom feed. However, there’s a trick. (Surprise, surprise!)
The default RSS feed doesn’t give you the data in the format you need. But, the Google Docs API has tons of information about working with feeds and Google spreadsheets. There are actually lots of variations on the standard feed that you can use to get your data in different formats.
I also figured out something new that was incredibly cool. The latest version of FeedWordpress has the capability to recognize a microformat called “inline tags.” (scroll down to the “tag” section on that last link for a description of what these are.) Basically, this means that if a word/phrase is wrapped in the following HTML, it can be automatically converted to a tag or category for the new post:
<a rel=”tag”>tag</a>
THIS is the “special HTML” that I mentioned adding to the formulas above in step 3. By simply adding text to the formula that wrapped the new categories I had created in these tags, I could have FeedWordpress turn them in to actual categories on the blog — which means we can use them to filter posts, create category clouds, etc.
But wait, there’s more! 😀
So, at this point, if I stopped, I could create posts that included the title of the assignment (this would go into the post title) and the categories (which would be added as WP categories.) Obviously, this isn’t enough. I need to import the description, author, and example URL. Each of these exists in the spreadsheet, but how was I going to associate them with the incoming post?
As it turns out, FeedWordpress has another feature that allows you to assign custom fields to a post as it is syndicated. FWP can actually parse a feed and pull out additional data that lives in it. See, the feed that I’m grabbing out of Google Spreadsheets contains all of that data, I just have to tell FeedWordPress how to find it and what to do with it.
A picture will probably be easier than describing how you do this in FWP:
Click for Larger Version
On the left-hand side, I give the custom fields a “key” (or name), in the middle field, I put in some code that tells FWP where to find the data. In my case, my data isn’t part of the standard RSS namespace, instead it lives in some custom attributes defined by Google. I honestly don’t remember how I figured out how to generate that code that tells FWP how to parse the data in the Google portion of the feed. I know I found some resources, but I can’t find them now. If I do find them, I’ll update with a link.
In the meantime, basically this is the code I used:
The URL points to google’s definition of it’s RSS namespace/attributes (forgive me if I’m using the wrong terms). The “cokwr” is just the coded “name” in the feed that corresponds to that data field.
Note that in the image above you see me setting up a few custom fields to grab data out of the feed (title, type) which I didn’t ultimately use or need.
5. Develop another custom WP template to display the syndicated data.
The final step was to create a custom template for the different assignment categories.
I’m able to have a single template work for each category. Here’s how:
I create a page for each category (“Visual”,”Design”, “Audio”, etc.).
When I create that page, I assign my template to it.
I also create a custom field for each page called “Assignment Category.” In the value for this custom field, I enter the name of the category that is going to show up on that page (“Visual”,”Design”, “Audio”, etc.)
In the template (the one I assigned in step 2) , I run a custom query based on the value of that custom field.
This is a pretty simply way to code a single template to filter posts based on the value of a custom field. Using it, I’m able to easily create six pages, one for each assignment category.
In terms of the layout, Jim and I settled on a design shows each assignment in a kind of “card” format. I’m using the double loop technique described here to separate the posts into two columns.
Within each card, I’m showing (and styling) the title, author, an image/screenshot of the example that was submitted, the description, the tags that someone should use if they complete the assignment, and a rating system (using the plugin WP Post Ratings).
Most of this is pretty straightfoward — I use WP’s built-in template tag to display the title. Then I use the get_post_meta function to spit out the author, description, and an image/screenshot associated with the example URL (more below). Finally, I use get_the_category to run a loop through the categories associated with the assignment (and these are the tags we recommend people use when submitting an assignment).
For the example URL, I’m doing some sniffing to see if the URL is an image. If it is, I display it. If it isn’t, I’m using the free version of ThumbnailsPro.com to generate a screenshot of the Web site (this is limited to 1000 shots a month).
Throw in some styling, and what we end up with is something like this. (Just realized when I went to that link that I’m not doing a check to see if there actually is a URL in the example field, that’s why some screenshots are broken. Guess I have more work to do).
Summary
Okay, that’s basically it. Here’s where I ask you to tell me if this was worth it (if you managed to get this far). Also, tell me all the ways I could have done this that would have been easier.
I know this is convoluted, but as I’ve said before part of why I love these projects is because I learn so much when I’m doing them. As a result of doing this project, I learned more about WordPress, Google Spreadsheets, RSS, FeedWordPress, php, and css.
And I’m really glad I wrote this all down. I can’t believe how much I had forgotten since starting this in mid-December!
Last semester, when we launched our new DTLT Web site, I was hoping to really use it as a tool for getting the word out to our faculty about news, upcoming events, professional dev. opportunities, and showcase projects. Ideally, I wanted to use it as a hub from which all of this information could be delivered.
What I really wanted was an easy way to create a newsletter that included content from the new site. I planned on sending these out to all UMW faculty about once a month. By using the site to generate the newsletter, I wouldn’t have to build it from scratch. After all, everything that I wanted to share with the faculty should, ideally, also have some presence on the Web site. What I quickly discovered, however, was that there was no easy way to use the content I was generating on the site to create such a newsletter.
WP has a few newsletter/subscription plugins, but they seem to do one of two things: send updates to subscribers whenever a new post is generated or simply generate a list of emails that you can then use with some other newsletter program. Neither of these was really ideal. I was pretty certain that most faculty wouldn’t appreciate an email from DTLT every time we added something to the site. And I’m not using any other third-party program to generate a newsletter. I also didn’t want an opt-in solution. I really wanted to be able to send something to all faculty using our internal all faculty email list at the University.
What I wanted was very simple: a basic text of html email that I could send to faculty with a list anof new items and links to read more.
After a few months of tinkering (and getting distracted by other projects), I’ve finally come up with a solution.
Basically, I created a custom page template called template.php newsletter.php which can be applied to page when you create it. The text you put in the page becomes the text at the top of the newsletter. (“Welcome Back! We hope you had a nice break. Here is our latest newsletter. . .”). Then you use a custom field (“issuecat”)on the page to define a category number. In my case, I created a category called “January 2010 Newsletter” and entered the corresponding category number into the custom field.
When I view the page, I get a specially formatted page, showing the text of the page and the content (up to the “More” divider”) for whatever posts I put in my category. At the top of the page is a link to the actual page on the blog in case someone can’t view the HTML email. I’ve also allowed for custom images to be displayed with the posts through the use of another custom field: newsimg. (Although I’m not using these at the moment.)
Getting the newsletter into an email program takes a little bit of trickery, and it depends a lot on what email program you’re using. In my case, I work on a Mac and use Mail or Entourage to send through our Microsoft Outlook mail server. Sending an HTML email that you’ve created elsewhere can’t be done out of the box in either of these programs. However, for Entourage there is a script that will allow you to send a complex HTML email. Basically, you save the WP newsletter page to your computer and then use this script to point Entourage to the file. The message should preserve all it’s formatting. In Mail, you can copy and paste the text of the newsletter into an email message. This won’t preserve images, but it will preserve the basic formatting.
In all honestly, I would love to do this with just a plan text email. There’s no particular reason why it has to be HTML and I’m not huge fan of HTML email. However, in order to have something that gets automatically generated (so that I’m not spending a bunch of time doing even basic line/paragraph breaks) by WP, this seemed like the only solution.
The code to make the template itself work is nothing fancy — just a variable for the category custom field that’s used to execute a second query on the page to grab the appropriate posts. The ordering is just descending chronological. I’d like to play around with grouping the posts based on type (event, news, project, etc.) but that’ll have to be for the next iteration.
The formatting of the page is based on a basic HTML email template I found online (can’t find the link right now, but I’ll try to add it later). As it turns out, the HTML you use to generate email is like generating a circa-1997 Web page. Figuring out how to make that work was painful.
If anyone cares to try it out, here’s a link to the template file, zipped up. You’ll have to make some changes to the code (for the page title, image, etc.) Also, full disclosure: I’m not a programmer, just a hack. There may be a better way to do this, code-wise. I just know it served my purposes. 🙂
I’ve blogged in the past about my endless DTLT Web Site Redesign project. And I’ve committed myself to regularly blogging about what I’m doing as part of that project. And then, of course, I’ve promptly broken that commitment. Oops.
It occurred to me after I published yesterday’s post that I should probably talk about why I think it’s important to do all the things I was trying to do with the Faculty Academy Web site. I’ve already touched on a few or those reasons — mainly the selfish desire to learn more about how WP/WPMU works and to, hopefully, discover some techniques/ideas that I could put to use on other projects. But I don’t want to suggest that putting together this site was purely an exercise; I’d like to believe that there was actually some meaningful purpose behind the experience.
In a former job, I spent a lot of time planing Web sites, thinking about their communicative goals, talking to focus groups and committees about their purpose and how we would measure their success. While I learned a lot from that experience, and I think I was able to put what I learned to good use, truthfully, a lot of it felt like wheel spinning. Talking about what we were trying to do so as to convince ourselves we understood what we were trying to do. Making a science (or a study) out of something that still, for me, often feels very nebulous and difficult to define.
So one of the reasons I love, love, love working on the site for Faculty Academy is that it has a somewhat short life-time (I know that it serves a purpose as an ongoing, permanent archive of the event, but it’s core user functionality is really critical for only about 6-8 weeks prior to the conference). It’s also a small enough conference, with enough returning attendees (most from within my own University), that I have some freedom to try new things and not worry too much if they backfire. Sure, the cfp and registration system needs to work. The program needs to be clear and easy-to-find. Logistical information needs to be accurate and consistent, but, beyond that, there’s a lot of opportunity to play.
This idea of “playing” as a way of building a Web site is, more and more, a much more rewarding way for me to work on sites. I feel pretty lucky that most of what I build online these days has a somewhat short life-span (a semester, perhaps), is done in collaboration with other playful individuals (my colleagues in DTLT and the amazing faculty and students at UMW), and doesn’t contain a lot of “serious,” institutional data that I need to worry about vetting with a huge committee or administration.
That said, I don’t want to downplay the importance of these projects. I just think course management systems, with all of their institutional-looking interfaces and static feature sets have lulled a lot of us (instructional technologists, faculty, students), into thinking that building online experiences within the Academy needs to be a locked-down, top-down, “standardized” experience. I think that’s just antithetical to how we ultimately teach and learn.
So as I embarked on this year’s conference site, I was seeking to build a site that could serve the following goals:
* provide clear, accurate information about the event (that’s a no-brainer)
* allow people to easily register or submit proposals (again, duh)
* provide an online venue for pre-conference interaction and investigation
* provide an online venue for live conference activity and monitoring of conference activities happening in other spaces
True:
* Not a lot of people added tags to program items
* I’m not sure how many people cared that there was a “live” feed of current sessions on the home page.
* As far as I can tell from the Google Analytics, no one viewed any of the archived conference video from previous years that I highlighted in the site footer prior to the event.
* Only a handful of people used delicious to add bookmarks that were tagged “umwfa09.”
But, by no means, do I think any of what I tried was a failure. First, as I’ve said before, I learned a ton doing it. I’m never failing when I’m learning. Second, even if a lot of people didn’t participate in some of the opportunities I provided, I believe a few people had seeds planted that we can continue to nurture throughout the year and at next year’s conference. Bit by bit, we make inroads. And we also model for our faculty, our students, and ourselves a way of building and creating that values learning, creativity, experimentation, and even “failure.”
Over the next week or so, I’m planning on putting up a bunch of posts about the work I did this year on the Faculty Academy Web site. Every year, working on this site is a particularly fun project for me, starting four years ago when we first began to host the conference Web site at www.facultyacademy.org with a one-off WordPress install. And every year, I’ve tried to use the project as an opportunity to push myself to learn more about how to use WordPress as a site for an event/conference. I spend an awful lot of time barking up the wrong trees and generally getting myself in trouble, but I chalk it all up to a great learning experience. For example, what I learned this year will not only come in handy as we put together the site next year, I’m also imagining how I can use it to help with a regional instructional technology conference that we often participate in here in Virginia and how I can put my lessons to use in the revamped DTLT Web site that went on hold as FA ramped up.
To start with, I’ll run quickly through a number of the tools, plugins, etc. that I made use of this year. I’ll try to dig deeper into what worked and what didn’t work for each one in future posts:
WordPress/WPMU: The conference site “proper” has lived within WordPress for several years now. I toyed with the idea of using something different this year, but ended up settling on WP again for a couple of reasons. One thing different this year was the the site was actually a blog within a WPMU install that Jim Groom helped me set up. The plan is to migrate all of our past FA sites to this install so that we can more easily upgrade, maintain (and possibly link) them. Another reason I decided to go with WP/WPMU was that we were hoping to use BuddyPress as a way to solicit registrations and proposals this year. We thought we might be able to set up custom user fields for the information we ask for when people are registering or submiting a presentation. Then, everyone would have an accounts on the site and we could maybe use that to build some kind of stronger online community presence for the conference. Bottom line, the BuddyPress experiment didn’t work out for a couple of reasons, but I’m still glad we went with WPMU. I think being able to migrate all of the conference sites to this platform — and build future conference sites within it — could pay off in the long run. Plus, it allowed me to get my feet wet with WPMU and to develop a deeper understanding of how that system works.
Google Docs/Spreadsheets: For the last three or four years, we’ve been using PhpSurveyor/LimeSurvey as the tool for soliciting registrations and proposals. It was a fine solution, but there were a couple of things about it that I wasn’t nuts about. For one, because it’s really a survey tool, the internal language in the application often confused people. I ended up hacking the core code so that there were no references to “survey” when people filled out the form. There was also no way to send people emails upon completion of the survey — which we got a few complaints about. Also, we had gotten to the point with that tool that we were making use of branching so that we could have one form for both registration and proposal submission. This seemed needlessly complicated. It was a pain to set up, and it was a pain to switch the forms mid-stream when the cfp would close but registration was still open. Finally, the output from PhpSurveyor isn’t very pretty. I ended up doing a bunch of exports periodically to a .csv or .xls file, and then cutting and pasting things together. I was always paranoid that I would screw up the cut-and-paste, and I felt like I was juggling way too much.
As I mentioned above, we toyed with the idea briefly of going with BuddyPress for this purpose, but we weren’t thrilled with how that was going to play out. So, instead, I used a Google Form/Spreadsheet which I embedded into the conference site. I’m not sure I’d do it again: there was a fair amount of template hacking (because I wanted more control over the form styling), Patrick still had to write a custom script for me so that people could get emails when forms were submitted, we ended up separating the cfp and the registration process which WAS better for us but may have been more complicated for users. All that said, having the data in a spreadsheet was very cool.
Exhibit/Google Spreadsheet: We’ve never had a dynamic registrant list on the site before — there was never any easy way to feed registration data into a place where we could consume it. But this year, when I realized that all of our registration data was going to be in a Google spreadsheet, I also realized it would be very easy to set up an Exhibit to display the data. It actually took a fair amount of time to set this up — more template hacking and some issues with getting the data to feed out of Google docs properly. But once it was set up, it worked seamlessly.
Various WP Plugins: I used a whole slew of new WP plugins for the site. It’s always fun to have a project that allows you to experiment with new plugins, and FA is a great opportunity to try things on:
* Add Link and FeedWordPress: I knew from some recent posts by Jim that these two plugins were working really well together, but I couldn’t believe how easy they made it to add a “Live Blogging” feature to the site while the conference ran (and beyond). We had about 8-10 people add their blog address/feed, and we’re still featuring any posts they write that they put in a category called “umwfa09.”
* More Fields and Advanced Custom Field Widget: I had experimented a few months ago with a plugin called “Flutter” which makes it easier to add custom fields (and create custom write panels), but it had some bugs and didn’t really work properly on WPMU. This time around, I discovered “More Fields” which is dirt-simple to setup and use. Then I stumbled on “Advanced Custom Field Widget” which makes it even dirt-simpler to display the values of custom fields in the sidebar. Bottom line: I was able to use the combination of these two plugins to enter session data for each presentation (location, time slot, format, presenters, etc.) and display it in the sidebar for each presentation’s post.
* Advanced Category Excluder and More Privacy Options: One of the challenges of working on a site for a conference that is coming up/ongoing is that you’re working on a site that people are going to be hitting regularly. You don’t want to show them some of what you’re working on for the actual days leading up to/of the conference. I was able to use these two plugins to hide certain activity until I was ready to make it available.
* FeedBurner FeedSmith: I’d never used a FeedBurner feed for a WordPress site before, but I’m glad I did this time. Not only did it allow me to track subscriptions to the site feed, I was able to set up a way for people to receive updates via email — which was really important since the plugin we’ve used for this in the past — Subscribe2 — wasn’t playing nicely with WPMU.
* Flickr Photo Album and Quick Flickr Widget: I actually used two different Flickr plugins at different times in the life of the site to display photos from Flickr. Flickr Photo Album was ideal for the display I wanted leading up to the conference (and made it easy to embed previous FA photos in pages/posts), but when the conference was running live, I preferred the output of Quick Flickr Widget on the home page to show a live feed of photos.
* WPtouch iPhone Theme: I don’t know who else benefitted from this besides Andy :-), but it was very cool to be able to simply install a plugin and have an iPhone/iPod touch-ready conference site.
* Yet Another Related Post Plugin: I kind of threw this one in at the last minute as the program was going live, and I was very pleasently pleased with the results. Basically, it allowed to me suggest related conference presentations for each individual session. If you’ve got a community that is actively tagging conference content (which ours wasn’t–see below), I could see this being very dynamic.
* Matt’s Community Tags: So often when you’re working on a site like this you spend an inordinate amount of time on a feature that seems really important to YOU but no one else cares about. This was one of those. But I don’t care, because I still think it’s a neat feature and maybe we’ll use it in the future. Basically, it allowed anyone to suggest a tag for any conference post (including all of the presentation posts). The tags go into moderation (which isn’t necessarily ideal), and you can use this to grow your tag cloud and, ultimatley, your understanding of the ideas inspired at the conference.
There were a few other great plugins that helped with the basic content-management aspects of the site, but I won’t go into all of those here.
For those who care, the theme I used was a seriously hacked version of WordPress Magazine Theme. It had good bones for what I wanted to do.
The feature of the site that I was most proud of, though, really didn’t require any special plugins — just a pretty mild hack to index.php. I knew I wanted to have something on the conference home page that displayed what was going on right now as the conference was running. It occurred to me the weekend before the conference that all I needed to do was create a post for each conference time slot with links to the various presentations and then time them to publish at the time when the slot began (actually, Jerry suggested going with 15 minutes prior to the beginning of a session, and that worked better). I put all of these posts in a new category called “currently.” Then I put a custom Loop on the home page that just displayed the most-recent post in that category. Voila! Dyanmic conference program on the Web site. I have no idea if anyone cared that there was a dynamic program on the Web site, but, again, I learned something figuring it out.
So. That was a lot longer than I intended. Maybe I don’t need to do individual posts about different tools now, but I think I still will, if only to document the successes and challenges for myself.
These days, I feel like I spend a great deal of my time figuring out how to tweak WordPress to work as a simple but elegant content management system. In the fall, I worked on a site for a family member that finally got me thinking about the possibilities on this front. Then, in November, I turned my attention back to revamping the DTLT Web site in WordPress and using a bunch of plugins to make the CMS thing work. At the time, I settled on installing it outside of UMW Blogs because I thought I was going to need to use some plugins that weren’t available in that environment. A lot of my attention was focused on Flutter, which allows for customization of WP’s internal write post/page panels.
In December, I was asked to fast-track a new site for the upcoming strategic planning process that’s about to kickoff at UMW. That site should get unveiled to the community later this afternoon. This time, I decided to use UMW Blogs because so many of the constituents (and those who will need to work on the site) already know and have accounts in that system. Thanks to Jim, I was able to install a few extra plugins that enabled me to do some more cms-y things there.
The most notable was a very powerful plugin called Widget Logic. Basically, it allows you to use WP conditional tags to govern when a widget is displayed in the sidebar(s). Used well, this means you can have dynamic, contextual sidebar content/navigation for different parts of your site. But there’s a downside to this widget. You have to be willing to delve into conditional tags. I love that kind of tinkering, but I’m not sure many other users in UMW Blogs are going to be willing to go there.
But the bigger challenge on all of these sites has been making sense of the page/post dichotomy. Jim has pointed out to me a bunch of time how broken he thinks pages are in WP, and I have to agree with him.
Take the strategic planning site for example. I knew that I wanted some content to use the features of posts: subscriable, able to be added to categories, displayed in rev. chron order. But, I also knew that the authors of the site would probably want to post some content that didn’t make sense in posts–content of a more static nature. Ostensibly, WP solves this by offering you posts and pages, but it is virtually impossible to get these two to play nicely together.
What I ended up doing was creating an information architecture twice: once in a page hierarchy (so the static-type content could be organized effectively) and once in a category hierarchy (so that posts could be assigned to the appropriate place). But when it came time to make those two hierarchies work together, I had to do a bunch of template massaging and widget logic-ing.
I can, for example, show a navigation menu of pages in the sidebar, that expands and collapses based on where I am on the site. But as soon as I jump out to a post, I lose that context and the navigation stops making sense. What would be nice is if pages could belong to categories! I have no idea why this isn’t a feature of pages now. I see enough people asking about it. I know there are plugins out there that kluge this, but I’m not sure that’s ideal in a WPMU environment. (Perhaps I’m wrong, but since categories exist across the entire WPMU environment, any tinkering with that feature would make me a little nervous).
Oh, and WP really needs a way for users to easily reorder pages without having to use the ridiculous page IDs.
With these two features: page categories and easily reordable pages, I think we might be able to get to a very nice CMS right out of the box. In the meantime, sometimes I feel like I’m jamming a square peg into a round hole. Again, I love doing all this tinkering and massaging, but I’ve got to build something that works well for the users who will be authoring the vast majority of content on these sites. If there’s too much kluge and not enough smooth, I’ll be hearing about it. (ouch)
In the meantime, for your viewing pleasure a bit of 80’s nostalgia:
I had such high hopes to do some serious blogging over our two week Christmas break. I have about a dozen posts brewing in my head, and I’m just trying to carve out the time to get them down. But, alas, holiday cheer, family visits, and a baby who decided it was time to give up our much-cherished sleeping through the night routine intervened.
Luckily, my task for work this morning involves one of the things I wanted to share, so I’m going to take the opportunity to document the process here.
About a year ago, DTLT was tasked with leading a project to complete a “Functional Inventory” of our teaching spaces. The point of the inventory was not to document serial numbers, models, or other typical physical details about equipment, but rather to describe what kinds of things a faculty member could generally expect to find in a room (and, thus, what they could expect to be able to DO in the room). The hope was that this could become both a resource for planning our strategy for upgrading classrooms/labs as well as a tool for faculty and department chairs as they developed schedules. (We currently have no enterprise scheduling tool at UMW.)
As I tried to tackle this project, I did a survey of the landscape in terms of tools I could use to collect and present this information. In the absence of a big scheduling application, I was looking at free, open-source products, and I quickly discovered that I was probably going to have to glue several pieces together in order to do what I wanted to do. I knew I needed some kind of Web-based mechanism for collecting the data (so that various individuals around campus could easily collaborate on collecting and maintaining the information). I also knew I need a fairly intuitive interface for faculty to use to browse, filter, and use the data.
I figured the simplest, most readily available tool for collecting the data would be a Google Spreadsheet. With it’s similarities to Excel, it’s a tool just about anyone could master immediately. Unfortunately, with about 160 rooms that needed to be recorded and about 30-40 fields for each record, entering data into a flat spreadsheet interface could quickly get unwieldy (and lead to errors).
What I really needed was a way to build a form to collect the data. Right around this time, Google introduced their form feature, which looked promising. But a closer examination proved it wouldn’t suffice. Information about rooms could potentially need to be modified by several people, and we needed a mechanism to update information once it was entered. Google forms don’t allow you to edit existing records.
I knew from previous experimentation about an online database service called Dabble, and that’s where I looked next. Dabble is a pretty powerful application that essentially allows you to create relational databases. Frankly, it’s a bit of overkill for the data I needed to collect at this point. I really just needed a table of information with a clear Web form for adding and editing information (no relationships really need to be defined), but Dabble looked like the best bet.
At this point, I started to settle on how to present the information once it had been entered. Dabble has a couple of options, but none of them was really right. There is a “raw” view that allows you to edit, filter, and view the data in a more-or-less spreadsheet form, but it would be way to confusing to ask all of our faculty to navigate. There is a form/page view, but that’s really designed more for entering and editing information more easily, not filtering and viewing it — at least not the way I wanted to filter and view it. And there is also a public data view that is just a spew of everything in the table — again, not very helpful.
Well, one of the great things about working in DTLT is that I have this amazing group of colleagues who regularly introduce me to technologies that capture my imagination. So at this point, thanks to Patrick’s previous work and evangilizing, I had a feeling I wanted to use Exhibit to do the presentation of the data. I love the way Exhibit allows you to easily put a nice visual front-end onto a set of data, and I was intrigued to learn more about how to customize the presentation of that front-end.
Now I needed to figure out how to get the data out of the tables in Dabble and into Exhibit. I knew that Exhibit could consume data from various types of sources, and I knew that Dabble could export data in a variety of formats. Surely, I could find some way to get them to talk to each other?
I started with what seemed like the simplest option. According to Exhibit’s Web site, it’s possible to use an Excel spreadsheet to feed data into the application — well, Dabble exports in Excel format! But, closer examination showed that Exhibit would require me to use the Babel translator on a copied selection of data, essentially converting a snapshot of Excel data into JSON. I wanted the data to be updated in real-time and reflected in the front-end presentation. Not because the data is to variable or time-sensitive but because I know everyone gets busy and more than likely we’d forget to do the snapshot uploads as often as needed.
The other format that Dabble exports to that looked promising was JSON, which is actually the data format that Exhibit requires. But closer examination of THIS option revealed that there is no one single flavor of JSON, and the kind that Dabble spits out couldn’t easily be converted to the kind Exhibit wanted. Rats.
The final option was a Google spreadsheet. Dabble exports to Excel, and that format can be uploaded into a Google spreadsheet. Also, it’s possible to fairly easily use a Google spreadsheet as the data source for Exhibit. However, my initial assessment of this (last spring) suggested that it was still going to require someone to regularly export the data out of Dabble and upload it into the Google spreadsheet. And the process for doing so wasn’t easy — cutting and pasting the data was cumbersome and often didn’t work properly in the spreadsheet interface.
At this point, sometime in mid- to late-March, events, so to speak, overcame the project. For various reasons it got put on the backburner, with information for about 98% of the rooms collected and languishing in the Dabble database, I was more or less stuck with figuring out how to get it out of that source and into a presentation that worked and, possibly, a different data environment for better management and upkeep.
Last month, I finally turned my attention back to this conundrum, determined to figure out a solution that would meet all of my requirements. This time, I focused my attention primarily on the Google spreadsheet middle layer. I believed that there had to be a way to use this tool to do the “translation” from Dabble to Exhibit, and I finally cracked the puzzle a few days before the holiday break.
The magic comes with a function in Google spreadsheets that imports data into the table from another source. There are a variety of formats that it accepts, but the one that ended up working for me was .csv (as it happens, another format that Dabble exports into).
I plugged the following formula into the A1 cell of a table, and voila!, I had data populated into spreadsheet cells.
At this point, there were just a few remaining questions.
First, I had no idea how “live” the data would stay. The Google documentation didn’t make clear whether the formula maintained a live connection to the data source, or whether it just grabbed the data once, dumped it, and was done. To test, I left the spreadsheet open and began editing the originating Dabble database. Lo and behold, I found that after a while the spreadsheet reflected changes to records as well as new records I added.
The next question was a strange one — and a bit existential. What would happen when the Google spreadsheet was closed. Or, to be cute, if a Google spreadsheet is closed does the imported data still make a sound? I wasn’t sure if what prompted the spreadsheet data to update was dependent on me actually having it open in a browser. Since I was just planning on using Google as the middle-layer in my Dabble/Exhibit sandwich, I didn’t really want to regularly mess with (or even open) it.
So, I closed my eyes and my spreadsheet, made some more Dabble edits and waited to see what would happen in Exhibit. To my delight, Exhibit picked up on and began displaying new and edited records. Things were looking good.
The last problem I needed to solve was sort of a nit-picky one. In order for Exhibit to know what to do with the data, it needed to exist in fields that were labeled with a particular field name. Basically, the field name has to live between two curly brackets: {field1}. When I imported the data from Dabble, it was getting assigned the field names from that application and I didn’t have that generic {label} field. I guess I could have changed all the field names in Dabble, but I didn’t really want to do that — I thought it would make Dabble less user-friendly for users entering information.
So, I decided to do some transformations in the Google spreadsheet. I simply created another sheet, put the field labels I needed in the first row, and linked the cells on the second sheet to the appropriate cells on the first.
The final step in this Dabble-Google-Exhibit dance was to publish the Google spreadsheet and use it as the data source for my exhibit.
If you’ve followed along so far, well. . .wow. I’m impressed. Here are some links as a reward:
* The original Dabble DB public data view: Currently, I’m using Dabble’s default, free account. You get a limited number of users with this kind of account and your data has to be public (CC licensed). That’s fine because I didn’t need a lot of user accounts for the data entry and I’ve got no problem with the licensing because the final product is public.
* The Exhbit presentation: Based on the data in the Google spreadsheet (via RSS/JSON) with few modifications (fields names, etc.)
There still a bit more to do. I need to finish tweaking the Exhibit front-end, and we’ve got a bit more work to do on the data. I’d also like to create parallel presentations for labs and computer carts (we have the data in Dabble; I just haven’t gotten through the other steps).
In the end, I’m really glad I was able to figure out how to make this work. I feel like I’m using each of the tools for what they do best (for my purposes). That said, there are now multiple points of failure and it feels a bit like it’s held together with shoestrings and duct tape. Also, my testing was on a small set of data; I have no idea how this is going to hold up under the increased pressure of a larger data set. Time will tell.
There are a lot of places I could start my next post about the DTLT site, but given the critical role that I’m imagining for custom fields (and, hopefully, the Flutter plugin), I thought that might make the most sense.
A Very Basic Introduction to Custom Fields
For those of you who don’t know, custom fields are a built-in feature of WordPress. They’re a part of the write panel for posts and pages, but you may have never noticed them. Here’s the default custom field panel:
Basically, they allow you to associate additional information with your posts or pages. If you read the official description of custom fields on WordPress’ site, you’ll see that the developers refer to this feature as a way to add meta-data to a post or page. Basically, you choose a “key” for your field — that’s the name of the element — and a value. Once you create a new field/key, you can associate it with other posts/pages, by choosing it from the “Select” drop-down menu. You can also also add a key to a post more than once.
But creating the custom field is only the first step. Once you’ve done that, the information is stored in the WP database, but it’s not going to show up on your post and page magically. You’ve got to edit the template to display the values. To do this, you use a built-in template tag (more on these in a later post) that you add to The Loop (which is the core part of WP template code for displaying posts and pages). The tag is just a simple snippet of php:
<?php the_meta(); ?>
With that bit of code added, your field values appear in your post/page (the location depends on where you place the code in The Loop). The technique is pretty simple, but it’s not terribly nuanced. All you’re going to get is a unordered list of whatever custom fields are associated with the post, and a pre-existing style in the WP CSS will be used to style it (of course you can modify that style, but you’re still dealing with a list of content).
For more advanced approaches, there are some built-in functions in WP that allow you to do more than just display the custom fields in a list. You can find more information about them on the WP page about custom fields.
On that same page, I’m particularly intrigued by this text: “We expect that independent developers will come up with many interesting uses for post meta-data in the form of plugins. The the_meta() template function is just an extremely basic example.” What’s interesting to me is how few plugins I’ve found that do make use of custom fields. When I first started using WordPress a few years ago, I started looking around for more powerful/elegant ways of utilizing this feature, but I’ve never found very much. I think that’s kind of odd — to my mind, custom fields provide some really intriguing ways of extending WordPress.
If you’re interested in learning more about custom fields, I encourage you to take a look at some of these resources:
My interest, quite frankly, is less in the possibility of adding meta-data to WP content. What I’m interested in really is being able to structure posts and pages, based on the kind of content that’s being created. So, for example, if I was creating a post about a project that we’re working on in DTLT, I could set up several custom fields for the various pieces that would make up a project content piece: Description, URL, Collaborator(s), Screenshot. There are three main reasons why I’m interested in this approach to content creation:
I imagine it would let me do more interesting things in terms of presenting the content. If each piece of information is held in a different custom field “container,” I can arrange them on the page (in custom templates) and style them more granularly.
If I pre-define fields for a type of content, then there’s a better chance of creating more consistent pieces of content, in general (particularly when multiple authors are working in a blog). If it’s important to me that a project post have particular types of information, then the custom fields serve as a kind of prompt to make sure each new post is complete.
For certain fields, I can imagine wanting to “pivot” information presentation on them. For example, if I’ve got a “collaborator(s)” field for projects, I might want to be able to slice my project content up so that I can see all of those projects that a particular faculty member collaborated on DTLT with.
All of these reasons really require that I structure my content into different containers, and custom fields definitely seems like a way to do this.
Where Flutter Comes In
I mentioned above that my search for WP plugins that build on the custom field feature has been pretty fruitless. Well, a few weeks ago, I finally turned up one that that looks like it has a lot of promise. Flutter (previously called Fresh Post), puts a more elegant front-end on custom fields, allowing you to define new “Write Panels” (essentially new versions of “Write Page” or “Write Post” in the administrative back-end of WP) with custom data fields. You can define as many different write panels as you want, theoretically with each one designed to deal with a different flavor of content for your site.
The first step in setting up a custom Write Panel is defining some options for it. You can see those in the image on the right. Being able to automatically define a category and set which default edit blocks appear is very cool.
Once I’ve created the custom panel, you can add custom fields to it. And, you have more options than just designating a key and a value for custom fields. Flutter actually has several field types that you can choose from:
Textbox
Multiline Textbox
Checkbox
Checkbox List
Radiobutton List
Dropdown List
Listbox
File
Image
Date
Audio
Basically, you define the fields you want to make up custom type of content and you build a custom panel for that type. When you’re done, you’re “Write” tab will reflect the new panel names (and you can hide the default Page/Post sub-tabs to minimize confusion).
Another very cool feature is that you can create groups of fields that can then be duplicated. So, for example, if I want to be able to add RSS feeds to a new piece of content, I can define a group called “RSS Feed” with two custom fields, “FeedTitle” and “FeedURL.” That group can then be duplicated, allowing me to have more than one RSS feed associated with a post. I can then use something like SimplePie to display the feed(s) on the page. (I’m using SimplePie this way now with the “Person” content type on the new DTLT site. There’s no styling yet, so it looks crappy but you get the point.)
There’s a whole other level to Flutter that I haven’t gotten into yet — once you’ve created your custom write panels, you can then use a GUI editor to edit your theme with custom widgets (or so it seems). However, my initial research into this feature suggests it’s built on the Canvas WP template engine, and I believe that project is now defunct.
There are a few pitfalls that I’ve run in to with Flutter.
By default, the “File” field type uses a Flash-based file uploader that I can’t get to work in my version of Firefox (3.0.4) with my version of Flash (10). It took me a while to find out that I could opt for the standard file upload feature in the Flutter settings. (The Flash version did work for me on Safari. Sorry, can’t tell you what the IE situation is.)
While you can disable the “Write > Post” and “Write > Page” subtabs, you can’t disable the “Manage > Post” and “Manage > Page” subtabs. It’s a small thing, but it could lead to confusion, particularly if there are multiple authors on a blog.
When you create a custom write panel of the “Page” variety, you’re given the option to show or not show the category block. Well, pages in WP don’t use categories (unfortunately!). I thought that it was possible Flutter had found a way to assign categories to pages, but, alas, this is not the case. Looks like they just offer the same customization options whether the custom panel is a post or a page. For this reason, I’m using posts exclusively as the building blocks for my content. I need me some categories.
The default WYSIWYG editor for custom fields of the type “text area” doesn’t seem to be as fully featured as the default WP editor. I’ve got the very cool cets_EmbedRSS plugin installed (kudos to Jim for pointing this one out), and while it adds the RSS button to the editor in the text area, it doesn’t seem to work. I’m not sure what’s going on here, but be forewarned.
In a post that D’Arcy recently wrote about Flutter, he mentioned that it did some odd things to the main write panel, causing his posts to wrap strangely. I haven’t seen this behavior, but that doesn’t mean there isn’t something wrong.
D’Arcy also mentions that what’s going on behind the scenes with Flutter is a bit klugey. This probably has as much to do with how custom fields are handled in the WP database as it does to anything that Flutter is doing, in particular. Basically, custom fields are stored in a table called wp_postmeta. Each new value is a new record, with post_id (presumably to associate the custom field with the proper post or page), meta_key, and meta_value fields. That seems a bit topsy-turvy — the fact that there is no relational structure where a new custom field becomes a new record, and then the values are associated with those records, but what the heck do I know? Flutter builds a bunch of new tables to store information about the different Flutter options that are then associated with the custom field records (don’t know how, yet; I haven’t really looked into it). Bottom line: I have no idea if the back-end database structure is going to affect any of the cool things that I’m wondering if I could do with Flutter. Guess I’ll find out.
For now, I’ve created five different custom write panels for the new DTLT site: Person, (News) Post, Opportunity, Project, and Resource. They each have a different set of fields, depending on what I imagine they should consist of. (I’ll blog later about what fields I’m using for what content, since that gets at a whole other, non-technology, set of decisions.) One of the cool things about this approach is that since at their core they are all just posts, you can use categories and tags as a way to slice across the different content types. So, for example, if I tag a (News) Post and a Project with “SteveGreenlaw,” then my tag page for “SteveGreenlaw” will show me all of the content (of any type) that is tagged that way. With a little template massaging, I think the display could be finessed to make that a pretty cool view of content.
What’s Next
I’m really excited about diving into creating the custom templates to display these different types of content. I’ve finally wrapped my heard around The Loop (I think) and features of WP like template tags. I’m basically an ignoramous when it comes to php, so I’ve got a lot of learning to do (there’s another post here about a breakthrough I had about learning php — I’ve got to blog about that, too!).
I’m also interested in figuring out if there is a way to filter WP content based on custom fields. So, for example, as I mentioned in my example above, if I’ve got a field called “Contributor(s),” can I create a display of content that just shows those posts that share the same value in that field? I’m sure there’s a way to do it. Question is if I can figure out how.
Perhaps the biggest challenge I’d like to try and solve that I haven’t even touched on here is how custom fields can interact with RSS feeds. I’ve found at least one plugin that seems to allow for including custom fields in RSS feeds. The reason I’m interested in this is that I think it might allow for distributed authorship on a blog like ours. Truth is, we all blog in different places, primarily, and very often the contributions we make to our own blogs could be meaningful on the DTLT site. I don’t want to ask people to duplicate effort. So, I’m wondering if it would be possible to get a feed from our disparate blog sources that spits out the same custom fields as I’ve defined for the DTLT site. One of the cool features of Flutter which I didnt’ get into above (because I really haven’t tried it) is that Write Panels can be exported and imported. So, theoretically, I could share those custom panels with others running WP, and if they have Flutter installed and if I can figure out how to add custom fields to the RSS feeds and if I can figure out how to get the DTLT site to reconsume those fields, we could do something kind of slick. That’s a lot of if’s, and, truth be told, this part of my project is as much proof-of-concept as anything else. Mostly, I’m interested in experimeting with distrubuted authorship, and this seems like one interesting approach.
So, that’s it for now. Thanks to Jim for the shout-out about this project. Now that he’s “outed” me, I’ve got more incentive to keep on blogging about it. 🙂