Everything In Between

The brutally honest, first-person account of Meitar Moscovitz's life.

Archive for the ‘Web Design’ Category

How web designers can do their own HTML/CSS: Read Foundation Website Creation

7 comments

Last month, 37signals published a short but sweet post about why web designers should do the HTML/CSS implementations for their own designs. The bottom line is, as we’ve all been saying for a long time now, that the Web is not the same kind of medium as other mediums like print. It is a fundamentally different kind of canvas than most web designers are used to using. As a result, if you as a web designer are not intimately familiar with it, you’re not going to do great work.

designing for the web is a lot less about making something dazzle and a lot more about making it work. The design decisions that matter pertain directly to the constraints of the materials. What form elements to use. What font sizes. What composition. What flow. Those decisions are poorly made at an arm’s length.

I’ve worked with many web designers in the past who only did abstractions and then handed over pictures to be chopped and implemented by “HTML monkeys”. It never really gelled well. The things that got strong attention were all the things that Photoshop did well. Imagery, curvy lines, and the frame. All the around stuff, never the it stuff.

In other words, to do great web design you have to design in the Web, not in some other medium for the Web. I mean, serious magazine firm employs designers who don’t understand how to work with page layout programs like InDesign. Why, then, do so many web design agencies employ designers who don’t know how to work with web technologies, or even how to use programs like Dreamweaver? It doesn’t really make any sense, and it’s no wonder that the resulting implementation is rarely top-notch work.

But if you’re a graphic designer who doesn’t know much about Web technologies, what are you to do? Well, as a first step, I think you should pick up my new book, Foundation Website Creation. It’s available from all good booksellers (and probably some crappy ones) as of today. The book is targeted towards all manner of web professionals, including graphic designers and website producers, who want to learn more about what it takes to actually implement a site.

If I do say so myself, the chapters on XHTML and CSS are exceptionally thorough. The book doesn’t try to turn you into an exceptional programmer. Instead, it will explain the foundational concepts you need to know to understand how XHTML and CSS actually work, and in so doing will enable you to use the tools you already know to solve problems and get things done.

I think this book will be an excellent starting point for lots of designers and other web professionals. However, it is not going to take you from zero to hero—no book can. That’s why I recommend that, after you read Foundation Website Creation and have a solid grasp of what the technology can do for you and how it actually does it, you next take a look at these excellent books:

  • DOM Scripting by Jeremy Keith — if you’re a designer that needs to add a behavioral layer with JavaScript and Ajax to your pages, you need to read this book next.
  • Mastering CSS with Dreamweaver CS3 – if you’re familiar with Dreamweaver and want to keep using it to create standards-based web sites, then I recommend you follow Foundation Website Creation with this book by Stephanie Sullivan and Greg Rewis to take your Dreamweaver skills to the next level.

As always, most of all, have fun. Because if you’re not having fun, you’re not going to make good web sites no matter what you know.

Note: As of this writing, the book listing on Amazon still publishes the wrong author list, which is very frustrating but out of my hands. At least the image of our book’s front cover lists the correct authors.

Arbitrarily exclude posts from displaying in WordPress

9 comments

When hacking away at WordPress sites, often times you’ll find yourself in a situation where you need to filter out certain posts from displaying on some pages, such as the home page. There are a lot of ways to do this, but few are perfect. Recently, I had the need to do this and went searching for pre-existing solutions.

I came across Vaibhav’s post on the topic and noted that his solution uses the query_posts() function to alter WordPress’s query object before The Loop has run. While this is a great solution if your exclusion criteria is simple enough to be supported directly by the WordPress query object, other times the query_posts() function doesn’t provide you with the hook you need.

In these cases, you can run the original query, note any modifications you need to make, and then create a new, modified query and display the results you get from running that one instead. For instance, you might need to do this if you need to exclude posts based on category and, say, the beginning of their title, or their category and a certain piece of content in the post itself, or all three, or any other combination you can think of.

Another advantage of this technique over simpler ones is that this method maintains the same behavior you’d expect to see in every other way. Most notably, this means that if you’ve told WordPress to display the 10 most recent posts on the home page (in the WordPress settings), you’ll still see ten posts on that page even after you exclude some of them.

To do something like excluding posts if they are in the “Uncategorized” category (traditionally the category with an ID of 1 in WordPress) and their title begins with “Some title”, you can do this:

// original query runs in The (real) Loop first
while ( have_posts() ) : the_post();
    // detect pots matching our exclusion criteria
    if (in_category(1) && (0 === strpos(the_title('', '', false), 'Some title')) ) {
        $wp_query->post_count++; // increment the post counter
        continue;
    }
    endif;
endwhile;
// now make a new query and show the posts for real, with the adjusted post count and filtering
$my_new_query = new WP_Query($query_string.'&showposts='.$wp_query->post_count);
// do another The Loop (and display the results this time)
while ( $my_new_query->have_posts() ) : $my_new_query->the_post();
    // detect and exclude these same posts
    if (in_category(1) && (0 === strpos(the_title('', '', false), 'Some title')) ) { continue; }

// ...the rest of the WordPress template goes here...

This is neat because it gives you the capability to define arbitrarily complex exclusion patterns and directly modify your new query object however you like before you execute it. Once you know this works, you’ll probably want to extract the filtering code into a function. Using the above example, your new code might look like this:

// define criteria for filtering
function matches_filtering_criteria () {
    if (in_category(1) && (0 === strpos(the_title('', '', false), 'Some title')) ) {
        return true;
    } else {
        return false;
    }
}
// original query runs in The (real) Loop first
while ( have_posts() ) : the_post();
    // detect pots matching our exclusion criteria
    if (matches_filtering_criteria()) {
        $wp_query->post_count++; // increment the post counter
        continue;
    }
    endif;
endwhile;
// now make a new query and show the posts for real, with the adjusted post count and filtering
$my_new_query = new WP_Query($query_string.'&showposts='.$wp_query->post_count);
// do another The Loop (and display the results this time)
while ( $my_new_query->have_posts() ) : $my_new_query->the_post();
    //
    // detect and exclude these same posts
    if (matches_filtering_criteria()) { continue; }

// ...the rest of the WordPress template goes here...

For more information on these functions, see:

Written by Meitar

June 6th, 2008 at 1:11 pm

I’m getting a book published and it’s called Foundation Website Creation

9 comments

For those who have been wondering what is keeping me so busy these days, the answer is that I’m working on the final stages of a book that is getting published as one of three co-authors. Not only am contributing three chapters (the technical chapters on (X)HTML and CSS, specifically), but I am also technically reviewing the entire book.

My co-authors on the book, called Foundation Web Standards Foundation Website Creation (you can pre-order now) and published by Friends of ED, an Apress company, are Jonathan Lane of Industry Interactive, Inc. and Joe Lewis, who blogs at Sanbeiji.com. I’m not going to say much more until after the book is released in late July.

For the eager, here’s the description of the book posted on the Friends of ED website:

Foundation Website Creation explores the process of constructing a web site from start to finish. There is more to the process than just knowing HTML! Designers and developers must follow a proper process to flush out goals and objectives and determine requirements both prior to, and during project development.

Large Web projects are rarely completed by a single person. Producers, project managers, designers, developers, writers, and editors all play critical parts in a project’s evolution. This book provides an overview of the entire process, and also shows project development from the perspective of these different roles. It introduces the key concepts and duties performed by every member of such a team, and gives you the skills necessary to tackle projects like a professional.

It’s quite exciting getting a book out, and it’s quite a bit more work than I’d have ever originally thought. That being said, it’s extremely rewarding. There’s a lot more work I need to do on it between now and the time it gets released to publishing, so, well…back to work I go.

Now you all know where I’ve been spending my time writing.

A web developer’s introduction to the Apple WikiServer (part 2)

3 comments

Last time, we checked out the Apple WikiServer from the user’s side of things. We learned about the code it generates, how it handles page name changes, and what the key filesystem locations the Apple WikiServer looks at are. This time, let’s delve a little deeper into the WikiServer’s internals by (safely) messing around with a running instance and seeing how we can effect changes that aren’t available in the GUI.

I’m going in!

Apple’s WikiServer keeps each group’s data segregated. There’s currently no way in the GUI to search across multiple wikis from a single wiki, or move one wiki page in one wiki to another wiki. Luckily, because the Apple WikiServer is a rather lightweight application, it’s not that hard to move things around. Doing so doesn’t seem to cause any problems with the application, either—a testament to its apparent simplicity.

Most simply, say you have created a number of different wikis for different groups, and in so doing you’ve created segregated spaces for different parts of your organization. Now say you’ve got a wiki page in one wiki that you’d rather place in a different one, or that you’d like to copy. Sure, you can edit the first wiki’s page, copy the WYSIWYG editor’s text, and paste it into a new page on the second wiki. But where’s the fun in that?

Instead, let’s move some files around to get a sense for how the Apple WikiServer stores its data.

First, recall that the Apple WikiServer stores its content inside the /Library/Collaboration directory on the computer hosting the wiki web site. Inside of this directory you’ll find four items:

$ cd /Library/Collaboration/
$ ls -la
total 8
drwxrwxr-x   6 _teamsserver  _teamsserver   204 Mar  2 13:50 .
drwxrwxr-t@ 60 root          admin         2040 Mar  3 19:16 ..
drwxr-xr-x   2 _teamsserver  _teamsserver    68 Mar  2 13:50 ArchivedGroups
drwxr-xr-x   6 _teamsserver  _teamsserver   204 Apr  4 18:48 Groups
drwxr-xr-x   2 _teamsserver  _teamsserver    68 Mar  2 13:50 Users
-rw-r--r--   1 _teamsserver  _teamsserver   249 Mar  2 13:50 dataVersion.plist

First, note that all of these files are owned solely by the _teamserver user, and only that user can access these files in any way. This keeps people like you and me from accidentally tampering with the Apple WikiServer data store. However, for the purposes of this exercise, we’re going to tamper anyway. To do so, you’ll need root permissions, which comes with a big caveat: be careful whenever you are root—one typo could erase your hard drive (and there is no undo)!

Become root by saying:

sudo su -

and supplying your password. Once you are root, you can explore further into the depths of the Apple WikiServer.

Inside the Apple WikiServer data store for wiki pages

The Apple WikiServer, which runs under the username _teamserver, is really just a bunch of organized flat files, supplemented with a number of SQLite databases (also flat files, really), and glued together with a bunch of Python scripts running under the Twisted networking framework. We’re not going to cover Python or Twisted in this post, so for further information check out their respective homepages. There’s also a great introduction to Twisted at ONLAMP.com.

To make the wiki go, the WikiServer runs these scripts to read and write data to these flat files. Let’s dig into this data store. Since the wikis are each associated with an existing group, all of the wiki files are inside the Groups subdirectory. In this directory, you’ll find one directory for each group that has a wiki. Each group directory, in turn, contains 6 other directories, 2 regular files, and 1 SQLite database:

# pwd
/Library/Collaboration/Groups/chiefs
# ls -p
discussion/	index.db	metadata.plist	resources/	wiki/
extrainfo	mailinglist/	public/		weblog/

The two regular files are metadata.plist and extrainfo. The metadata.plist file maintains the preferences of the individual wiki web site that you set from the “Group Settings” page on the wiki web site itself. That is, these settings are all editable via the web directly at http://your-server.local/groups/your-group-name/settings/. That page is also accessible to an admin user from the wiki home page under the “Admin functions” header in the sidebar of the web page (the key names in the plist file are pretty self-explanatory and map easily to the GUI options).

At the moment, the extrainfo file is a bit of mystery. It stores single lines of plain ASCII text in the form:

groups/your-group-name/web-service/page-id

where your-group-name is the name of the associated group for the file, web-service is one of wiki, weblog, and I assume can also be mailinglist or discussion, although I’ve only seen the first two on my server in practice.

What we’re most interested in for the purposes of wiki pages is, unsurprisingly, the wiki directory. This directory stores as many subdirectories as there are pages on your wiki. Every time you create a new page, a new directory is added here. If you delete that page, however, this directory is not deleted outright.

Each directory is named with the unique page identifier that the Apple WikiServer automatically generates followed by a .page extension. The exception is the welcome.page directory, special in that it contains the content of the wiki’s main (front) page. The Mac OS X Server Web Technologies Administration for Version 10.5 Leopard manual explains the contents of this directory as follows:

  • /Library/Collaboration/Groups/groupname/wiki/pagename.page/ contains the component files of a wiki page.
  • /Library/Collaboration/Groups/groupname/wiki/pagename.page/page.html contains the main text of the wiki (html content).
  • /Library/Collaboration/Groups/groupname/wiki/pagename.page/page.plist contains the metadata for the wiki page.
  • /Library/Collaboration/Groups/groupname/wiki/pagename.page/revisions.db contains the version history database for that wiki page.
  • /Library/Collaboration/Groups/groupname/pagename.page/images/ contains the images for that wiki page.
  • /Library/Collaboration/Groups/groupname/pagename.page/attachments/ contains all attachments for that wiki page.

Here are some additional details:

  • The “page.html” file contains all of the (X)HTML that appears inside the WYSIWYG editor field when you click the “Switch to HTML View” button (the arrow brackets). Nothing more, and nothing less.
  • The “page.plist” file maintains the metadata that associates a single wiki page to its group as far as the Apple WikiServer is concerned. If you take a closer look at it, you’ll find property list keys such as commentUID and uid whose values are both strings—URLs, in fact—that the Apple WikiServer uses to, for example, call the appropriate wiki theme to render around the page content. This file also stores self-explanatory data such as author, createdDate, page kind, a last modifiedDate and lastModifiedAuthor and, of course, the page title. The most interesting key in this file is the versioned key, which is a boolean that can turn versioning on or off. By default, wiki pages have this key set to true and (for example) weblog pages have this set to false. However, you can manually turn off versioning for a specific wiki page by changing this key yourself. It won’t delete past revisions, it will just stop new revisions from being saved. This is especially cool, because it means you can version-control weblog pages simply by editing the page’s associated plist file.
  • The revisions.db is the SQLite database in which all revisions are stored. The database contains a single table, revisions, that looks like this:
    CREATE TABLE revisions(revision INTEGER PRIMARY KEY AUTOINCREMENT, editType, comment, lastModifiedBy, content, time DEFAULT CURRENT_TIMESTAMP);

    The interesting bit is the content field, which itself is just a string—but a string stored as an Apple property list, in full. Some keys in the property list inside the SQLite database are the same as those inside the page.plist file for the page, but with some differences. For instance, there is no versioned key in the plist in the database (for obvious reasons), and there is a tags key (which is missing from the filesystem equivalent). Most importantly, there is a content key, which stores the content of the page.html file.

  • The revisions.db file is created automatically only if the versioned key in the page’s page.plist file is set to true.

Finally: move a wiki page from one wiki to another

Now that we understand some of the internals of the Apple WikiServer data store, let’s mess with it just a little by moving that one test wiki page from one wiki into another. Since almost everything is flat files, it’s remarkably easy to do:

# mv /Library/Collaboration/Groups/your-group-name/wiki/page-id.page /Library/Collaboration/Groups/new-group-name/

Be certain that there isn’t already an existing page in the new-group-name wiki with the same page-id as the one you’re moving. So far, Apple WikiServer appears to generate unique page IDs across the entire system (as opposed to just per-group), but I haven’t verified this yet.

With the wiki page files physically moved into the new wiki, you can now access the page at the new wiki URL. Trying to access it in the old URL will result in an HTTP 404 “Not Found” error. However, the page at the new wiki URL has the same theme as the other, old wiki. To correct this, you need to edit the page.plist file in two places: the uid string value and the commentUID string value relative URLs need their your-group-name changed to the new-group-name, whatever it is.

After you save this this change, simply reload the wiki page in your browser. Voila. Page moved.

 

Written by Meitar

April 8th, 2008 at 4:12 am

A web developer’s introduction to the Apple WikiServer (part 1)

10 comments

I absolutely love wikis, so when Apple introduced Mac OS X Server 10.5 “Leopard,” one of the new features I was really excited about was “WikiServer” (what the Apple marketing department calls “Teams”). I’m calling this specifically the Apple WikiServer in order to avoid confusion with the pre-existing wiki plus web server package called WikiServer.

Apple WikiServer: Mac OS X Server’s built-in Intranet builder

At work, I’m finally getting the opportunity to try the Apple WikiServer out. Its strongest asset, by far, is the integration it has with Apple’s Mac OS X permission scheme. Apple WikiServer makes heavy use of the OS‘s built-in user accounts to define users and groups, and the permissions those users and groups have to edit, view, and comment on pages in the wiki you create with it. And, because Leopard Server has full support for Access Control Lists, those permissions schemes can be as complex as you like.

This is very important because many large (and small) organizations have sensitive material that they’d like to keep private, or restricted to certain groups. Historically, wikis are a free-for-all. Anyone and everyone who has access to any part of the wiki can change any other part of the wiki. Recent wiki implementations such as later version of MediaWiki and some other wiki software have implemented permissions systems to allow administrative users to control access rights, but these are often complicated or require code-level configurations.

With Apple’s WikiServer, all of these permissions can be managed via the Workgroup Manager application, and because you can take advantage of the built-in ACL support, you can model your organizations permissions scheme directly in the Server OS permissions structure, giving you a much easier way to control information access. Take note, however, that like almost all other things that have to do with your Apache configurations, your Server’s Web Service will likely need to be stopped and started again for any changes you make to a wiki’s permissions take effect.

The Workgroup Manager application is also where you go to create new wikis for groups. To enable a wiki, you need to already have created a group and assigned users to that group. For instance, I created a Developer Wiki where all of the in-house developers can share tech tips, so I created a group called “Developers” and assigned individual developers, as well as the company executives (by way of the “Executives” group) to that group. The group-within-a-group technique is key, because if the company executives change, the members of the Developers group does not need to change, too. In all of Apple’s publications, Apple refers to the wikis hosted by WikiServer as an “intranet website.”

It’s clear that Apple intended this product for use within small companies, and not necessarily out on the open Internet. What follows are just a few notes I’ve compiled about how the Apple WikiServer works.

Front-end Code Generation from the Apple WikiServer WYSIWYG Editor

The Apple wikis are very nice to use. Their functionality is relatively straightforward to find and activate. However, the HTML code that the Apple wikis generate can be a little confusing. By default, new page text is entered into a semantically meaningless <div> element. This can be changed by highlighting text and then selecting “Paragraph” from the formatting toolbar. Subsequent paragraphs that are typed seem to then use <p> elements. However, some paragraphs revert back to <div>s when I used it, and I’m still not sure why or when this occurred.

On the plus side, so far, all the browsers I’ve used with the Apple WikiServer function the same way. This include Firefox 2, Safari 3.1, and Internet Explorer 6 and 7.

Typing actual code and having it marked up as such can’t be done in the GUI formatting toolbar to select a <code> element. The “Monospace” item in the text formatting toolbar creates <pre> elements and <pre> elements only. However, Apple does provide a “Switch to HTML view” button (the arrow brackets button) and one can enter standard HTML, including <code>…</code> elements in that view, and then switch back. This behaves perfectly on all browsers except Internet Explorer, in which your text area field shows no line breaks whatsoever.

Apple’s WYSIWYG editor handles escaping special characters when those special characters have HTML entity reference equivalents, such as double quotes (“), arrow brackets (< and >), and ampersands (&). It does not seem to handle Unicode characters, such as the ellipses in the prior paragraph. However, such Unicode characters need not be escaped as long as the document’s character set is UTF-8 (or UTF-16), which the Apple WikiServer specifies and supports out of the box.

Pressing the Return key twice causes the Apple wiki to generate an empty <div> or <p> element with an explicit break (<br />) inside of it. One can deduce that this is a design choice in order to help transition users who are used to plain <textarea /> inputs to Apple’s WYSIWYG editor. It’s also the only way to space paragraphs properly if the user hasn’t selected the “Paragraph” option in the text formatting toolbar. Otherwise, simply hitting the Return key once is enough to space paragraphs apart properly (i.e., the functionality is equivalent to the way Microsoft Word or Pages handles paragraph breaks).

Interestingly, the “Enter URL…” functionality form the toolbar is smarter than one might first assume. For instance, it recognizes email address and prepends a mailto: scheme to the link if it finds one. This is contrary to what the Apple-provided manual states, which tells you to enter the “mailto:” portion as part of the URL. In fact, you should omit this, else your final mailto link will actually read “mailto:mailto:your.email@address.com”.

This means linking to “mailto: links” is as simple as typing an email address. Similarly, the WYSIWYG doesn’t complain if your fully-qualified URL doesn’t include a scheme, so you can enter //apple.com/ and the subsequent link is generated as <a href="//apple.com/">Link text</a>. This is one step above and beyond even WordPress’s new WYSIWYG editor, which forcefully prepends an http: scheme to URLs without one.

For the most part, copy-and-paste works as expected, except in cases where the WYSIWYG editor does not understand the current formatting, such as a specific font and (and this is a biggie) for links. At first, the editor will appear to show that the formatting (including links) is saved, but when you actually save the page, only the formatting that the WYSIWYG editor understands is actually saved. Worse, all your links are turned into underlined—but unlinked—text. In short, this means that if you are copying and pasting page content that contains links, you need to do so in the HTML view of the page editor.

Inexplicably, the editor generates <i> and <b> tags for italics and bold, instead of the preferred <em> and <strong> elements. I’m not sure I understand why this is the case. There does exist a an “emphasis” option in the toolbar, as does an “important” option, but these generate strange spans instead. The “Important” item wraps the selected text inside a <span class=”Apple-style-span custom_forecolor_important”>…</span> and the “Emphasis” item wraps the selected text inside a <span class=”Apple-style-span custom_forecolor_emphasis”>…</span> element.

There’s also one other item, “Highlight,” which wraps the selected text inside of a <span class=”Apple-style-span custom_backcolor_highlight”>…</span> element.

The only explanation that makes sense to me, after much speculation, is that perhaps Apple does not want to encode semantic information such as what <em> and <strong> would imply from users who use a WYSIWYG editor. This shows either a blatant distrust of users or incredible foresight. I’m not sure which.

Page names and URLs

Currently, the search functionality built into Apple’s WikiServer only searches on the text of a page’s title.

Apple’s WikiServer generates unique page names for each new wiki page. These names consist of two parts, but only one seems to make any difference. For example, if you create a new Wiki page called “Hello”, you might get an address in your web browser’s location bar that looks like this:

http://your-server.local/groups/your-group-name/wiki/1d06a/Hello.html

Most of this is standard URL stuff (the protocol, the server address), and most of the rest is self-explanatory (the group name, the wiki section). The important bits in this URL are the last two:

  • 1d06a
  • Hello.html

Obviously, “Hello.html” came from the fact that you named your new page “Hello”. WikiServer appended “.html” on its own. The other bit, the short string of random characters, is a unique identifier used across all of this group’s web services (the wiki, blog, calendar, and mail list, if these other services are enabled) to uniquely identify this page. What’s interesting about this is that only the unique string of characters seems to matter in regards to accessing the page. That is, if you next ask for:

http://your-server.local/groups/your-group-name/wiki/1d06a/Some-Random-Page.html

you’ll still get the same “Hello.html” page from before, even though you’re seemingly asking for “Some-Random-Page.html”. In fact, it doesn’t seem to matter what you replace “Some-Random-Page” with. So long as there is some text in that part of the URL, that the URL ends with “.html” and that the unique identifier remains untouched, you’ll always end up retrieving the “Hello.html” page.

This means that if you change this page’s name later to, for instance, “Hello world”, old links that point to “…/1d06a/Hello.html” will continue to work, even while new links will start to point at “…/1d06a/Hello_world.html”. From a usability perspective, this is simple and effective; it ensures that users have a reminder of what the page is about by looking at the last part of the URL. However, once page names change, it becomes a bit non-optimal, because the same page can be referred to by multiple names—a “no-no” in the SEO world and a practice discouraged by most semantic-web types.

I would imagine that Apple made this design decision because the company envisioned their WikiServer to be used, again, primarily in intranet and SOHO environments, and as a result are not too concerned with search engine optimization. As an aside, this unique string is also how Apple’s WikiServer identifies the stored content on the filesystem. Read on for more details.

Hacking the Apple WikiServer

There isn’t a lot of information out on the Web right now about how to work with the WikiServer, especially for developers. Therefore, some digging is needed. After a bit of research, I discovered the following key directories that the WikiServer uses. They are as follows:

  • /usr/share/collaboration - This has a few developer tool support files as well as the majority of the client-side code for the Wiki (javascripts, etc).
  • /usr/share/wikid - This directory holds the Python sources and compiled bytecode for all the “Teams” components (including wiki, blog, calendar, etc.). It seems to run on Twisted and a number of other familiar-sounding components.
  • /Library/Application Support/Apple/WikiServer - This is where most the data is stored, inside of plist files and a few others. The Themes subdirectory here is where Apple recommends that look-and-feel changes be made.
  • /Library/Collaboration – This is the default data storage location for all the “Teams” components. The actual content of the wikis and blogs will be kept somewhere in this directory, which means that this is the directory you want to backup to backup the content of your wikis. This location is the only user-configurable one of the bunch. To change it, change the “Data Store” value in Server Admin. (A more detailed listing of this directory hierarchy is available on page 62 of the Mac OS X Server Web Technologies Administration For Version 10.5 Leopard manual.)

If you take a peek at the /Library/Collaboration directory, and follow that into the Groups/your-group-name/wiki directory, you’ll find a list of all the pages in your wiki stored as .page bundles, identified with the unique character string WikiServer generated when it first created the page.

It should be noted that anything in the /usr/share directory will likely be overridden whenever Apple releases an update that modifies the WikiServer. As a result, any and all changes you make to WikiServer’s templates or themes should be done by creating new files in the /Library/Application Support/Apple/WikiServer/Themes directory.

It’s interesting to note that the WikiServer seems to use Python for its back-end processing. This may open up some interesting integration possibilities for Python programmers in the future.

More help eslewhere

Even though Apple WikiServer is relatively new, there’s a load of helpful information about it on the web. Most of the good stuff is on Apple’s own Discussions boards, but more and more info is beginning to show up on blog posts. A Google search should give you what you need. For the really lazy, however, here are a few helpful items:

This was just a brief introduction to WikiServer from some notes I’ve been collecting in my experimentations, but I hope it’s helpful to someone somewhere. Cheers. Or, continue to Part 2.

Written by Meitar

April 5th, 2008 at 5:10 am

No-Framework Ruby on the Web using eRuby on Mac OS X

16 comments

I have a suspicion that there are a lot of web developers out there who, like me, are eager to start learning more about Ruby but who are stunted by the incredible amount of unfamiliar conventions that are used in Rails. For many of us, our first introduction to Ruby was (or is) through Rails and the challenge of learning both Ruby and Rails at once should not be underestimated; frankly it’s damn hard.

Thankfully, there’s an easier way. Especially if you’re accustomed to “old-school” development workflows that you learned through, say, PHP or perhaps Perl scripting, then ditching Rails and starting purely with Ruby might be the way to go. Doing things on your own without the “magic” of Rails will let you learn Ruby in a simple, yet fully-featured environment, much like the way you might have learned classic CGI programming.

Specifically, by using eRuby, the Embedded Ruby interpreter, you can make Ruby web development feel just like PHP development. Install it, upload an HTML file with some embedded Ruby code in it, and—voila—you have a single-page web application.

Why this tutorial?

Hivemind’s Getting Started with Ruby on the Web is an excellent resource that described this process from start-to-finish for Windows users. In fact, it was after finding that article that I realized web development with Ruby didn’t have to be governed by Rails and, being a web developer like the authors of Hiveminds, I wanted an easy way to use my Ruby knowledge on the Web.

However, I couldn’t find any similar tutorial or walkthrough for those of us who use Macs. Even the Linux walkthroughs are lacking (or at least my Googling skill for them is). After spending a little while successfully getting eRuby set up on my Mac running Mac OS X 10.4 Tiger, I thought I’d share what I learned with others, so I wrote this article. Its content mirrors the one from Hiveminds to a great degree but focuses on getting eRuby installed on Mac OS X instead of Windows (obviously). I imagine these instructions should be pretty similar if not identical for any other *nix-like platform.

The Setup

Getting eRuby installed and configured with your web server is actually pretty straightforward and won’t take an experienced web developer much time at all. All we’re going to need is the Apache web server and the Ruby programming language to start, both of which are already pre-installed on Mac OS X 10.4 Tiger. (And in Mac OS X 10.5 Leopard, Apple is even shipping new Macs with Ruby On Rails preconfigured, but that’s a subject for another time.) However, Apple typically ships an older copy of Ruby than is readily available, so you might choose to use a newer version of Ruby that you download yourself.

The easiest way to get a copy of eRuby (and an updated Ruby, if you want it) is with a package manager such as MacPorts. With MacPorts installed (which is a simple, standard package installation downloadable from the MacPorts home page), simply run

sudo port install eruby

from your terminal to download the latest stable Ruby and eRuby in one fell swoop. After this runs, you’ll have a new Ruby in /opt/local/bin/ruby and an eRuby in /opt/local/bin/eruby. Alternatively, of course, you could compile and install eRuby yourself. Instructions for that are on the eRuby homepage.

As a quick test to see if everything is installed and working correctly, create a plain text file with your favorite editor that contains the following code:

Hello world! The time is now <%= Time.now %>.

All this does is print out a “Hello world!” greeting and then announces the current time (as reported by your system clock, of course).

If you named the above file helloworld.rhtml then you can feed this file to the eruby interpreter as follows:

eruby helloworld.rhtml

Note that the file extension doesn’t actually matter. You could use .erb, if you like, or any other arbitrary file extension. The file extension is, as you’ll see later, only used for telling Apache which kind of file it is. So once you come up with file extension you like, stick with it. The standard file extensions are either .rhtml or .erb, so I’d recommend using one of those. (I prefer .erb, myself, since I don’t necessarily only want to create HTML pages. I might want to create XML documents like news feeds or even XML databases, so .erb seems a more reasonable file name extension, though most of the eRuby documentation uses .rhtml.)

If things worked properly, you should see output similar to the following:

Hello world! The time is now Wed Oct 24 21:58:54 -0400 2007.

Serve it up!

Now that eRuby is installed and working, the next step is to set it up as a CGI so that when your web server (Apache, in my case) fetches the file it will first feed it through eRuby for processing before sending it back to the browser. The simplest way to do this is to configure Apache to use a specific directory somewhere on your filesystem as a CGI directory—that is, a directory whose contents are all treated as CGI programs. You do this via Apache’s ScriptAlias directive.

Conveniently, standard installations of Mac OS X already come with a CGI directory. It’s located at /Library/WebServer/CGI-Executables. This directory is just like any other, except that Apache treats it specially. It treats it specially because Apache’s configuration file, /etc/httpd/httpd.conf contains a line of text that reads as follows. (On a standard installation of Mac OS X client, this is line 671 of the file.)

ScriptAlias /cgi-bin/ "/Library/WebServer/CGI-Executables/"

This line basically just tells apache, “Treat every file in the /Library/WebServer/CGI-Executables directory as though it were a CGI program.” So, since that’s how we’re treating eRuby, we’re going to want to put our eruby binary in that directory. However, we don’t actually want to make copies of the binary. Having too many copies of a program on your system can easily get confusing. So instead, we’ll make a symbolic link (or an alias to use the classic Mac terminology) to the binary.

ln -s /opt/local/bin/eruby /Library/WebServer/CGI-Executables/eruby

With our eruby CGI executable in the proper place for Apache to find it, we can now tell Apache which files we want it to send to this program. We do this using the AddHandler and Action directives.

AddHandler simply tells Apache to treat files with a certain extension in a certain way. For instance, you can say something like, “Treat all files ending in .php as PHP scripts.” Similarly, you can (and will) tell Apache, “Treat all files ending in .rhtml or .erb as eRuby CGI pages.”

To do this, we add the following line to our /etc/httpd/users/username.conf file somewhere inside the <Directory> and </Directory> block. Naturally, replace username with, of course, your Mac OS X user’s short name:

AddHandler rubypage .erb .rhtml

Again, this just tells Apache that files ending in .erb and .rhtml should be treated the same way other rubypages are treated. But how are eRuby pages supposed to be treated? They’re supposed to be handed off to the eRuby program, of course, so we need an Action directive that applies to the rubypage handler we just defined.

Right below the above line, add the following line, too:

Action rubypage /cgi-bin/eruby

This line tells Apache that any file that it is treating as a “rubypage” file should be sent to the program at the URL accessible at /cgi-bin/eruby, which we’ve defined earlier to be our symbolic link to the eruby interpreter.

Your completed user-specific Apache configuration file should now look something like this:

<Directory "/Users/username/Sites/">
…
    # Let eRuby files get parsed through the proper CGI binary
    AddHandler rubypage .erb .rhtml
    Action rubypage /cgi-bin/eruby
</Directory>

Are You Being Served?

That’s it, everything should now be in place. To make sure, move your earlier helloworld.rhtml file into your user’s Sites folder, and now simply point your browser to http://localhost/~username/helloworld.rhtml (again, replacing username with your Mac OS X user short name, of course). Congratulations, you’re serving up Ruby-coded applications via eRuby.

Additional Reading

This is just the set up, of course. Now the real fun begins: learning Ruby. Here are some suggested places to start.

Naturally, feel free to leave comments if you have more resources that you found helpful.

Written by Meitar

October 25th, 2007 at 12:00 am

Window and Element Resizing Annoyances in Internet Explorer

leave a comment

This has been an interesting day. In less than 8 hours, I’ve had to tackle the following IE nuisances:

document.body vs. document.documentElement

In IE 6, in order to access the current width of the window in JavaScript you need to get document.body.clientWidth only if you’re in quirks mode. If you’re in standards mode, this property not only still exists, but it means something entirely different! It instead refers to the width of the body element.

This causes real trouble for some scripts when the value of the this variable seems to suddenly become frozen or fixed at a single value instead of changing appropriately on a window resize event. Instead of document.body.clientWidth, in standards mode, use document.documentElement.clientWidth. (Reference table at QuirksMode.org)

Internet Explorer crashes when attempting min-width

If you use IE‘s proprietary expression() syntax to script a CSS value, beware of calculating widths or heights that exactly match the value you’d like to set. If you do something like the following to set a minimum width on #someElement, IE will crash when you actually resize that element to be 500 pixels wide.

#someElement { width: expression(document.body.clientWidth < 500 ? "500px" : "auto"); }

Instead of doing the above, you should check for almost exactly the size you want, like so:

#someElement { width: expression(document.body.clientWidth < 501 ? "500px" : "auto"); }

However, the really important thing to keep in mind is that the minimum width you’re testing (501 in that second case) needs to be at least one pixel greater than the total content and padding width of the element. So if you have an element that needs to be no less than 500 pixels wide but also has 10 pixels of left and right padding, you need to check not for 501 pixels in width, but rather for 521 pixels in width. (Reference on CameronMoll.com.)

Written by Meitar

May 24th, 2007 at 5:30 pm

The Importance of Naming Conventions in Collaborative Web Production

one comment

It strikes me as very, very interesting how, especially in the world of technology where everything is thought to be so regimented and precise, where a single typo can be the difference between compilation and error, that there is so much versatility in every step of the creative process. This is, of course, a result of the nature of the industry, that being a knowlege-based economy, but the observation still holds strength.

I’m beginning a new project at work where, for the first time, I’m working with a large team of developers, and not just integration developers but front-end developers like myself. Since I’m the new guy, I’m finding myself required to learn the teams established vocabulary and this is making me realize just how much of my own vocabulary I have developed myself without even realizing how large it’s grown.

It all comes down to how we organize our code and that, of course, depends very much on how we are used to thinking about things. On a team of people working together for a common goal, such implementation-specific details are much more central to the success of the project than when working alone, such as in a freelance situation.

It’s interesting to me to see how many of the the established coding standards and naming conventions are obviously built off of the same kinds of ideas that I’ve already had and have been using for quite some time, and yet how different they are in implementation. This extends beyond the obvious case of using dash-separated class and ID names instead of camel case lettering or vice versa. It goes so far as to project management and workflow considerations, file name conventions, and semantics.

In some cases, optimizations are actually sacrificed on a team in favor of clarity, but this is actually a good thing. In my freelance work, I typically squeeze every last ounce of optimization into a project by using shorter names, more optimized files, and extremely dense code to ensure the best possible result. In a project with other developers however, the success of the project is far more dependant on everyone’s collective understanding of the code, so clarity is and should be prioritized above optimizations.

Written by Meitar

May 3rd, 2007 at 10:02 pm

Making code maintainable: mind your edit-per-change ratio

leave a comment

One of the most fundamental problems when dealing with the world on any level, whether your issue is technological, physical, or conceptual, is handling change. People are fond of saying that the only constant in the world is that things will change. That’s certainly true, but that nugget of wisdom doesn’t actually tell us what to do about all these inevitable changes.

In some industries, such as construction (for example), people are very careful about what they do because they know how hard it will be to change something after the fact. In the digital workplace, however, people don’t seem to think as much about this sort of thing because it’s relatively easy to change things. After all, everyone’s dealing in bits and bytes at a fundamental level. However, if you take a higher-level look, you’ll see that many times things are not as easy to change correctly as you might think, and the costs associated with these mistakes and after-the-fact edits can be enormous.

Take a web site, for instance. (I bet you saw that coming.) After a web site is launched (and even before, sometimes), changes have to go back and forth between designers and coders, production and design, and back again. Many times so-called final versions are just the next revision and not actually set in stone, no matter what anyone says. For a web developer, all these changes can be really troublesome, however they also provide an opportunity for rapid, iterative improvement of your (X)HTML and CSS code.

In a recent project I worked on, I found myself faced with the challenge of positioning two columns of data that each had a different number of elements inside of them but that ultimately had to be the exact same total height. My production manager, who fell in love with floated layouts a long time ago, wanted to position the page using one column floated left and the other floated right, with their dimensions fixed so as to give them both room to fit inside their parent. This seemed perfectly logical to me, so I implemented it that way.

As the project moved forward, however, I realized that in our design changes to this kind of floated layout would require a minimum of editing two files. First, we’d need to edit the HTML source of our page to change the order of the content boxes inside the floated columns, and second we’d need to change the dimensions of the elements in our style sheets. Instead, reimplementing the design with absolute positioning would require edits to only one source file, the style sheet itself, where both the position and the element dimensions could be specified in a single CSS declaration.

With all the frequent changes the design department was making, this argument ultimately won everyone over, and the site uses absolute positioning for the design. The key concept to take away from this experience is that part of making things easy in the future is to design with change in mind, to be as flexible as possible from the get-go, but also to think about the actual implementations in such a way as to lower your edit-per-change ratio as much as possible. The fewer things you have to change, the easier it will be to change things moving forward.

Written by Meitar

April 13th, 2007 at 2:48 pm

TEDTalks: Inspirational, incredible, and moving ideas

one comment

For those not yet familiar with it, TED is an invitation-only annual conference of some of the brightest and most talented individuals in all fields of Technology, Entertainment, and Design. For the first time (in February 2006), the presentations were recorded and broadcast to the world once per week at the TED.com web site.

I’ve just spent the past three and a half hours at the site watching the presentations and I’ll have to blame them for making me sleepy at work tomorrow. Nevertheless, they are some of the most compelling and fascinating presentations I have ever seen in my life. I highly, highly recommend that you spend a few moments to check them out.

For those interested in Human-Computer Interface design, you absolutely must view Jeff Han’s talk on an “interface-less” touch-screen-like display which will very likely obsolete the traditional mouse and keyboard.

For those interested in global health and economics, you absolutely must view Hans Rosling’s talk on the myths of the third world.

And for those who just want more proof how much Apple Computer rocks our socks, you must view David Pogue’s excellent presentation on the woes caused by software frustration (and it’s partially set to music).

My personal favorite (so far) was Sir Ken Robinson’s almost stand-up comedy approach to explaining to us why the current state of the world’d public education systems will not serve us for our future.