<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Everything In Between &#187; Web Design</title>
	<atom:link href="http://maymay.net/blog/category/web-design/feed/" rel="self" type="application/rss+xml" />
	<link>http://maymay.net/blog</link>
	<description>The brutally honest, first-person account of Meitar Moscovitz&#039;s life.</description>
	<lastBuildDate>Thu, 19 Jan 2012 08:54:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Cross-post: Edenfantasys&#8217;s unethical technology is a self-referential black hole</title>
		<link>http://maymay.net/blog/2010/05/19/web-merchants-inc-edenfantasys-unethical-technology/</link>
		<comments>http://maymay.net/blog/2010/05/19/web-merchants-inc-edenfantasys-unethical-technology/#comments</comments>
		<pubDate>Wed, 19 May 2010 23:20:04 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Business & E-Commerce]]></category>
		<category><![CDATA[Content Syndication]]></category>
		<category><![CDATA[Crosspost]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Maybe Maimed]]></category>
		<category><![CDATA[Search Engine Optimization]]></category>
		<category><![CDATA[Tech/Computing]]></category>
		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=1217</guid>
		<description><![CDATA[This entry was originally published at my other blog. I&#8217;m cross-posting it here in order to make sure it gets copied to more servers, as some people have suggested I&#8217;ll face a cease and desist order for publishing it in the first place. Please help distribute this important information by freely copying and republishing this [...]]]></description>
			<content:encoded><![CDATA[<p><em>This entry was originally published at <a href="http://maybemaimed.com/2010/05/19/edenfantasyss-unethical-technology-is-a-self-referential-black-hole/">my other blog</a>. I&#8217;m cross-posting it here in order to make sure it gets copied to more servers, as some people have suggested I&#8217;ll face a cease and desist order for publishing it in the first place. Please help distribute this important information by freely copying and republishing this post under the conditions of my <acronym title="Columbia College">CC</acronym>-BY-NC-ND license: provide me with attribution and a (real) back link, and you are free to republish an unaltered version of this post wherever you like. Thanks.</em></p>
<p>A few nights ago, I received an email from Editor of EdenFantasys&#8217;s SexIs Magazine, Judy Cole, asking me to modify <a href="http://kinkontap.com/?p=676">this Kink On Tap brief</a> I published that cites Lorna D. Keach&#8217;s writing. Judy asked me to &#8220;provide attribution and a link back to&#8221; SexIs Magazine. An ordinary enough request soon proved extraordinarily unethical when I discovered that <strong>EdenFantasys has invested a staggering amount of time and money to develop and implement a technology platform that actively denies others the courtesy of link reciprocity</strong>, <a href="http://www.ted.com/talks/jonathan_zittrain_the_web_is_a_random_act_of_kindness.html">a courtesy on which the ethical Internet is based</a>.</p>
<p>While what they&#8217;re doing may not be illegal, EdenFantasys has proven itself to me to be an unethical and unworthy partner, in business or otherwise. Its actions are blatantly hypocritical, as I intend to show in detail in this post. Taking willful and self-serving advantage of those not technically savvy is a form of inexcusable oppression, and none of us should tolerate it from companies who purport to be well-intentioned resources for a community of sex-positive individuals.</p>
<p>For busy or non-technical readers, see the next section, <a href="#executive-summary">Executive Summary</a>, to quickly understand what EdenFantasys is doing, why it&#8217;s unethical, and <a href="#how-this-affects-you">how it affects you</a> whether you&#8217;re a customer, a contributor, or a syndication partner. For the technical reader, the <a href="#technical-details">Technical Details</a> section should provide ample evidence in the form of a walkthrough and sample code describing the unethical Search Engine Optimization (<acronym title="Search Engine Optimization">SEO</acronym>) and Search Engine Marketing (<acronym title="Search Engine Marketing">SEM</acronym>) techniques EdenFantasys, <acronym title="Also Known As">aka</acronym>. Web Merchants, Inc., is engaged in. For anyone who wants to read further, I provide an <a href="#editorial">Editorial</a> section in which I share some thoughts about what you can do to help combat these practices and bring transparency and trust&mdash;not the sabotage of trust EdenFantasys enacts&mdash;to the market.</p>
<h2 id="executive-summary">EXECUTIVE SUMMARY</h2>
<p>Internet sex toy retailer Web Merchants, Inc., which bills itself as the &#8220;sex shop you can trust&#8221; and does business under the name EdenFantasys, has implemented technology on their websites that actively interferes with contributors&#8217; content, intercepts outgoing links, and alters republished content so that links in the original work are redirected to themselves. Using techniques widely acknowledged as unethical by Internet professionals and that are arguably in violation of major search engines&#8217; policies, EdenFantasys&#8217;s publishing platform has effectively outsourced the task of <a href="http://en.wikipedia.org/wiki/Spamdexing#Types_of_Link_Spam">&#8220;link farming&#8221; (a questionable Search Engine Marketing [<acronym title="Search Engine Marketing">SEM</acronym>] technique)</a> to sites with which they have &#8220;an ongoing relationship,&#8221; such as <a href="http://AlterNet.org/">AlterNet.org</a>, other large news hubs, and individual bloggers&#8217; blogs.</p>
<p>Articles published on EdenFantasys websites, such as the &#8220;community&#8221; website SexIs Magazine, contain <acronym title="HyperText Markup Language">HTML</acronym> crafted to look like links, but aren&#8217;t. When visited by a typical human user, a program written in JavaScript and included as part of the web pages is automatically downloaded and intercepts clicks on these &#8220;link-like&#8221; elements, fetching their intended destination from the server and redirecting users there. Due to the careful and deliberate implementation, the browser&#8217;s status bar is made to appear as though the link is legitimate, and that a destination is provided as expected.</p>
<p>For non-human visitors, including automated search engine indexing programs such as Googlebot, the &#8220;link&#8221; remains non-functional, making the article a search engine&#8217;s dead-end or &#8220;orphan&#8221; page whose only functional links are those whose destination is EdenFantasys&#8217;s own web presence. <strong>This makes EdenFantasys&#8217; website(s) a self-referential black hole that provides no reciprocity for contributors who author content, nor for any website ostensibly &#8220;linked&#8221; to from article content.</strong> At the same time, EdenFantasys editors actively solicit inbound links from individuals and organizations through &#8220;link exchanges&#8221; and incentive programs such as &#8220;awards&#8221; and &#8220;free&#8221; sex toys, as well as syndicating SexIs Magazine content such that the content is programmatically altered in order to create multiple (real) inbound links to EdenFantasys&#8217;s websites after republication on their partner&#8217;s media channels.</p>
<h3 id="how-this-affects-you">How EdenFantasys&#8217;s unethical practices have an impact on you</h3>
<p>Regardless of who you are, EdenFantasys&#8217;s unethical practices have a negative impact on you and, indeed, on the Internet as a whole.</p>
<div class="admonition tip" style="float: right; width: 33%; margin: 0 0 1em 1em;">
<strong>See for yourself</strong>: First, <em>log out of any and all EdenFantasys websites</em> or, preferably, use a different browser, or even a proxy service such as <a href="http://torproject.org/">the Tor network</a> for greater anonymity. Due to EdenFantasys&#8217;s technology, <em>you cannot trust that what you are seeing on your screen is what someone else will see on theirs.</em> Next, temporarily disable JavaScript (<a href="http://www.tucows.com/article/1690">read instructions for your browser</a>) and then try clicking on the links in SexIs Magazine articles. If clicking the intended off-site &#8220;links&#8221; doesn&#8217;t work, you know that your article&#8217;s links are being hidden from Google and that your content is being used for shady practices. In contrast, with JavaScript still disabled, navigate to another website (such as this blog), try clicking on the links, and note that the links still work as intended.</p>
<p><strong>Here&#8217;s another verifiable example</strong> from the EdenFantasys site showing that many other parts of Web Merchants, Inc. pages, not merely SexIs Magazine, are affected as well: With JavaScript disabled, visit the <a href="http://www.edenfantasys.com/sex-community/companies/aslan-leather/" rel="nofollow">EdenFantasys company page on Aslan Leather</a> (note, for the sake of comparison, the link in this sentence will work, even with JavaScript off). Try clicking on the link in the &#8220;Contact Information&#8221; section in the lower-right hand column of the page (shown in the screenshot, below). This &#8220;link&#8221; <em>should</em> take you to the Aslan Leather homepage but in fact it does not. So much for that &#8220;link exchange.&#8221;<br />
<a href="http://maybemaimed.com/wp-content/uploads/2010/05/edenfantasys-company-contact-information.png"><img src="http://maybemaimed.com/wp-content/uploads/2010/05/edenfantasys-company-contact-information-300x266.png" alt="" title="edenfantasys-company-contact-information" width="300" height="266" class="size-medium wp-image-1752" /></a><br />
(Click to enlarge.)
</div>
<ul>
<li><strong>If you&#8217;re an EdenFantasys employee</strong>, people will demand answers from you regarding the unethical practices of your (hopefully former) employer. While you are working for EdenFantasys, you&#8217;re seriously soiling your reputation in the eyes of ethical Internet professionals. Ignorance is no excuse for the lack of ethics on the programmers&#8217; part, and it&#8217;s a shoddy one for everyone else; you should be aware of your company&#8217;s business practices because you represent them and they, in turn, represent you.</li>
<li><strong>If you&#8217;re a partner or contributor</strong> (reviewer, affiliate, blogger), while you&#8217;re providing EdenFantasys with inbound links or writing articles for them and thereby propping them up higher in search results, EdenFantasys is not returning the favor to you (when they are supposed to be doing so). Moreover, they&#8217;re attaching your handle, pseudonym, or real name <em>directly</em> to all of their link farming (i.e., spamming) efforts. They <em>look</em> like they&#8217;re linking to you and they <em>look</em> like their content is syndicated fairly, but they&#8217;re actually playing dirty. They&#8217;re going the extra mile to ensure search engines like Google do not recognize the links in articles you write. They&#8217;re trying remarkably hard to make certain that all roads lead to EdenFantasys, but none lead outside of it; no matter what the &#8220;link,&#8221; search engines see it as stemming from and leading to EdenFantasys. The technically savvy executives of Web Merchants, Inc. are using you without giving you a fair return on your efforts. Moreover, EdenFantasys is doing this in a way that preys upon people&#8217;s lack of technical knowledge—potentially your own as well as your readership&#8217;s. Do you want to keep doing business with people like that?</li>
<li><strong>If you&#8217;re a customer</strong>, you&#8217;re monetarily supporting a company that essentially amounts to a glorified yet subtle spammer. If you hate spam, you should hate the unethical practices that lead to spam&#8217;s perpetual reappearance, including the practices of companies like Web Merchants, Inc. EdenFantasys&#8217;s unethical practices may not be illegal, but they are unabashedly a hair&#8217;s width away from it, just like many spammers&#8217;. If you want to keep companies honest and transparent, if you really want a &#8220;sex shop you can trust,&#8221; this is relevant to you because EdenFantasys is not it. If you want to purchase from a retailer that truly strives to offer a welcoming, trustworthy community for those interested in sex positivity and sexuality, pay close attention and take action. For ideas about what you can do, please see <a href="#what-you-can-do">the &#8220;What you can do&#8221; section, below</a>.</li>
<li><strong>If you&#8217;ve never heard about EdenFantasys before</strong>, but you care about a fair and equal-opportunity Internet, this is relevant to you because what EdenFantasys is doing takes advantage of non-tech-savvy people in order to slant the odds of winning the search engine game in their favor. They could have done this fairly, and I personally believe that they would have succeeded. Their sites are user-friendly, well-designed, and solidly implemented. However, they chose to behave maliciously by not providing credit where credit is due, failing to follow through on agreements with their own community members and contributors, and sneakily utilizing other publishers&#8217; web presences to play a very sad zero-sum game that they need not have entered in the first place. In the Internet I want, nobody takes malicious advantage of those less skilled than they are because their own skill should speak for itself. Isn&#8217;t that the Internet and, indeed, the future you want, too?</li>
</ul>
<h2 id="technical-details">TECHNICAL DETAILS</h2>
<p>What follows is a technical exploration of the way the EdenFantasys technology works. It is my best-effort evaluation of the process in as much detail as I can manage within strict self-imposed time constraints. If any of this information is incorrect, I&#8217;d welcome any and all clarifications provided by the EdenFantasys CTO and technical team in an appropriately transparent, public, and ethical manner. (You&#8217;re welcome—nay, <em>encouraged</em>—to leave a comment.)</p>
<p>Although I&#8217;m unconvinced that EdenFantasys understands this, it is the case that honesty is the best policy&mdash;especially on the Internet, where <em>everyone</em> has the power of &#8220;View source.&#8221;</p>
<h3>The &#8220;EF Framework&#8221; for obfuscating links</h3>
<p>Article content written by contributors on SexIs Magazine pages is published after all links are replaced with a <code>&lt;span&gt;</code> element bearing the <code>class</code> of <code>linklike</code> and a unique <code>id</code> attribute value. This apparently happens across any and all content published by Web Merchants, Inc.&#8217;s content management system, but I&#8217;ll be focusing on Lorna D. Keach&#8217;s post entitled <cite>SexFeed:Anti-Porn Activists Now Targeting Female Porn Addicts</cite> for the sake of example.</p>
<p>These fake links look like this in HTML:</p>
<pre><code class="html">And according to Theresa Flynt, vice president of marketing for Hustler video, &lt;span class="linklike" ID="EFLink_68034_fe64d2"&gt;female consumers make up 56% of video sales.&lt;/span&gt;</code></pre>
<p>This originally published <acronym title="HyperText Markup Language">HTML</acronym> is what visitors without JavaScript enabled (and what search engine indexers) see when they access the page. Note that the <code>&lt;span&gt;</code> is not a real link, even though it is made to look like one. (See Figure 1; click it to enlarge.)</p>
<p><strong>Figure 1:</strong></p>
<p><a href="http://maybemaimed.com/wp-content/uploads/2010/05/figure-11.png"><img src="http://maybemaimed.com/wp-content/uploads/2010/05/figure-11-300x241.png" alt="" title="figure-1" width="300" height="241" class="alignnone size-medium wp-image-1759" /></a></p>
<p>In a typical user&#8217;s browser, when this page is loaded, a JavaScript program is executed that mutates these &#8220;linklike&#8221; elements into <code>&lt;a&gt;</code> elements, retaining the &#8220;linklike&#8221; <code>class</code> and the unique <code>id</code> attribute values. However, no value is provided in the <code>href</code> (link destination) attribute of the <code>&lt;a&gt;</code> element. See Figure 2.</p>
<p><strong>Figure 2:</strong></p>
<p><a href="http://maybemaimed.com/wp-content/uploads/2010/05/figure-2.png"><img src="http://maybemaimed.com/wp-content/uploads/2010/05/figure-2-300x241.png" alt="" title="figure-2" width="300" height="241" class="alignnone size-medium wp-image-1760" /></a></p>
<p>The JavaScript program is downloaded in two parts from the endpoint at <code>http://cdn3.edenfantasys.com/Scripts/Handler/jsget.ashx</code>. The first part, retrieved in this example by accessing the <acronym title="Uniform Resource Identifier">URI</acronym> at <code>http://cdn3.edenfantasys.com/Scripts/Handler/jsget.ashx?i=jq132_cnf_jdm12_cks_cm_ujsn_udm_stt_err_jsdm_stul_ael_lls_ganl_jqac_jtv_smg_assf_agrsh&#038;v_14927484.12.0</code>, loads the popular <a href="http://jquery.org/">jQuery JavaScript framework</a> as well as custom code called the &#8220;EF Framework&#8221;.</p>
<p>The EF Framework contains code called the <code>DBLinkHandler</code>, an object that parses the <code>&lt;span&gt;</code> &#8220;linklike&#8221; elements (called &#8220;pseudolinks&#8221; in the EF Framework code) and retrieves the real destination. The entirety of the <code>DBLinkHandler</code> object is shown in <a href="#code-listing-1">code listing 1</a>, below. Note the code contains a function called <code>handle</code> that performs the mutation of the <code>&lt;span&gt;</code> &#8220;linklike&#8221; elements (seen primarily on lines 8 through 16) and, based on the prefix of each elements&#8217; <code>id</code> attribute value, two key functions (<code>BuildUrlForElement</code> and <code>GetUrlByUrlID</code>, whose signatures are on lines 48 and 68, respectively) interact to set up the browser navigation after responding to clicks on the fake links.</p>
<pre id="code-listing-1"><code class="javascript">var DBLinkHandler = {
    pseudoLinkPrefix: "EFLink_",
    generatedAHrefPrefix: "ArtLink_",
    targetBlankClass: "target_blank",
    jsLinksCssLinkLikeClass: "linklike",
    handle: function () {
        var pseudolinksSpans = $("span[id^='" + DBLinkHandler.pseudoLinkPrefix + "']");
        pseudolinksSpans.each(function () {
            var psLink = $(this);
            var cssClass = $.trim(psLink.attr("class"));
            var target = "";
            var id = psLink.attr("id").replace(DBLinkHandler.pseudoLinkPrefix, DBLinkHandler.generatedAHrefPrefix);
            var href = $("&lt;a&gt;&lt;/a&gt;").attr({
                id: id,
                href: ""
            }).html(psLink.html());
            if (psLink.hasClass(DBLinkHandler.targetBlankClass)) {
                href.attr({
                    target: "_blank"
                });
                cssClass = $.trim(cssClass.replace(DBLinkHandler.targetBlankClass, ""))
            }
            if (cssClass != "") {
                href.attr({
                    "class": cssClass
                })
            }
            psLink.before(href).remove()
        });
        var pseudolinksAHrefs = $("a[id^='" + DBLinkHandler.generatedAHrefPrefix + "']");
        pseudolinksAHrefs.live("mouseup", function (event) {
            DBLinkHandler.ArtLinkClick(this)
        });
        pseudolinksSpans = $("span[id^='" + DBLinkHandler.pseudoLinkPrefix + "']");
        pseudolinksSpans.live("click", function (event) {
            if (event.button != 0) {
                return
            }
            var psLink = $(this);
            var url = DBLinkHandler.BuildUrlForElement(psLink, DBLinkHandler.pseudoLinkPrefix);
            if (!psLink.hasClass(DBLinkHandler.targetBlankClass)) {
                RedirectTo(url)
            } else {
                OpenNewWindow(url)
            }
        })
    },
    BuildUrlForElement: function (psLink, prefix) {
        var psLink = $(psLink);
        var sufix = psLink.attr("id").toString().substring(prefix.length);
        var id = (sufix.indexOf("_") != -1) ? sufix.substring(0, sufix.indexOf("_")) : sufix;
        var url = DBLinkHandler.GetUrlByUrlID(id);
        if (url == "") {
            url = EF.Constants.Links.Url
        }
        var end = sufix.substring(sufix.indexOf("_") + 1);
        var anchor = "";
        if (end.indexOf("_") != -1) {
            anchor = "#" + end.substring(0, end.lastIndexOf("_"))
        }
        url += anchor;
        return url
    },
    ArtLinkClick: function (psLink) {
        var url = DBLinkHandler.BuildUrlForElement(psLink, DBLinkHandler.generatedAHrefPrefix);
        $(psLink).attr("href", url)
    },
    GetUrlByUrlID: function (UrlID) {
        var url = "";
        UrlRequest = $.ajax({
            type: "POST",
            url: "/LinkLanguage/AjaxLinkHandling.aspx",
            dataType: "json",
            async: false,
            data: {
                urlid: UrlID
            },
            cache: false,
            success: function (data) {
                if (data.status == "Success") {
                    url = data.url;
                    return url
                }
            },
            error: function (xhtmlObj, status, error) {}
        });
        return url
    }
};</code></pre>
<p>Once the mutation is performed and all the content &#8220;links&#8221; are in the state shown in Figure 2, above, an event listener has been bound to the anchors that captures a click event. This is done using prototypal extension, <acronym title="Also Known As">aka</acronym>. classic prototypal inheritance, in another part of the code, the <code>live</code> function on line 2,280 of the (de-minimized) <code>jsget.ashx</code> program, as shown in code listing 2, here:</p>
<pre id="code-listing-2"><code class="javascript">        live: function (G, F) {
            var E = o.event.proxy(F);
            E.guid += this.selector + G;
            o(document).bind(i(G, this.selector), this.selector, E);
            return this
        },
</code></pre>
<p>At this point, clicking on one of the &#8220;pseudolinks&#8221; triggers the EF Framework to call code set up by the <code>GetUrlByUrlID</code> function from within the <code>DBLinkHandler</code> object, initiating an <a href="http://en.wikipedia.org/wiki/XMLHttpRequest">XMLHttpRequest (XHR)</a> connection to the <code>AjaxLinkHandling.aspx</code> server-side application. The request is an <acronym title="HyperText Transfer Protocol">HTTP</acronym> POST containing only one parameter, called <code>urlid</code>, and its value matches a substring from within the <code>id</code> value of the &#8220;pseudolinks.&#8221; In this example, the <code>id</code> attribute contains a value of <code>EFLink_68034_fe64d2</code>, which means that the unique ID POST&#8217;ed to the server is <code>68034</code>. This is shown in Figure 3, below.</p>
<p><strong>Figure 3:</strong></p>
<p><a href="http://maybemaimed.com/wp-content/uploads/2010/05/figure-3.png"><img src="http://maybemaimed.com/wp-content/uploads/2010/05/figure-3-300x199.png" alt="" title="figure-3" width="300" height="199" class="alignnone size-medium wp-image-1761" /></a></p>
<p>The response from the server, shown in Figure 4, is also simple. If successful, the intended destination is retrieved by the <code>GetUrlByUrlID</code> object&#8217;s <code>success</code> function (on line 79 of <a href="#code-listing-1">Code Listing 1</a>, above) and the user is redirected to that web address, as if the link was a real one all along. The real destination, in this case to CNN.com, is thereby only revealed after the XHR request returns a successful reply.</p>
<p><strong>Figure 4:</strong></p>
<p><a href="http://maybemaimed.com/wp-content/uploads/2010/05/figure-4.png"><img src="http://maybemaimed.com/wp-content/uploads/2010/05/figure-4-300x199.png" alt="" title="figure-4" width="300" height="199" class="alignnone size-medium wp-image-1762" /></a></p>
<p>All of this obfuscation effectively blinds machines such as the Googlebot who are not JavaScript-capable from seeing and following these links. It deliberately provides no increased Pagerank for the link destination (as a real link would normally do) despite being &#8220;linked to&#8221; from EdenFantasys&#8217;s SexIs Magazine article. While the intended destination in this example link was at CNN.com, it could just as easily have been—and is, in other examples—links to the blogs of EdenFantasys community members and, indeed, everyone else linked to from a SexIs Magazine article or potentially any website operated by Web Merchants, Inc. that makes use of this technology.</p>
<h3>The EdenFantasys Outsourced Link-Farm</h3>
<p>In addition to creating a self-referential black hole with no gracefully degrading outgoing links, EdenFantasys also actively performs link-stuffing through its syndicated content &#8220;relationships,&#8221; underhandedly creating an outsourced and distributed link-farm, just like a spammer. The difference is that this spammer (Web Merchants, Inc. <acronym title="Also Known As">aka</acronym> EdenFantasys) is cleverly crowd-sourcing high-value, high-quality content from its own &#8220;community.&#8221;</p>
<p>Articles published at SexIs Magazine are syndicated in full to other large hub sites, such as AlterNet.org. Continuing with the above example post by Lorna D. Keach, <cite>Anti-Porn Activists Now Targeting Female Porn Addicts</cite>, we can see that <a href="http://www.alternet.org/story/146774/christian_anti-porn_activists_now_targeting_female_">this content was republished on AlterNet.org</a> shortly after original publication through EdenFantasys&#8217; website on May 3<sup>rd</sup> at <code>http://www.alternet.org/story/146774/christian_anti-porn_activists_now_targeting_female_</code>. However, a closer look at the <acronym title="HyperText Markup Language">HTML</acronym> code of the republication shows that each and every link contained within the article points to the same destination: the same article published on SexIs Magazine, as shown in Figure 5.</p>
<p><strong>Figure 5:</strong></p>
<p><a href="http://maybemaimed.com/wp-content/uploads/2010/05/figure-5.png"><img src="http://maybemaimed.com/wp-content/uploads/2010/05/figure-5-300x199.png" alt="" title="figure-5" width="300" height="199" class="alignnone size-medium wp-image-1763" /></a></p>
<p>Naturally, these syndicated links provided to third-party sites by EdenFantasys are real and function as expected to both human visitors and to search engines indexing the content. The result is &#8220;natural,&#8221; high-value links to the EdenFantasys website from these third-party sites; EdenFantasys doesn&#8217;t merely scrounge pagerank from harvesting the sheer number of incoming links, but as each link&#8217;s anchor text is different, they are setting themselves up to match more keywords in search engine results, keywords that the original author likely did not intend to direct to them. Offering search engines the implication that EdenFantasys.com contains the content described in the anchor text, when in fact EdenFantasys merely acts as an intermediary to the information, is very shady, to say the least.</p>
<p>In addition to syndication, EdenFantasys employs human editors to do community outreach. These editors follow up with publishers, including individual bloggers (such as myself), and request that any references to published material <q>provide attribution and a link back to us</q>, to use the words of Judy Cole, Editor of SexIs Magazine in an email she sent to me (see below), and presumably many others. EdenFantasys has also been known to request &#8220;link exchanges,&#8221; and offer incentive programs that encouraged bloggers to add the EdenFantasys website to their blogroll or sidebar in order to help raise both parties search engine ranking, when in fact EdenFantasys is not actually providing reciprocity.</p>
<p><a href="http://aagblog.com/2005/10/17/problems-with-edenfantasyscom/">More information about EdenFantasys&#8217;s unethical practices</a>, which are not limited to technical subterfuge, can be <a href="http://aagblog.com/?s=edenfantasys">obtained via AAGBlog.com</a>.</p>
<h3 id="editorial">EDITORIAL</h3>
<p>It is unsurprising that the distributed, subtle, and carefully crafted way EdenFantasys has managed to crowd-source links has (presumably) remained unpenalized by search engines like Google. It is similarly unsurprising that nontechnical users such as the contributors to SexIs Magazine would be unaware of these deceptive practices, or that they are complicit in promoting them.</p>
<p>This is no mistake on the part of EdenFantasys, nor is it a one-off occurrence. The amount of work necessary to implement the elaborate system I&#8217;ve described is also not even remotely feasible for a rogue programmer to accomplish, far less accomplish covertly. No, this is the result of a calculated and decidedly underhanded strategy that originated from the direction of top executives at Web Merchants, Inc. <acronym title="Also Known As">aka</acronym> EdenFantasys.</p>
<p>It is unfortunate that technically privileged people would be so willing to take advantage of the technically uneducated, particularly under the guise of providing a <em>trusted</em> place for the community which they claim to serve. These practices are exactly the ones that &#8220;the sex shop you can trust&#8221; should in no way support, far less be actively engaged in. And yet, here is unmistakable evidence that EdenFantasys is doing <em>literally</em> everything it can not only to bolster its own web presence at the cost of others&#8217;, but to hide this fact from its understandably non-tech-savvy contributors.</p>
<p>On a personal note, I am angered that I would be contacted by the Editor of SexIs Magazine, and asked to properly &#8220;attribute&#8221; and provide a link to <em>them</em> when it is precisely that reciprocity which SexIs Magazine would clearly deny me (and everyone else) in return. It was this request originally received over email from Judy Cole, that sparked my investigation outlined above and enabled me to uncover this hypocrisy. The email I received from Judy Cole is republished, in full, here:</p>
<blockquote><p>From: Judy Cole &lt;luxuryholmes@gmail.com&gt;<br />
Subject: Repost mis-attributed<br />
Date: May 17, 2010 2:42:00 PM PDT<br />
To: kinkontap+viewermail@gmail.com<br />
Cc: Laurel &lt;laurelb@edenfantasys.com&gt;</p>
<p>Hello Emma and maymay,</p>
<p>I am the Editor of the online adult magazine SexIs (http://www.edenfantasys.com/sexis/). You recently picked up and re-posted a story of ours by Lorna Keach that Alternet had already picked up: </p>
<p>http://kinkontap.com/?s=alternet</p>
<p>We were hoping that you might provide attribution and a link back to us, citing us as the original source (as is done on Alternet, with whom we have an ongoing relationship), should you pick up something of ours to re-post in the future.</p>
<p>If you would be interested in having us send you updates on stories that might be of interest, I would be happy to arrange for a member of our editorial staff to do so. (Like your site, by the way. TBK is one of our regular contributors.)</p>
<p>Thanks and Best Regards,</p>
<p>Judy Cole<br />
Editor, SexIs</p></blockquote>
<p>Judy&#8217;s email <em>probably</em> intended to reference the new <a href="http://kinkontap.com/?cat=11">Kink On Tap briefs</a> that my co-host Emma and I publish, not a search result page on the Kink On Tap website. Specifically, she was talking about this brief: <a href="http://KinkOnTap.com/?p=676">http://KinkOnTap.com/?p=676</a>. I said as much in my reply to Judy:</p>
<blockquote><p>Hi Judy,</p>
<p>The <acronym title="Uniform Resource Locator">URL</acronym> in your email doesn&#8217;t actually link to a post. We pick up many stories from AlterNet, as well as a number from SexIs, because we follow both those sources, among others. So, did you mean this following entry?</p>
<p>   <a href="http://KinkOnTap.com/?p=676">http://KinkOnTap.com/?p=676</a></p>
<p>If so, you should know that we write briefs as we find them and provide links to where we found them. We purposefully do not republish or re-post significant portions of stories and we limit our briefs to short summaries in deference to the source. In regards to the brief in question, we do provide attribution to Lorna Keach, and our publication process provides links automatically to, again, the source where we found the article. :) As I&#8217;m sure you understand, this is the nature of the Internet. Its distribution capability is remarkable, isn&#8217;t it?</p>
<p>Also, while we&#8217;d absolutely be thrilled to have you send us updates on stories that might be of interest, we would prefer that you do so in the same way the rest of our community does: by contributing to the community links feed. You can find detailed instructions for the many ways you can do that on our wiki:</p>
<p>   <a href="http://wiki.kinkontap.com/wiki/Community_links_feed">http://wiki.kinkontap.com/wiki/Community_links_feed</a></p>
<p>Congratulations on the continued success of SexIs.</p>
<p>Cheers,<br />
-maymay</p></blockquote>
<p>At the time when I wrote the email replying to Judy, I was perturbed but could not put my finger on why. Her email upset me because she seemed to be suggesting that our briefs are wholesale &#8220;re-posts,&#8221; when in fact Emma and I have thoroughly discussed attribution policies and, as mentioned in my reply, settled on a number of practices including a length limit, automated back linking (yes, with real links, go <a href="http://kinkontap.com/?cat=11">see some Kink On Tap briefs for yourself</a>), and clearly demarcating quotes from the source article in our editorializing to ensure we play fair. Clearly, my somewhat snarky reply betrays my annoyance.</p>
<p>In any event, this exchange prompted me to take a closer look at the Kink On Tap brief I wrote, at the original article, and at the cross-post on AlterNet.org. I never would have imagined that EdenFantasys&#8217;s technical subterfuge would be as pervasive as it has proven to be. It&#8217;s so deeply embedded in the EdenFantasys publishing platform that I&#8217;m willing to give Judy the benefit of the doubt regarding this hypocrisy because she doesn&#8217;t seem to understand the difference between a search query and a permalink (something any laymen blogger would grok). This is apparent from her reply to my response:</p>
<blockquote><p>From: Judy Cole &lt;luxuryholmes@gmail.com&gt;<br />
Subject: Re: Repost mis-attributed<br />
Date: May 18, 2010 4:57:59 AM PDT<br />
[&hellip;redundant email headers clipped&hellip;]</p>
<p>Funny, the <acronym title="Uniform Resource Locator">URL</acronym> in my email opens the same link as the one you sent me when I click on it. </p>
<p>Maybe if you pick up one of our stories in future, you could just say something like &#8220;so and so wrote for SexIs.&#8221; ?</p>
<p>As it stands, it looks as if Lorna wrote the piece for Alternet. Thanks.</p>
<p>Judy</p></blockquote>
<p>That is the end of our email exchange, and will be for good, unless and until EdenFantasys changes its ways. I will from this point forward endeavor never to publish links to any web property that I know to be owned by Web Merchants, Inc., including EdenFantasys.com. I will also do my best to avoid citing any and all SexIs Magazine articles from here on out, and I encourage <em>everyone</em> who has an interest in seeing honesty on the Internet to follow my lead here.</p>
<p>As some of my friends are currently contributors to SexIs Magazine, I would like all of you to know that <strong>I sincerely hope you immediately sever all ties with any and all Web Merchants, Inc. properties, suppliers, and business partners</strong>, especially because you are friends and I think your work is too important to be sullied by such a disreputable company. Similarly, I hope you encourage your friends to do the same. I understand that the economy is rough and that some of you may have business contracts bearing legal penalties for breaking them, but I urge you to nevertheless consider looking at this as a cost-benefit analysis: the sooner you break up with EdenFantasys, the happier everyone on the Internet, including you, will be (and besides, you can loose just as much of your reputation, money, and pagerank while being happy as you can being sad).</p>
<h4 id="what-you-can-do">What you can do</h4>
<ul>
<li>If you are an EdenFantasys reviewer, a SexIs Magazine contributor, or have any other arrangement with Web Merchants, Inc., <strong><a href="mailto: luxuryholmes@gmail.com?subject=EdenFantasys%20and%20SexIs%20Magazine%20must%20conduct%20themselves%20ethically%20or%20I%20quit%20now">write to Judy Cole</a></strong> and demand that content you produce for SexIs Magazine adheres to ethical Internet publication standards. Sever business ties with this company immediately upon receipt of any non-response, or any response that does not adequately address every concern raised in this blog post. (Feel free to leave comments on this post with technical questions, and I&#8217;ll do my best to help you sort out any l33t answers.)</li>
<li>EdenFantasys wants to stack the deck in Google. They do this by misusing your content and harvesting your links. To combat this effort, <strong>immediately remove any and all links to EdenFantasys websites and web presences</strong> from your websites. Furthermore, do not&mdash;I repeat&mdash;do not publish new links to EdenFantasys websites, not even in direct reference to this post. Instead, provide enough information, as I have done, so visitors to your blog posts can find their website themselves. In lieu of links to EdenFantasys, link to other bloggers&#8217; posts about this issue. (Such posts will probably be mentioned in <a href="#comments">the comments section of this post</a>.)</li>
<li><strong>Boycott EdenFantasys</strong>: the technical prowess their website displays does provide a useful shopping experience for some people. However, that in no way obligates you to purchase from their website. If you enjoy using their interface, use it to get information about products you&#8217;re interested in, but then go buy those products elsewhere, perhaps from the manufacturers directly.
<ul>
<li>On the recommendation of my friend <a href="http://charlieglickman.com/">Dr. Charlie Glickman</a>, I suggest <a href="http://www.goodvibes.com/">Good Vibrations</a>.</p>
<li>On the recommendation of <a href="http://maybemaimed.com/2010/04/26/femquaker-shanna-katz-sex-positive-sexuality-educator/">my friend Shanna Katz</a>, I also recommend <a href="http://funlove.com/">Fascinations</a>.</li>
</ul>
</li>
<li><strong>Watch for &#8220;improved&#8221; technical subterfuge from Web Merchants, Inc.</strong> As a professional web developer, I can identify several things EdenFantasys could do to make their unethical practices even harder to spot, and harder to stop. If you have any technical knowledge at all, even if you&#8217;re &#8220;just&#8221; a savvy blogger, you can keep a close watch on EdenFantasys and, if you notice <em>anything</em> that doesn&#8217;t sit well with you, speak up about it like I did. Get a professional programmer to look into things for you if you need help; yes, you can make a difference just by remaining vigilant as long as you share what you know and act honestly, and transparently.</li>
</ul>
<p>If you have additional ideas or recommendations regarding how more people can help keep sex toy retailers honest, please suggest them in the comments.</p>
<p><ins datetime="2010-05-19T20:32:44+00:00"><strong>Update:</strong> To report website spamming or any kind of fraud to Google, use the <a href="https://www.google.com/webmasters/tools/spamreport?pli=1">authenticated Spam Report tool</a>.</ins></p>
<p><ins datetime="2010-05-20T00:07:22+00:00">Update: Google provides much more information about why the kinds of practices EdenFantasys is engaged in degrade the overall web experience for you and me. Read <a href="http://www.google.com/support/webmasters/bin/answer.py?answer=66355">Cloaking, sneaky Javascript redirects, and doorway pages</a> at the Google Webmaster Tools help site for additional <acronym title="Search Engine Optimization">SEO</acronym> information. Using Google&#8217;s terminology, EdenFantasys&#8217;s unethical technology is a very skilled mix of social engineering and &#8220;sneaky JavaScript redirects.&#8221;</ins></p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2010/05/19/web-merchants-inc-edenfantasys-unethical-technology/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>My SVG is Bigger than Your Flash &#8211; Presentation Notes</title>
		<link>http://maymay.net/blog/2010/01/07/my-svg-is-bigger-than-your-flash-presentation-notes/</link>
		<comments>http://maymay.net/blog/2010/01/07/my-svg-is-bigger-than-your-flash-presentation-notes/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 22:57:19 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Standards]]></category>
		<category><![CDATA[SVG]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=1063</guid>
		<description><![CDATA[A few weeks ago, right before the Christmas holidays, I gave a brief internal presentation about SVG, an XML-based web standard for interactive images, to my coworkers. Since I was told that the presentation was helpful, I thought I&#8217;d share my notes. Those notes follow: Introduction First, credit where credit is due. I learned almost [...]]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago, right before the Christmas holidays, I gave a brief internal presentation about <acronym title="Scalable Vector Graphics">SVG</acronym>, an <acronym title="eXtensible Markup Language">XML</acronym>-based web standard for interactive images, to my coworkers. Since I was told that the presentation was helpful, I thought I&#8217;d share my notes. Those notes follow:</p>
<h2>Introduction</h2>
<p>First, credit where credit is due.</p>
<p>I learned almost everything I know about <acronym title="Scalable Vector Graphics">SVG</acronym> from an acquaintance I met in <a href="http://raphaeljs.com/australia.html">Australia</a> named <a href="http://dmitry.baranovskiy.com/">Dmitry Baranovskiy</a>. He is a superb client-side web developer who I helped add documentation for a brief time for one of his <acronym title="Scalable Vector Graphics">SVG</acronym>-related projects called <a href="http://raphaeljs.com/">RaphaëlJS</a>. I&#8217;ll show you that in a little bit.</p>
<p>Okay, so what is <acronym title="Scalable Vector Graphics">SVG</acronym>?</p>
<h2>What is <acronym title="Scalable Vector Graphics">SVG</acronym>?</h2>
<p>In a sentence, <a href="http://www.adobe.com/svg/">according to Adobe</a>, the originators of the technology:</p>
<blockquote cite="http://www.adobe.com/svg/"><p>Scalable Vector Graphics (<acronym title="Scalable Vector Graphics">SVG</acronym>) is a text-based graphics language that describes images with vector shapes, text, and embedded raster graphics.</p></blockquote>
<p>What does that mean?</p>
<ul>
<li>Scalable means that the technology is <a href="http://en.wikipedia.org/wiki/File:Bitmap_VS_SVG.svg"> natively resolution-independent</a>.</li>
<li>Vector means that image data is described using relative mathematical coordinates:
<ul>
<li><a href="http://maymay.net/blog/wp-content/uploads/2010/01/SVG_path_syntax_1.png"><img src="http://maymay.net/blog/wp-content/uploads/2010/01/SVG_path_syntax_1.png" alt="SVG Path Syntax example 1" title="SVG_path_syntax_1" width="517" height="383" class="size-full wp-image-1065" /></a></li>
<li><a href="http://maymay.net/blog/wp-content/uploads/2010/01/SVG_path_syntax_2.png"><img src="http://maymay.net/blog/wp-content/uploads/2010/01/SVG_path_syntax_2.png" alt="SVG Path Syntax example 2, with syntax highlighting." title="SVG_path_syntax_2" width="517" height="384" class="size-full wp-image-1066" /></a></li>
</ul>
</li>
<li>Graphics means that it&#8217;s used to create images, but also means <a href="http://raphaeljs.com/image-rotation.html">it natively supports bitmapped graphics</a>, and videos, using <code><a href="http://www.w3.org/TR/SVG/extend.html#ForeignObjectElement">&lt;foreignObject&gt;</a></code>.</li>
</ul>
<p>But wait, there&#8217;s &#8221;more&#8221;.</p>
<h2>Why use <acronym title="Scalable Vector Graphics">SVG</acronym>?</h2>
<ul>
<li><a href="http://raphaeljs.com/text-rotation.html">It&#8217;s text-based</a>, which means it&#8217;s highly searchable. Remember <acronym title="Search Engine Optimization">SEO</acronym> in the heyday of the &#8220;Flash website&#8221;? Now Flash has all kinds of meta attributes to provide extra <acronym title="Search Engine Optimization">SEO</acronym> oomph, but if we had just used <acronym title="Scalable Vector Graphics">SVG</acronym> in the first place, we wouldn&#8217;t have had this problem.
<ul>
<li>That means <a href="http://raphaeljs.com/fonts.html">we also get custom fonts</a>, for free.</li>
<li>Oh, and it&#8217;s super accessible, too.</li>
</ul>
</li>
<li>Mobile support: <acronym title="Scalable Vector Graphics">SVG</acronym> comes in a few flavors that are all interoperable with each other in order to define different levels of support. Whereas Flash is monolithic, <acronym title="Scalable Vector Graphics">SVG</acronym> comes in profiles that support low-end devices with reasonable quality while still providing high-fidelity content. Just like the Web was designed to do.
<ul>
<li>Don&#8217;t believe me? Watch this: <a href="http://vimeo.com/1987967">Raphaël Rotation on iPod touch</a></li>
</ul>
</li>
<li>Easy to learn: there isn&#8217;t much new here because it uses everything you already know about <acronym title="eXtensible Markup Language">XML</acronym>, <acronym title="Cascading Style Sheets">CSS</acronym>, and JavaScript to provide every feature it has. That&#8217;s right, you can <a href="http://raphaeljs.com/pie.html">use plain old <acronym title="HyperText Markup Language">HTML</acronym> for your page content</a>, add some <acronym title="Cascading Style Sheets">CSS</acronym> to style it <em>and</em> the <acronym title="Scalable Vector Graphics">SVG</acronym>, and then JavaScript to script it. &#8220;The trifecta&#8221; just added another dimension.</li>
<li>And, if you care about such things, <a href="http://www.w3.org/Graphics/SVG/"><acronym title="Scalable Vector Graphics">SVG</acronym> has been an open standard</a> well before Flash was.</li>
</ul>
<h2>Browser support</h2>
<ul>
<li>Opera has full support and has had some amount of support since Opera 8.</li>
<li>Gecko has had increasing support since 2005.</li>
<li>WebKit has had increasing support since 2006.</li>
<li>Internet Explorer (still) has no native support. We hate you, Internet Explorer. (That said, however, <a href="http://www.sitepoint.com/blogs/2010/01/07/internet-explorer-svg/">Microsoft has just recently joined the <acronym title="World Wide Web Consortium">W3C</acronym>&#8216;s <acronym title="Scalable Vector Graphics">SVG</acronym> Working group</a>, so there may yet be some hope.)</li>
</ul>
<h2>What can we do about <acronym title="Internet Explorer">IE</acronym> today?</h2>
<p>Here is the breakdown of options we have to deal with <acronym title="Internet Explorer">IE</acronym>&#8216;s frustrating lack of support.</p>
<ul>
<li>Rely on <acronym title="HyperText Transfer Protocol">HTTP</acronym> content negotiation to serve <acronym title="Scalable Vector Graphics">SVG</acronym> to supporting browsers, and raster images to Internet Explorer. Works great, except now we&#8217;re still using raster images, so basically it feels like 1995 again. It&#8217;s also <a href="http://en.wikipedia.org/wiki/Scalable_Vector_Graphics#Support_for_SVG_in_web_browsers">what Wikipedia does</a>.</li>
<li>Use plugins. Adobe has had one forever called the <a href="http://www.adobe.com/svg/viewer/install/"> Adobe <acronym title="Scalable Vector Graphics">SVG</acronym> Viewer</a>. It&#8217;s pretty good…but it&#8217;s a plugin. I&#8217;m not sure how Flash got away with also being a plugin, but whatever.</li>
<li>Relent and use Flash on the client-side, but revel in delicious <acronym title="Scalable Vector Graphics">SVG</acronym> pureness for our source files: <a href="http://flash-creations.com/notes/sample_svgtoflash.php">Using <acronym title="Scalable Vector Graphics">SVG</acronym> Path Data in Flash</a>.</li>
<li>Use a cross-browser <acronym title="Application Programming Interface">API</acronym>. Turns out, there are quite a few:
<ul>
<li><a href="http://www.dojotoolkit.org/topics/platforms/svg"><acronym title="Scalable Vector Graphics">SVG</acronym> in The Dojo Toolkit</a> &#8211; Early and solid, but it uses Dojo (and we don&#8217;t).</li>
<li><a href="http://code.google.com/p/svgweb/">svgweb</a> &#8211; Google&#8217;s experimental library. It&#8217;s got the biggest <a href="#Hype_it_up">hype</a>right now.</li>
<li><a href="http://raphaeljs.com/">RaphaëlJS</a>, written by my acquaintance Dmitry Baranovskiy and, of course, my favorite cross-browser <acronym title="Scalable Vector Graphics">SVG</acronym> toolkit. Since it&#8217;s stand-alone, you can actually mix-and-match with your favorite JavaScript framework. In other words, you take your pick of jQuery, YUI, Prototype, or whatever, and layer RaphaëlJS on top for all your <acronym title="Scalable Vector Graphics">SVG</acronym>-related work. Now that&#8217;s creamy.</li>
</ul>
</li>
</ul>
<h2>How do <acronym title="Scalable Vector Graphics">SVG</acronym>-writing JS frameworks work?</h2>
<ol>
<li>Provides a cross-browser JavaScript <acronym title="Application Programming Interface">API</acronym> (think jQuery) for writing <acronym title="Scalable Vector Graphics">SVG</acronym> commands.</li>
<li>Writes to the <acronym title="Document Object Model">DOM</acronym> based on your Raphaël commands:
<ul>
<li>Writes <acronym title="Scalable Vector Graphics">SVG</acronym> to supporting browsers.</li>
<li>Writes VML<sup><a href="http://maymay.net/blog/2010/01/07/my-svg-is-bigger-than-your-flash-presentation-notes/#footnote_0_1063" id="identifier_0_1063" class="footnote-link footnote-identifier-link" title="VML is Microsoft&amp;#8217;s proprietary, non-standard Vector Markup Language. It&amp;#8217;s basically the exact same thing as SVG, but only works in Internet Explorer. Because whereas Apple only thinks differently, Microsoft has to do it differently. We hate you, Microsoft.">1</a></sup> to Internet Explorer.</li>
</ul>
</li>
<li>Makes you coffee.</li>
</ol>
<h2 id="Hype_it_up">Hype it up</h2>
<div class="wp-caption alignright" style="width:425px;"><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/XCk22AaRxiE&#038;hl=en_US&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/XCk22AaRxiE&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>1 Minute Intro to (Google&#8217;s) <acronym title="Scalable Vector Graphics">SVG</acronym> Web + Demos + rock and roll (because why not?)
</div>
<ul>
<li><a href="http://research.sun.com/projects/lively/">Sun Labs&#8217; Lively Kernel</a> &#8211; A full &#8220;web <acronym title="Operating System">OS</acronym>&#8221; implemented in native <acronym title="Scalable Vector Graphics">SVG</acronym> and JavaScript (no frameworks). Like SmallTalk, you can actually change the runtime environment yourself by editing JavaScript within the environment. Now <em>that&#8217;s</em> meta.
<li><a href="http://cristian.nexcess.net/ajax/svg_chart/">Ajax and <acronym title="PHP Hypertext Preprocessor; an HTML-embedded scripting language">PHP</acronym> <acronym title="Scalable Vector Graphics">SVG</acronym> Demo: Realtime Charting</a></li>
</ul>
<h2>Sources and additional resources</h2>
<ul>
<li><a href="http://www.sitepoint.com/blogs/2008/12/22/svg-is-the-future-of-application-development/"><acronym title="Scalable Vector Graphics">SVG</acronym> Is The Future Of Application Development</a> &#8211; Describes other awesome uses of <acronym title="Scalable Vector Graphics">SVG</acronym>.
<li><a href="http://www.webdirections.org/resources/dmitry-baranovskiy-start-using-web-vector-graphics-today/">Start Using Web Vector Graphics Today</a> &#8211; Web Directions South presentation by Dmitry Baranovskiy.
<li><a href="http://www.slideshare.net/Dmitry.Baranovskiy/svg"><acronym title="Scalable Vector Graphics">SVG</acronym></a> &#8211; a slideshow overview by Dmitry Baranovskiy.</li>
<li><a href="http://www.w3schools.com/svg/svg_intro.asp"><acronym title="Scalable Vector Graphics">SVG</acronym> Intro</a> on W3Schools.com. (Quick &#8216;n&#8217; dirty and not highly recommended, but an oft-cited reference so you might as well know it exists.)</li>
</ul>
<ol class="footnotes"><li id="footnote_0_1063" class="footnote">VML is Microsoft&#8217;s proprietary, non-standard Vector Markup Language. It&#8217;s basically the exact same thing as <acronym title="Scalable Vector Graphics">SVG</acronym>, but only works in Internet Explorer. Because whereas Apple only thinks differently, Microsoft has to do it differently. We hate you, Microsoft.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2010/01/07/my-svg-is-bigger-than-your-flash-presentation-notes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Crosspost: My impressions on the new “sex-positive social network” Blackbox Republic</title>
		<link>http://maymay.net/blog/2009/12/14/blackbox-republic-social-network-review/</link>
		<comments>http://maymay.net/blog/2009/12/14/blackbox-republic-social-network-review/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 19:46:29 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Branding & Identity]]></category>
		<category><![CDATA[Business & E-Commerce]]></category>
		<category><![CDATA[Crosspost]]></category>
		<category><![CDATA[Information & Communication]]></category>
		<category><![CDATA[Internet Marketing]]></category>
		<category><![CDATA[Maybe Maimed]]></category>
		<category><![CDATA[Tech News]]></category>
		<category><![CDATA[Tech/Computing]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Writing and blogging]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=1041</guid>
		<description><![CDATA[This post was originally published on my other blog, a much more Not Safe For Work site, at maybemaimed.com. However, it turns out that blog is censored in various countries, such as Dubai. Gotta love Internet censorship. Sigh. Anyways, since I think the material there is interesting and technology-relevant, and in order to help people [...]]]></description>
			<content:encoded><![CDATA[<p>This post was <a href="http://maybemaimed.com/2009/12/12/my-impressions-on-the-new-sex-positive-social-network-blackbox-republic/">originally published on my other blog</a>, a much more Not Safe For Work site, at <a href="http://maybemaimed.com/2009/12/12/my-impressions-on-the-new-sex-positive-social-network-blackbox-republic/">maybemaimed.com</a>. However, it turns out that blog is <a href="http://identi.ca/notice/16736914">censored in various countries, such as Dubai</a>. Gotta love Internet censorship. <em>Sigh.</em> Anyways, since I think the material there is interesting and technology-relevant, and in order to help people avoid Internet censorship, I&#8217;m cross-posting the contents here. Enjoy.</p>
<hr />
<p>Social media. Internet publishing. Privacy. Three phrases that have seemed to be at tenacious odds with each other in a multitude of subtle and not-so-subtle ways. For people like me, who have progressive views about sexuality, these three things are constantly on our minds. How do we participate in the online revolution without being forced to &#8220;come out&#8221; about every sex act we enjoy, some of which are still illegal thanks to <a href="http://malesubmissionart.com/post/271520580/in-forbidding-darkness-a-young-man-is">draconian restrictions on sexual freedom</a>, <a href="http://maybemaimed.com/2009/11/01/on-youth-sexuality-education-and-your-fears/">even (and especially?) in America</a>.</p>
<p>This month, a new social network called <a href="http://blackboxrepublic.com/">Blackbox Republic</a> (BBR) is attempting to tackle this head-on and aims to create a place for, <a href="http://www.readwriteweb.com/archives/can_blackbox_republic_breathe_new_life_into_the_on.php">as Marshall Kirkpatrick put it</a>, this particular <q cite="http://www.readwriteweb.com/archives/can_blackbox_republic_breathe_new_life_into_the_on.php">large and unserved group of people</q>. Although BBR is clearly a business, it&#8217;s a business whose creators have laudable intentions for positive social and cultural change. In that respect, and in many others, Blackbox Republic is worth a close look.</p>
<p>I was informed about the venture via <a href="http://clarissethorn.wordpress.com/">Clarisse Thorn</a> many months ago. I got in touch with BBR and signed up for a limited-offer &#8220;founder&#8221; account—basically a private beta. The founder account gave me free access to the <a href="http://www.blackboxrepublic.com/private-and-social">features of the BlackboxRepublic.com website</a> for what would <a href="http://www.blackboxrepublic.com/dues">normally be a $25 monthly subscription fee</a>. </p>
<p>So, without further ado, here are my impressions about Blackbox Republic, and how its launch may be just what the Internet needs to get us moving in the right direction with regards to personal privacy, and mainstream awareness of the different needs of different people on the Internet.</p>
<h2>Mainstream sex-positivity or a VIP room in cyberspace? Or both?</h2>
<p>Over the past few months, Blackbox Republic has been building a marketing arsenal of anticipation and intrigue. Its creators are successful in non-sexuality-focused spheres of influence: <a href="http://www.linkedin.com/in/samlawrence">Sam Lawrence</a> is the respected former Chief Marketing Officer of <a href="http://www.jivesoftware.com/">Jive Software, Inc.</a>, and April Donato, has experience in community management. They also both jive (pun!) well with the sex-positive movement, discussing it at length in the early stages of their marketing efforts after de-cloaking the new company.</p>
<p>In <a href="http://www.socialnetworkingwatch.com/2009/08/sam-lawrence-ceo-of-blackbox-republic.html">an interview for Social Networking Watch</a>, Sam Lawrence said,</p>
<blockquote cite="http://www.socialnetworkingwatch.com/2009/08/sam-lawrence-ceo-of-blackbox-republic.html"><p>[<strong>Sam Lawrence:</strong>] The co-founder [April Donato] and myself are part of [the sex-positive] community. Sex positive means that your sexuality is not an issue. You don’t have an issue with other people’s sexuality. You’re open to what other people are interested in and what their boundaries are, and you’re open with your own.</p>
<p>[…]</p>
<p>[<strong>Interviewer:</strong>] To what extent do you practice a sex-positive lifestyle?</p>
<p>[<strong>Sam Lawrence:</strong>] From the perspective of sex not being an issue, I think that love is generated by people being open enough about who they are as people to put all of themselves out on the table. As far as putting all of myself on the table, it’s something that I do every single day.</p></blockquote>
<p>I have an enormous amount of respect for anyone able to so capably present themselves as authentically as Sam does. On the eve of <a href="http://kinkforall.pbworks.com/KinkForAllNewYorkCity2Schedule">KinkForAll New York City 2</a>, I met Sam and April at one of their &#8220;founder meetups&#8221; and had the chance to talk to them face-to-face. Our conversation revolved around the importance of steadfastly holding true to one&#8217;s own desires and having appropriate places to express those things with appropriate communication tools. I really liked their emphasis on self-identification over labeling throughout our discussion.</p>
<p>I also really appreciated the way that Sam and April spoke about their target audience. Blackbox Republic will welcome everyone, but it&#8217;s not <em>designed</em> for everyone, and I think that&#8217;s a good thing. <a href="http://onlinedatingpost.com/archives/2009/12/blackbox-republic-remixs-dating-love-and-social-life/">David Evans writing at Online Dating Post says</a>,</p>
<blockquote cite="http://onlinedatingpost.com/archives/2009/12/blackbox-republic-remixs-dating-love-and-social-life/"><p>BBR has room for everyone, but is not for everyone. Definitely catering to non-mainstream folks, it will soon feature a constellation of micro-communities, or groups, called Camps. BBR doesn’t tell people how to organize their camps; we’ll do it ourselves, thankyouverymuch.</p></blockquote>
<p>So is Blackbox Republic a dating site, or a social network? Well, both, kind of. Part of BBR&#8217;s slogan includes, &#8220;Dates will happen. Sex will happen. It matters how you get there.&#8221; The implication, of course, being that the current suite of tools for finding love or play online—sites like <a href="http://alt.com/">Alt.com</a>, <a href="http://okcupid.com/">OkCupid</a>, and <a href="http://craigslist.org/">countless</a> <a href="http://personals.nerve.com/">personals</a> <a href="http://personals.yahoo.com/">boards</a>—focus too strongly on the end result, turning matchmaking into a meat market instead of the natural process of getting to know one another. The focus BBR is placing on each person&#8217;s &#8220;journey&#8221; is an extremely welcome paradigm shift in the online dating world.</p>
<p>Along with the welcome and (IMHO, painfully obviously better) new approach to online dating, however, Blackbox Republic faces some real challenges. For new users, the service costs a minimum of $5 a month to use (and $9 per month for new sign-ups starting in 2010), which gives access to basic features like a personal profile. For $25 a month, members get added features like the ability to list real-world meet-ups, send private messages, and partake in a virtual &#8220;gifting&#8221; economy (think LiveJournal&#8217;s &#8220;<a href="http://www.livejournal.com/shop/vgift.bml?cat=gifts">virtual gifts</a>&#8220;).</p>
<p>For that reason, BBR has been called a &#8220;members-only club.&#8221; There are some legitimate differences of opinion as to whether this is a positive or a negative thing. In a press release over the summer, <a href="http://blogs.zdnet.com/collaboration/?p=741">Blackbox Republic is reported as stating</a>:</p>
<blockquote cite="http://blogs.zdnet.com/collaboration/?p=741"><p>Blackbox Republic will be a members-only experience that will unite the sex-positive community and give them a personal, private and secure way to connect online and in person.</p></blockquote>
<p>Writing for ZDNet, <a href="http://blogs.zdnet.com/collaboration/?p=1123">Oliver Marks likens Blackbox Republic&#8217;s approach to online dating to the fashionability of owning an Apple computer</a>:</p>
<blockquote cite="http://blogs.zdnet.com/collaboration/?p=1123"><p>Think of Blackbox Republic as a fashionable online ‘members-only’ club where you might expect to meet people with similar interests to your own, and ideally the person of your dreams. […] Blackbox Republic is arguably an Apple product to Facebook’s Windows look &#038; feel: a much more intimately crafted, fuller featured personal user interface which should appeal to Apple generation sensibilities.</p></blockquote>
<div id="attachment_1163" class="wp-caption alignright" style="width: 310px"><a href="http://maybemaimed.com/wp-content/uploads/2009/12/bbr-chic-new-club-design-screenshot.png"><img src="http://maybemaimed.com/wp-content/uploads/2009/12/bbr-chic-new-club-design-screenshot-300x214.png" alt="Many pages on Blackbox Republic&#039;s website showcase fashionably dressed women." title="bbr-chic-new-club-design-screenshot" width="300" height="214" class="size-medium wp-image-1163" /></a><p class="wp-caption-text">Many pages on Blackbox Republic's website showcase fashionably dressed women.</p></div>
<p>Indeed, almost everything about Blackbox Republic&#8217;s marketing and design seems to me as though it&#8217;s positioning itself as the equivalent of the hip, new, <em>and exclusive</em> nightclub down the street. There are images of super-chic women in short skirts and tight pants all over the Blackbox Republic promotional pages—way more than there are pictures of men. I was (yet again) <a href="http://malesubmissionart.com/post/270107422/an-uncircumcised-dark-skinned-man-lays-on-his-side">put-off by this over-prevalence of women in all advertising material</a>.</p>
<p>This isn&#8217;t really a criticism of the site, but rather a statement of disappointment that the marketing gurus behind the effort seemed to me to have succumbed to overwhelming cultural pressure to sell their site with <a href="http://malesubmissionart.com/post/168794536/a-naked-man-lays-on-a-bed-next-to-a-video-camera">old-school sex appeal: women&#8217;s sex appeal, of course</a>. How…traditional.</p>
<p>Not only is the <a href="http://twitter.com/maymaym/statuses/6486477499">Blackbox Republic intro video markedly gender-skewed</a>, but somewhere along the line <a href="http://www.xconomy.com/seattle/2009/12/09/blackbox-republic-no-longer-just-sex-positive-opens-alternative-social-site/">Sam and April decided to drop the &#8220;sex-positive&#8221; phraseology from their marketing</a>:</p>
<blockquote cite="http://www.xconomy.com/seattle/2009/12/09/blackbox-republic-no-longer-just-sex-positive-opens-alternative-social-site/"><p>[L]ike most startups, Blackbox decided it needed to change up. Observers were confused by the sex-positive label.</p></blockquote>
<p>Oh well. I think this just goes to further showcase how much more social change we really need in our culture.</p>
<p>However, while the clubby, cliquey feel is totally my own subjective perception, there are other issues at play here, too. Most notably, as Clarisse Thorn and many others rightfully remind us very often, <a href="http://clarissethorn.wordpress.com/2009/04/17/my-kinkforall-nyc-presentation/">the sex-positive movement is overwhelmingly white</a>, middle- to upper-class, college-educated, and privileged in a huge number of ways that many people often take for granted. Even without a for-pay social network, not everyone who wants to <em>can</em> participate in the great-sex-for-everyone party atmosphere of many sex-positive niches.</p>
<p>Will creating a &#8220;members-only club&#8221; of sex-positivity on the Internet really be a positive thing for &#8220;the movement&#8221;? Well, maybe. Although it has the potential to exclude lower-income people from the experience, who are sadly also often the people with the most pressing need for the kinds of privacy-related tools BBR offers (school teachers spring to mind!), one upside is that <a href="http://www.socialnetworkingwatch.com/2009/08/sam-lawrence-ceo-of-blackbox-republic.html">Blacbox Republic promises to pledge a portion of membership dues to a charity of the user&#8217;s choice</a>.</p>
<blockquote cite="http://www.socialnetworkingwatch.com/2009/08/sam-lawrence-ceo-of-blackbox-republic.html"><p> It’s $25 a month and $5 of those community dues go to charity. One way to think about it is if you’re sex-positive, you can either spend money on expensive coffee every month or upgrade your social life and meet other sex-positive people like you.</p></blockquote>
<p>Inescapably, the major selling point of any social network is, of course, the network! If your friends aren&#8217;t on Twitter, then you&#8217;re probably not going to find it useful. The same truth holds for Blackbox Republic: if the users you want to interact with aren&#8217;t there, I doubt you&#8217;re going to find the experience fruitful. Due to the membership fees and the socioeconomic realities of the sex-positive community, I&#8217;m concerned that BBR&#8217;s current business model is <em>too</em> exclusive, and as a result it will have a lot of trouble attracting the kind of diverse community its creators seem to be hoping for.</p>
<p>Yet, some others think differently (pun!). For instance, <a href="http://www.accmanpro.com/2009/07/15/blackbox-republic-and-the-sex-positive-community/">Dennis Howlett welcomes the for-pay model for a social network</a>:</p>
<blockquote cite="http://www.accmanpro.com/2009/07/15/blackbox-republic-and-the-sex-positive-community/"><p>anyone can join provided they’re willing to pay the $25 a month (I like that he has a pay model from the get go. That sorts out the weirdos and hangers on from day one)</p></blockquote>
<p>I wonder if adopting a <a href="http://en.wikipedia.org/wiki/Freemium">free-mium</a> approach might work better. Still, there are real-world limits to business. Everyone needs to make money, and I don&#8217;t think Blackbox Republic&#8217;s business model is inherently more exclusive than, say, purchasing access to porn. If anything, BBR&#8217;s got some real promise to inject much-needed financial awareness to the sexually insensitive corporate infrastructure of our society. Nevertheless, convincing people to join &#8220;the Republic&#8221; is going to be a hard sell.</p>
<h2>Show me the features!</h2>
<p>Let&#8217;s say you do decide to join. What do you get? Other than the sex-positive mindset, what&#8217;s the benefit?</p>
<p>Well, the bulk of the experience is what you&#8217;d expect. Profiles (called &#8220;personas&#8221;), messaging, user search capabilities (called &#8220;explore&#8221;), and so forth. A Twitter-like &#8220;activity stream&#8221; dominates the main page where you can post text, picture, or video status updates. Event listings fill the sidebar. (I&#8217;m not going to provide internal screenshots in deference to <a href="http://www.blackboxrepublic.com/faq">BBR&#8217;s strict confidentiality rules</a>.)</p>
<p>While that&#8217;s fun, it&#8217;s nothing special. What makes Blackbox Republic different is flexibility, and privacy.</p>
<h3>Goodbye drop-downs, hello sliders!</h3>
<div id="attachment_1165" class="wp-caption alignright" style="width: 260px"><a href="http://maybemaimed.com/wp-content/uploads/2009/12/bbr-sliders-screenshot.png"><img src="http://maybemaimed.com/wp-content/uploads/2009/12/bbr-sliders-screenshot-250x300.png" alt="An innovative new interface acknowledges (most of) the diversity in human sexual experience and desire." title="bbr-sliders-screenshot" width="250" height="300" class="size-medium wp-image-1165" /></a><p class="wp-caption-text">An innovative new interface acknowledges (most of) the diversity in human sexual experience and desire.</p></div>
<p>Blackbox Republic&#8217;s most visible feature is the way its interface allows you to flexibly self-identify various facets of yourself. Rather than give you static drop-down menus or radio buttons for things like your sexual orientation and relationship status, you&#8217;re presented with sliders you can change at will. Perhaps you&#8217;re feeling particularly same-sex attracted one day. Just move the &#8220;Orientation&#8221; slider towards the &#8220;Gay&#8221; end and away from the &#8220;Hetero&#8221; end. If that changes tomorrow, just move the slider back. Sho-weet!</p>
<p>BBR offers you 5 different sliders for your profile. In addition to the one for sexual orientation, you also get one for relationship &#8220;status&#8221; (ranging from attached to unattached, with Facebook&#8217;s famous &#8220;it&#8217;s complicated&#8221; neatly in the middle), whether you&#8217;re available for more partners or not, how comfortable you are with casual sexual activity, and how eagerly you&#8217;re looking to par-tay. I&#8217;m instantly reminded of <a href="http://fetlife.com/">FetLife</a>&#8216;s innovative, if dull-looking, mechanism for specifying multiple relationships. Blackbox Republic gives you similar flexibility as FetLife does but presented in a superb and far more intuitive interface.</p>
<p>All that said, one slider is conspicuously missing: the one for gender. The sliders are a very interesting idea and might just be the most innovative feature of the entire site. It speaks volumes about the sensitive and thoughtful mindset of the developers, and that&#8217;s why I&#8217;m so disappointed that the interface for self-identifying gender is relegated to the Sex 1.0 days of a single, binary option of &#8220;male&#8221; or &#8220;female.&#8221;</p>
<p>What gives? Are polyamorous people more welcome here than those who don&#8217;t fit the gender binary? I hope this is simply an omission that will be fixed as the service matures, since I couldn&#8217;t find any other reason why gender was absent from the sliders. For extra credit, I hope to see <em>different</em> profile options for &#8220;Sex&#8221; and &#8220;Gender,&#8221; two distinct concepts that frequently and incorrectly get used interchangeably. This would make it possible to represent complex gender presentations like <a href="http://sexpositive.wikia.com/wiki/Additive_gender">additive gender</a> on a social networking interface for the first time ever, and that&#8217;d totally be something to write home about!</p>
<h3>Privacy and security</h3>
<p>The other major selling point of Blackbox Republic is its careful attention to privacy. The entire offering, including its name, is predicated on letting users very carefully segment their information based on their privacy boundaries. I love some of the things BBR has done to enable this, and I can only imagine it&#8217;s going to get better from here.</p>
<h4>Blackbox Republic&#8217;s Web of Trust</h4>
<p>There are three levels of privacy, which (as far as I can figure out) map directly to the level of trust other members have gained within the Republic&#8217;s community. It works like a <a href="http://en.wikipedia.org/wiki/Web_of_trust">web of trust</a>. New users are &#8220;un-vouched.&#8221; As they begin to interact with others on the site and, hopefully, make some friends, they should receive &#8220;vouches&#8221;—or votes of trust—from previously-vouched members. As a member, you get to control whether something you do, such as posting a status update, gets sent to the &#8220;public,&#8221; (i.e., the entire public-facing Internet), to all Blackbox Republic members (i.e, to both vouched and un-vouched members) or only to vouched members.</p>
<p>Additionally, privacy settings allow you to specify whether you want to allow un-vouched members to send you private messages, to follow your updates, to comment on your posts, or to see you in search results.</p>
<p>Unlike Facebook, which has very good privacy controls that almost nobody on Earth is aware of (thus negating the control&#8217;s usefulness), Blackbox Republic makes it a point to highlight their privacy controls at just about every sensical turn. Each of the settings I found defaults to the most private setting, not the most public, which is exactly the right move. I gotta say, I found turning <em>off</em> privacy settings instead of having to turn (or leave) them on to be a really empowering feeling.</p>
<h4>You&#8217;re not a &#8220;friend,&#8221; you&#8217;re an acquaintance!</h4>
<p>Moreover, the Blackbox Republic platform makes a native distinction between &#8220;friends&#8221; (again, like Facebook, or FetLife) and &#8220;followers&#8221; (like Twitter). When I friend someone, I&#8217;m connected to them in a way that I&#8217;m not if I just follow someone. I&#8217;m not yet certain what the practical distinction between &#8220;friending&#8221; and &#8220;following&#8221; are, other than the fact that your view of the people you&#8217;re connected with is segmented based on which button you clicked, but I think the distinction is a very appropriate and natural one to embed in the software.</p>
<p>This separation is probably the single most important innovation in the space of social networks as a medium of communication and collaboration that I can point at. I love that I can indicate without ambiguity which people I want to remain in constant communication with and which I simply want to watch from a distance. After all, aren&#8217;t at least <em>some</em> of your &#8220;friends&#8221; on Facebook really just &#8220;acquaintances&#8221; in reality? I think that for the first time ever in a social network, Blackbox Republic gets this feature right. Now, if only I could figure out what it actually <em>does</em>. :)</p>
<h4>What? No on-the-wire encryption?!</h4>
<p>With all that being said, there&#8217;s still at least one really frightening problem with Blacbox Republic&#8217;s careful attention to privacy: as far as I could tell, no part of my session is <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security"><acronym title="Secure Sockets Layer">SSL</acronym>/TLS</a> encrypted!</p>
<div id="attachment_1164" class="wp-caption alignleft" style="width: 310px"><a href="http://maybemaimed.com/wp-content/uploads/2009/12/bbr-login-screen.png"><img src="http://maybemaimed.com/wp-content/uploads/2009/12/bbr-login-screen-300x263.png" alt="Stunningly, for a site that sells privacy, not even Blackbox Republic&#039;s login form is on a secure page." title="bbr-login-screen" width="300" height="263" class="size-medium wp-image-1164" /></a><p class="wp-caption-text">Stunningly, for a site that sells privacy, not even Blackbox Republic's login form is on a secure page.</p></div>
<p>The entire BlackboxRepublic.com website is served over <acronym title="HyperText Transfer Protocol">HTTP</acronym>, including the login form and—again, as far as I could tell—every  page on the <em>inside</em> of the site. This means that it&#8217;s trivial for malicious people who don&#8217;t even have a Blackbox Republic subscription to intercept, eavesdrop, and modify my interaction with the site. They could watch—and save—private messages between me and one of my friends (or lovers!), for instance.</p>
<p>In Blackbox&#8217;s defense, I don&#8217;t know of any social network that protects you from this. FetLife is another example of a website that should seriously consider <acronym title="HyperText Transfer Protocol Secured; HTTP over SSL">HTTPS</acronym>-only pages, but as of this writing hasn&#8217;t implemented it. Therein lies one of the most frightening oversights in the entire social networking space: regardless of so-called privacy settings, everything you do on the vast majority of social networks, blogs, and other sites on the Internet are the equivalent of passing notes between friends in a classroom. Better hope that big bully who likes to steal your lunch money doesn&#8217;t open the note and read it himself while he&#8217;s passing along your login details!</p>
<p>The thing is, few other social networking sites place so strong a spotlight on user privacy and security. Since Blackbox Republic seems to be nobly and rightfully holding itself up to a new standard of privacy, I feel justified in pointing out this glaring omission in their service offering. Given everything else they&#8217;ve done <em>so well</em>, and how well-aligned the majority of their technical implementation seems to be with their philosophy, this omission came as a big surprise to me.</p>
<p>Until Blackbox Republic only serves <acronym title="HyperText Transfer Protocol Secured; HTTP over SSL">HTTPS</acronym> traffic for all private areas of their site, I can&#8217;t make a recommendation in good conscious that it&#8217;s the place to be for privacy-conscious people. But again, despite public opinion to the contrary, I&#8217;ve never been able to make that claim for FetLife either.</p>
<h2>Conclusion</h2>
<p>Blackbox Republic is one of the most interesting websites on the Internet today. Its privacy-conscious and sexually open approach to social networking and online dating deserves huge praise. Its technical implementation—although plagued with some glaring oversights for now—is to be seriously respected.</p>
<p>From a social change perspective, I think the site is a mixed bag. Its exclusivity arguably makes the insularity of the sexuality communities an even bigger problem than it already is. On the other hand, the market-value of that very same exclusivity, if steered toward a benevolent purpose, can end up benefiting philanthropic, non-profit, and other sex-positive endeavors that often struggle to find necessary financial support.</p>
<p>Moreover, Blackbox Republic&#8217;s internal gifting economy does seem to encourage a sort of altruistic nature among members. How that may or may not translate into increased support for non-commercial activists has yet to be seen. Nay-sayers should remember that this kind of thing simply hasn&#8217;t been done before and the net effect could be quite positive.</p>
<p>Having just launched, however, I don&#8217;t think Blackbox Republic should be touted as the go-to site for sex-positive people quite yet. Like other social networks, it needs to grow to become truly useful, and its subscription fee business model poses a serious obstacle to many people. I was fortunate to get in with a free &#8220;founder&#8221; account, but I have mixed feelings about encouraging my friends to join me knowing they—or someone nice enough to &#8220;gift&#8221; a limited-time subscription to them—will have to pay for the service.</p>
<p>Additionally, its focus on being, well, a black box and <a href="http://www.xconomy.com/seattle/2009/12/09/blackbox-republic-no-longer-just-sex-positive-opens-alternative-social-site/">its commitment to not allow Google or other search engines to index its internal content</a> simply doesn&#8217;t resonate that strongly with me.</p>
<blockquote cite="http://www.xconomy.com/seattle/2009/12/09/blackbox-republic-no-longer-just-sex-positive-opens-alternative-social-site/"><p>Lawrence emphasizes that what members say in Blackbox Republic will stay private. There’s no danger of what they post inside becoming part of their “Google resume,” as he puts it. He says he would resist efforts from search engines to index content the way Facebook and Twitter allow. “The value proposition is this is the first private, large social network out there,” Lawrence says.</p></blockquote>
<p>Put simply, and noting that I&#8217;m probably not the majority case here, <a href="http://maybemaimed.com/2009/11/14/online-reputation-management-for-sex-bloggers-when-a-tweet-wont-do/">I <em>rely</em> on my &#8220;Google résumé,&#8221;</a> to use Sam&#8217;s words, to live the life I want. My lukewarm reaction to this isn&#8217;t a criticism of the goal, simply an observation that it turns out I&#8217;m not in the ideal target market for Blackbox Republic&#8217;s value proposition.</p>
<p>In other words, I think I&#8217;m &#8220;too out&#8221; for this site to be immediately useful to me. The fact that FetLife is not readily available to the public Internet is the single biggest reason why I don&#8217;t sign on to that site very often, and so I have the same reason not to spend all that much time behind the curtains of Blackbox Republic.</p>
<p>Nevertheless, many other people do. If you&#8217;re among the cross-section of the populace who&#8217;d like a sociosexual experience online and would also like to effectively outsource your social reputation management, if you will, but you feel that sites like Facebook just aren&#8217;t cutting it, then Blackbox Republic is definitely worth checking out.</p>
<p>If you do check it out, or even if you don&#8217;t, I&#8217;d love to know what you think in the comments. And if you&#8217;re definitely sold, consider signing up via <a href="http://www.blackboxrepublic.com/partner/maymay">my partner link</a>. Full disclosure: signing up that way earns me a small commission. If you&#8217;d rather sign up but not give me a commission for the referral, just register from the front page.</p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2009/12/14/blackbox-republic-social-network-review/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Buy Web Development Books from SitePoint&#8217;s 5-for-1 Sale and Donate to Bushfire Relief</title>
		<link>http://maymay.net/blog/2009/02/10/buy-web-development-books-from-sitepoints-5-for-1-sale-and-donate-to-bushfire-relief/</link>
		<comments>http://maymay.net/blog/2009/02/10/buy-web-development-books-from-sitepoints-5-for-1-sale-and-donate-to-bushfire-relief/#comments</comments>
		<pubDate>Tue, 10 Feb 2009 13:06:39 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Branding & Identity]]></category>
		<category><![CDATA[Crosspost]]></category>
		<category><![CDATA[Internet Marketing]]></category>
		<category><![CDATA[Maymay Media]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Writing and blogging]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=875</guid>
		<description><![CDATA[For those of you who don&#8217;t already know, I&#8217;ve been a blogger over at SitePoint for a few months now. Today, I&#8217;m even happier to be a participant in the SitePoint community because, for a limited time only, SitePoint is offering the sale of the century: buy 5 SitePoint books for the price of 1. [...]]]></description>
			<content:encoded><![CDATA[<p>For those of you who don&#8217;t already know, <a href="http://www.sitepoint.com/articlelist/537/">I&#8217;ve been a blogger over at SitePoint</a> for a few months now. Today, I&#8217;m even happier to be a participant in the SitePoint community because, for a limited time only, SitePoint is offering the sale of the century: <strong><a href="http://5for1.aws.sitepoint.com/" title="Purchase SitePoint books to donate to Victorian bushfire relief efforts.">buy 5 SitePoint books for the price of 1</a></strong>. Every last cent of the proceeds from the sale of these books will go towards relief efforts for the <a href="http://www.abc.net.au/news/stories/2009/02/08/2485299.htm">recent Victorian bushfires</a> that have claimed over 300 lives and are among the worst fire disasters on record.</p>
<p>The books are full-color <acronym title="Portable Document Format">PDF</acronym> downloads, and include some really awesome titles. These are precisely the kinds of books you want as PDFs, too, since you can search through them and always keep them with you while you&#8217;re coding and looking for inspiration or a reference (even when you&#8217;re without Internet access). I couldn&#8217;t help but pounce on this deal, and I&#8217;m now the proud owner of the following books, which have all received some pretty great reviews:</p>
<ul>
<li><a href="http://www.sitepoint.com/books/xml1/">No Nonsense <acronym title="eXtensible Markup Language">XML</acronym> Web Development With <acronym title="PHP Hypertext Preprocessor; an HTML-embedded scripting language">PHP</acronym></a></li>
<li><a href="http://www.sitepoint.com/books/ajax1/">Build Your Own AJAX Web Applications</a></li>
<li><a href="http://www.sitepoint.com/books/design1/">The Principles of Beautiful Web Design</a> (on <a href="http://www.heyraena.com/">Raena</a>&#8216;s recommendation)</li>
<li><a href="http://www.sitepoint.com/books/photoshop1/">The Photoshop Anthology: 101 Web Design Tips, Tricks &#038; Techniques</a></li>
<li><a href="http://www.sitepoint.com/books/jsdesign1/">The Art &#038; Science Of JavaScript</a></li>
</ul>
<p>In just 3.5 hours, SitePoint has managed to raise over $15,000 <abbr title="Australian Dollars">AUD</abbr>, <a href="http://twitter.com/sentience/statuses/1195088041">according to employee Kevin Yank on Twitter</a>. And that&#8217;s just on this side of the world. All my North hemisphere friends were asleep when this was announced, but not to worry. SitePoint&#8217;s sale will last until this Friday, so there&#8217;s plenty of time to take advantage of it.</p>
<p>Obviously, I think you should do so. Not only are you getting some really quality content and helping disaster victims at the same time, you&#8217;re also sending a loud and clear message that companies whose humanity outshines their accounting are the ones you&#8217;re going to support. I&#8217;m thrilled to see that SitePoint is one of these <em>human</em> companies, and ever more thrilled to be a part of it.</p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2009/02/10/buy-web-development-books-from-sitepoints-5-for-1-sale-and-donate-to-bushfire-relief/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>clickjane.css: A CSS User Style Sheet to Help Detect and Avoid Clickjacking Attacks</title>
		<link>http://maymay.net/blog/2008/12/29/clickjanecss-a-css-user-style-sheet-to-help-detect-and-avoid-clickjacking-attacks/</link>
		<comments>http://maymay.net/blog/2008/12/29/clickjanecss-a-css-user-style-sheet-to-help-detect-and-avoid-clickjacking-attacks/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 10:31:07 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Crosspost]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Maymay Media]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security & Privacy]]></category>
		<category><![CDATA[Tech/Computing]]></category>
		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=847</guid>
		<description><![CDATA[Clickjacking or, more formally, user interface redressing, is a class of security vulnerabilities similar to phishing scams. The technique uses web standards to trick unsuspecting victims into performing actions they were not intending to. Clickjacking does not rely on bugs in any software. Instead, the technique is simply an abuse of the growing graphical capabilities [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Clickjacking">Clickjacking</a> or, more formally, <dfn>user interface redressing</dfn>, is a class of security vulnerabilities similar to phishing scams. The technique uses web standards to trick unsuspecting victims into performing actions they were not intending to.</p>
<p>Clickjacking does not rely on bugs in any software. Instead, the technique is simply an abuse of the growing graphical capabilities that advanced web standards like <acronym title="Cascading Style Sheets">CSS</acronym> provide to web browsers. A good <a href="http://www.grc.com/sn/sn-168.htm">introduction to clickjacking</a> is provided by <a href="//grc.com/">Steve Gibson</a> and <a href="http://leoville.com/">Leo Laporte</a> on their <a href="//twit.tv/sn">Security Now! podcast</a>.</p>
<p>As far as I&#8217;m aware, only <a href="//mozilla.com/firefox/">Firefox</a> when combined with the <a href="//noscript.net/">NoScript</a> <a href="https://addons.mozilla.org/firefox/addon/722">add-on</a> and Internet Explorer when combined with the <a href="//guardedid.com/">GuardedID product</a> provide any measure of protection against clickjacking attacks. To date no other browser can detect, alert, or otherwise help you to avoid or mitigate the risks of clickjacking attacks.</p>
<p>That said, there&#8217;s gotta be <em>something</em> users of other browsers can do. Well, it may not be as much as what NoScript can do, but there is something: use a user style sheet to help expose common clickjacking attack attempts.</p>
<h2><code>clickjane.css</code> helps detect clickjacking attacks for all browsers</h2>
<p>Until browser manufacturers provide built-in protections against clickjacking attacks in their software (which is arguably the best place for such logic in the first place), I&#8217;ve started putting together <a href="http://github.com/meitar/clickjane-css/">a user style sheet I&#8217;m calling <code>clickjane.css</code></a> that attempts to instantly reveal common clickjacking attempts. Since it&#8217;s a <acronym title="Cascading Style Sheets">CSS</acronym> user style sheet, this approach should be cross-browser compatible so that users of any browser including Safari, Opera, and other browsers that don&#8217;t have other means of protecting against clickjacking attacks can use it.</p>
<p>I&#8217;ve only recently learned about this class of exploits and so I&#8217;m not supremely well-informed on the topic. As a result, the <code>clickjane.css</code> file is relatively sparse and currently only reveals what I&#8217;m sure is a small set of clickjacking attmpts. However, as I research the topic further and learn more about the actual underlying <acronym title="HyperText Markup Language">HTML</acronym> and <acronym title="Cascading Style Sheets">CSS</acronym> that clickjacking uses, I&#8217;ll be updating the <code>clickjane.css</code> code to reveal those attempts as well.</p>
<p>Naturally, contributions and assistance in any form are most welcome! Learn more about <code>clickjane.css</code> as well as how to use it at the <a href="http://github.com/meitar/clickjane-css/wikis">Clickjane <acronym title="Cascading Style Sheets">CSS</acronym> Github wiki</a>.</p>
<h2>Before and after <code>clickjane.css</code></h2>
<p>Here are two example screenshots of <a href="http://www.planb-security.net/notclickjacking/iframetrick.html">a benign clickjacking demo</a>.</p>
<ol>
<li>Before:
<div><div id="attachment_858" class="wp-caption alignnone" style="width: 310px"><a href="http://maymay.net/blog/wp-content/uploads/2008/12/before-clickjane.png"><img src="http://maymay.net/blog/wp-content/uploads/2008/12/before-clickjane-300x283.png" alt="Screenshot of Safari before clickjane.css is used to expose clickjacking attempts." title="before-clickjane" width="300" height="283" class="size-medium wp-image-858" /></a><p class="wp-caption-text">Screenshot of Safari before clickjane.css is used to expose clickjacking attempts.</p></div></div>
</li>
<li>After:
<div><div id="attachment_859" class="wp-caption alignnone" style="width: 310px"><a href="http://maymay.net/blog/wp-content/uploads/2008/12/after-clickjane.png"><img src="http://maymay.net/blog/wp-content/uploads/2008/12/after-clickjane-300x283.png" alt="Screenshot of Safari after clickjane.css is used to expose clickjacking attempts." title="after-clickjane" width="300" height="283" class="size-medium wp-image-859" /></a><p class="wp-caption-text">Screenshot of Safari after clickjane.css is used to expose clickjacking attempts.</p></div></div>
</li>
</ol>
<h2>Good habits you should get into to mitigate clickjacking risks</h2>
<p>Here is a list of behaviors that you should make habitual while you browse the web. Engaging in these behaviors can dramatically reduce the likelihood that you will be victimized by a clickjacking attack.</p>
<ul>
<li>Explicitly log out of any service you have logged in to when you are done. That log-out button is there for a reason: use it!</li>
<li>Avoid providing your browser with &#8220;Auto-Complete&#8221; information for critical sites, such as your bank.</li>
<li>Make sure you are <a href="http://www.adobe.com/support/security/advisories/apsa08-08.html">running Flash Player 10 or greater, which mitigates this vulnerability</a> for Adobe Flash content.</li>
</ul>
<h2>More resources to learn about clickjacking</h2>
<ul>
<li><a href="http://hackademix.net/2008/10/26/more-clickjacking/">Hackademix.net &#8211; More clickjacking</a> links to the <a href="http://video.google.com/videoplay?docid=-5747622209791380934">OWASP presentation</a>, the <a href="http://www.sectheory.com/clickjacking.htm">white paper</a>, and a blog post showing <a href="http://sirdarckcat.blogspot.com/2008/10/about-css-attacks.html">several <acronym title="Cascading Style Sheets">CSS</acronym>-based exploits</a>.</lI>
</ul>
<h2>Translations of this article:</h2>
<ul>
<li><ins datetime="2011-04-20T07:06:13+00:00"><a href="http://www.designcontest.com/show/everything-in-between-be">Belorussian (thanks, Bohdan Zograf)</a></ins></li>
<li><ins datetime="2011-08-24T20:14:39+00:00"><a href="http://webhostingrating.com/libs/clickjane-css-a-css-ua">Ukrainian (thanks, Alyona Lompar)</a></ins></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2008/12/29/clickjanecss-a-css-user-style-sheet-to-help-detect-and-avoid-clickjacking-attacks/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Why CSS needs delegation capabilities and not &#8220;variables&#8221;</title>
		<link>http://maymay.net/blog/2008/12/14/why-css-needs-delegation-capabilities-and-not-variables/</link>
		<comments>http://maymay.net/blog/2008/12/14/why-css-needs-delegation-capabilities-and-not-variables/#comments</comments>
		<pubDate>Sun, 14 Dec 2008 07:55:04 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Crosspost]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tech/Computing]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Standards]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=815</guid>
		<description><![CDATA[It&#8217;s been too long since I joined the fun, if amazingly heated, debates over the direction that Web standards are moving in. Recently, given the &#8220;free&#8221; time to do so, I decided to dive head first into what is (sadly) an almost 14 year old debate. The result is this blog post, which is mostly [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been too long since I joined the fun, if amazingly heated, debates over the direction that Web standards are moving in. Recently, given the &#8220;free&#8221; time to do so, I decided to dive head first into what is (sadly) an almost 14 year old debate. The result is this blog post, which is mostly a response to Bert Bos&#8217;s essay <cite><a href="http://www.w3.org/People/Bos/CSS-variables">Why &#8220;variables&#8221; in <acronym title="Cascading Style Sheets">CSS</acronym> are harmful</a></cite> and Matt Wilcox&#8217;s opposing response to that essay, <cite><a href="http://mattwilcox.net/archive/entry/id/991/">Why <acronym title="Cascading Style Sheets">CSS</acronym> needs to borrow from programming languages</a></cite>. Their articles are each worthy of a read, possibly before this one.</p>
<p>Here&#8217;s <strong>the summary</strong> of my argument.</p>
<p class="summary">Adding many &#8220;programmatic&#8221; features to the <acronym title="Cascading Style Sheets">CSS</acronym> language such as variables, macros, or flow control <em>is</em> a mistake. However, <acronym title="Cascading Style Sheets">CSS</acronym>&#8216;s failure to simply encode visual <em>relationships</em> (instead of merely typographic properties)&mdash;a severe deficiency in the core language itself&mdash;requires the addition of delegation features. With the additional capability to reference an arbitrary element&#8217;s computed value regardless of its hierarchical context, <acronym title="Cascading Style Sheets">CSS</acronym> will be more accessible to both amateur and professional web designers, more capable, and will more forcefully promote the semantic Web and its ideals.</p>
<h3>In this corner: <acronym title="Cascading Style Sheets">CSS</acronym> variables are harmful</h3>
<p>Bert does a great job of summarizing the conclusion of his argument himself. In his essay, Bert says:</p>
<blockquote cite="http://www.w3.org/People/Bos/CSS-variables"><p>Adding any form of macros or additional scopes and indirections, including symbolic constants, is not just redundant, but changes <acronym title="Cascading Style Sheets">CSS</acronym> in ways that make it unsuitable for its intended audience. Given that there is currently no alternative to <acronym title="Cascading Style Sheets">CSS</acronym>, these things must not be added.</p></blockquote>
<p>As we all know, one of the wonderful things about <acronym title="Cascading Style Sheets">CSS</acronym> is that the core language itself is remarkably simple. (What&#8217;s <em>not</em> simple is the spectacular way browser manufacturers have destroyed everyone&#8217;s hope that implementing <acronym title="Cascading Style Sheets">CSS</acronym>-based designs in the real world will ever be easy, but that&#8217;s a whole different can of worms.) Fundamentally, <acronym title="Cascading Style Sheets">CSS</acronym>&#8216;s syntax can be explained with a mere three major components: property/value pairs, declaration blocks, and rule sets.</p>
<p>What this means is that <acronym title="Cascading Style Sheets">CSS</acronym> <em>as a language</em> is stupidly easy to learn. I think everyone would agree that it&#8217;s certainly easier to learn than, say, JavaScript or <a href="//en.wikipedia.org/wiki/Extensible_Stylesheet_Language"><acronym title="eXtensible Stylesheet Language">XSL</acronym></a>. Now, that&#8217;s important because, without putting too fine a point on it, Bert mentions multiple times that <acronym title="Cascading Style Sheets">CSS</acronym>&#8216;s &#8220;intended audience&#8221; are the diverse and likely relatively technically ignorant content authors that are responsible for the overwhelming majority of web pages on the public Internet today.</p>
<p>He makes the very good point that <q cite="http://www.w3.org/People/Bos/CSS-variables">The value of the semantic Web isn&#8217;t defined by how well structured the best documents are, but by how well structured the vast majority of documents</q> are. In other words, <acronym title="Cascading Style Sheets">CSS</acronym> needs to remain instantly useable <em>and reusable</em> to these untrained, amateur web content publishers for the benefits of self-describing documents (i.e., the semantic Web) to see mass adoption.</p>
<p>To wit:</p>
<blockquote cite="http://www.w3.org/People/Bos/CSS-variables"><p>reusing other people&#8217;s style sheets is more difficult if those style sheets contain user-defined names. Class names are an example. Their names may suggest why the author created them (assuming they are in a language you understand), but typically you will have to look at the document to see where they occur and why. Symbolic constants make that problem worse.</p></blockquote>
<p>And, later:</p>
<blockquote cite="http://www.w3.org/People/Bos/CSS-variables"><p>For many people, style sheets with constants will thus simply not be usable. It is too difficult to look in two places at once, the place where a value is used and the place where it is defined, if you don&#8217;t know why the rule is split in this way. Many people are confused by indirection anyway and adding an extra one, in addition to the element and class names, has the same effect as obfuscating the style sheet.</p></blockquote>
<p>Whether or not you believe Bert Bos is underestimating the average web designer, it&#8217;s pretty clear that these are really good points. Nobody wants <acronym title="Cascading Style Sheets">CSS</acronym> to be obfuscated, hard to learn, or hard to reuse. That&#8217;d just be crazy talk.</p>
<h3>In the other corner: <acronym title="Cascading Style Sheets">CSS</acronym> variables are a real-world requirement</h3>
<p>The more features you add to an application, a programming language, or indeed any software, the more difficult it becomes to grok it. As the Python people would say, the larger a language gets the more difficult it is to hold all of it in your head. Nevertheless, adding &#8220;features&#8221; is sometimes the only way to add <em>capabilities</em>, and I don&#8217;t think anyone in their right mind would argue that, once written, software should never change. (That&#8217;d just be crazy talk, too.)</p>
<p>In his opposing arguments, Matt Wilcox recognizes this when he says, <q cite="http://mattwilcox.net/archive/entry/id/991/">Yes, the syntax should be simple, but the capabilities of <acronym title="Cascading Style Sheets">CSS</acronym> should not.</q> What he&#8217;s alluding to without verbalizing it is the balance between adding necessary capabilities without unnecessarily growing the &#8220;size of the language.&#8221;</p>
<p>However, Matt says that modern web design <em>methodologies</em> (e.g., separation of concerns between structure, presentation, and behavior) dictate that <acronym title="Cascading Style Sheets">CSS</acronym> needs more capabilities than it currently has:</p>
<blockquote cite="http://mattwilcox.net/archive/entry/id/991/"><p><acronym title="Cascading Style Sheets">CSS</acronym> lacks capabilities to allow truly flexible design, requiring layer upon layer of ‘tricks’ to accomplish certain objectives, requiring content to be structured ‘just so’ to achieve a display objective, or in the case of some designs proving instead to be completely incapable.</p>
<p>[…]</p>
<p><acronym title="Cascading Style Sheets">CSS</acronym>’s positioning is a cludge. It’s a cludge because you can only position relative to the last positioned parent container. Well, that limitation in itself dictates that all positioning relies upon how the content is structured. And that means the presentation and the content are not truly separable.</p></blockquote>
<p>To align <acronym title="Cascading Style Sheets">CSS</acronym>&#8216;s capabilities with the requirements of real-world web design objectives, he says, <acronym title="Cascading Style Sheets">CSS</acronym> needs to be capable of describing relationships between semantically and structurally arbitrary but visually related elements.</p>
<blockquote cite="http://mattwilcox.net/archive/entry/id/991/"><p>Visual design is fundamentally about relationships between elements. For all of the artistic flourishes and creativity, it’s about relationships. ‘That yellow’ only grabs your attention because of its contrasting relationship with ‘that blue’. ‘This heading’ only works as a heading because of it’s exaggerated relationship to the size of the body text. […] <acronym title="Cascading Style Sheets">CSS</acronym> has no clue about relationships, period. And that’s why <acronym title="Cascading Style Sheets">CSS</acronym> as it stands right now, is not good enough. That’s why <acronym title="Cascading Style Sheets">CSS</acronym> without variables (true variables), without basic logic, without maths, can never be as flexible as we need it to be.</p></blockquote>
<p>This is what web designers have been complaining about for (what feels like hundreds of) years. The fact that <acronym title="Cascading Style Sheets">CSS</acronym> has no capability to describe <em>presentational relationships</em> between elements in addition to directly describing an individual element&#8217;s presentational properties is a gaping hole that sorely degrades its ability to be a media-agnostic styling language. Every single web designer I&#8217;ve worked with has gasped at this omission, and though at first I didn&#8217;t understand why, the more I understood the principles behind graphic design the more I came to realize how fundamentally problematic this omission really is.</p>
<h3>Adding delegation makes <acronym title="Cascading Style Sheets">CSS</acronym> <em>easier</em> for designers</h3>
<p>As Matt eloquently stated, design is all about relationships. Good web designers create designs by constructing visual elements that have strong, often exacting relationships with other visual elements. There are many names and examples for this: visual language, visual hierarchy, the golden ratio, the grid, visual balance, the typographer&#8217;s scale, and so on.</p>
<p>What happens when the designer tries to define <em>a relationship</em> between elements? &#8220;How do I say that the whitespace between element A and element B should always be the same? How do I define element A&#8217;s height as half of element B&#8217;s?&#8221; These definitions, which are natural and necessary to the way designers work in both their mind and their mediums, are impossible to encode in <acronym title="Cascading Style Sheets">CSS</acronym>.</p>
<p>The closest you can get is declaring the same values to each element&#8217;s properties, not describing the relationship itself. This suffices only so long as these values are known ahead of time and are the same as one another, which severely limits the design possibilities we are capable of (without resorting to what Matt calls &#8220;tricks&#8221;). <em>That&#8217;s</em> why achieving simple visual effects are actually very complex and so, sadly, <em>that&#8217;s</em> where you&#8217;ll find the majority of indirection and obfuscation in <acronym title="Cascading Style Sheets">CSS</acronym> today. (I&#8217;m looking at you, <a href="http://www.alistapart.com/articles/fauxcolumns/">faux columns</a>.)</p>
<h3>So who wins?</h3>
<p>Both Bert Bos and Matt Wilcox have made some great points. Bert rightfully wishes to keep <acronym title="Cascading Style Sheets">CSS</acronym> lean and simple, even at the expense of some arguably beneficial styling power. Matt, on the other hand, argues that our needs as web designers have evolved faster than the technology to the point where <acronym title="Cascading Style Sheets">CSS</acronym> is <em>too</em> limited, fundamentally so.</p>
<p>The truth is, they&#8217;re both right. And they&#8217;re both wrong. Or rather, they are each taking a position that is too extreme. Bert&#8217;s absolutely correct when says that many of these proposed extensions are redundant and harmful, and yet Matt&#8217;s also correct that <acronym title="Cascading Style Sheets">CSS</acronym> lacks some fundamental capabilities that designers <em>expect</em> to be present.</p>
<p>Bert says that the <acronym title="Cascading Style Sheets">CSS</acronym> capabilities everyone&#8217;s asking for can be implemented using techniques that don&#8217;t rely on <acronym title="Cascading Style Sheets">CSS</acronym> whatsoever. These techniques, he says, make things like true <acronym title="Cascading Style Sheets">CSS</acronym> variables &#8220;redundant.&#8221;</p>
<blockquote cite="http://www.w3.org/People/Bos/CSS-variables"><p>There are examples of <acronym title="Cascading Style Sheets">CSS</acronym> with constants to satisfy all styles of programming, e.g.: <a href="http://davidwalsh.name/css-variables-php-dynamic">David Walsh</a> (in <acronym title="PHP Hypertext Preprocessor; an HTML-embedded scripting language">PHP</acronym>), <a href="http://sperling.com/examples/pcss/">Tedd Sperling</a> (in <acronym title="PHP Hypertext Preprocessor; an HTML-embedded scripting language">PHP</acronym>), <a href="http://www.digital-web.com/articles/generating_dynamic_css_with_php/">Digital Web Magazine</a> (in <acronym title="PHP Hypertext Preprocessor; an HTML-embedded scripting language">PHP</acronym>), <a href="http://ecoconsulting.co.uk/training/css_includes.shtml">Eco Consulting</a> (in <acronym title="Server Side Include">SSI</acronym>), and <a href="http://icant.co.uk/articles/cssconstants/">Christian Heilmann</a> (<acronym title="Server Side Include">SSI</acronym> and <acronym title="PHP Hypertext Preprocessor; an HTML-embedded scripting language">PHP</acronym>).</p></blockquote>
<p>Quite simply, he&#8217;s correct in stating that programmatic features need not be added to <acronym title="Cascading Style Sheets">CSS</acronym> proper to achieve desired results, but he&#8217;s incorrect in his apparent thinking that designers will be able to use these other tools to leverage <acronym title="Cascading Style Sheets">CSS</acronym>. Take, for instance, the probably more familiar (though not linked above) notion of using JavaScript to manipulate <acronym title="Cascading Style Sheets">CSS</acronym> values.</p>
<pre><code class="javascript">var x = document.getElementById('SideBar'); // get #SideBar element
var y = document.getElementById('MainColumn'); // get #MainColumn
var z = document.defaultView.getComputedStyle(y, '').getPropertyValue('height'); // get computed height of #MainColumn
x.style.height = ( parseInt(z) / 2 ) + 'px'; // set #SideBar's height 1/2 of #MainColumn's</code></pre>
<p>This is an example of programmatic code that uses variables and expressions. It sets the element with the ID of <code>SideBar</code> to half the pixel height of the element with the ID of <code>MainColumn</code>. It does this by obtaining the <code>MainColumn</code>&#8216;s height (at the time this code runs) and saving it in a variable, then performs some trivial math to half the value and use the result as the pixel height of the <code>SideBar</code>.</p>
<p>Doing this is currently impossible with <acronym title="Cascading Style Sheets">CSS</acronym> alone, yet it&#8217;s something that clearly belongs with whatever other &#8220;presentational&#8221; code exists and not in &#8220;programmatic&#8221; scripts that would otherwise be charged with defining &#8220;functionality.&#8221; As Matt states, using JavaScript to &#8220;script&#8221; solutions to <acronym title="Cascading Style Sheets">CSS</acronym>&#8216;s shortcomings like this is not an acceptable answer.</p>
<blockquote cite="http://mattwilcox.net/archive/entry/id/991/"><p><acronym title="Cascading Style Sheets">CSS</acronym> doesn’t have [basic logic or maths]. Nor is it the job of JavaScript to make up for this lack of abilities. JavaScript is about interaction behaviour, and what we are talking about here is pure display logic. Not interaction logic.</p></blockquote>
<p>Moreover, the <em>place</em> designers expect to put code like this is, of course, into a <acronym title="Cascading Style Sheets">CSS</acronym> style sheet. The <em>way</em> designers expect to put code like this into <acronym title="Cascading Style Sheets">CSS</acronym> is by adding delegation features. Requiring designers to learn JavaScript (or any other programming language) to encode such design relationships is nothing short of ridiculous. In what world is that easier for untrained laymen to understand than <acronym title="Cascading Style Sheets">CSS</acronym>?</p>
<h3>Adding delegation to <acronym title="Cascading Style Sheets">CSS</acronym> is worth the effort</h3>
<p>One of Bert&#8217;s arguments against such additions to <acronym title="Cascading Style Sheets">CSS</acronym> is that implementations would become harder to create, and that we&#8217;ll (almost certainly) see more bugs.</p>
<blockquote cite="http://www.w3.org/People/Bos/CSS-variables"><p>extending <acronym title="Cascading Style Sheets">CSS</acronym> makes implementing more difficult and programs bigger, which leads to fewer implementations and more bugs. That has to be balanced against the usefulness of the extension.</p></blockquote>
<p>Although I do agree with his statement that an extension&#8217;s usefulness has to be balanced against its potential costs, I think something so fundamental to design methodology as delegation greatly overcompensates for the cost of such implementation efforts. Moreover, if I understand Bert correctly and as he also discusses, the majority of implementations that would need to implement such delegation already have relatively complex internal structures to make the implementation effort somewhat easier:</p>
<blockquote cite="http://www.w3.org/People/Bos/CSS-variables"><p>There is no scoping [in proposals that only define <em>global</em> constants]. That means that an implementation needs a symbol table, but no stack. A stack would require a little bit more memory, but mostly it would make implementations more complex. (Although every programmer has, one hopes, learnt to program a symbol table with lexical scope during his training.) Constants in <acronym title="Cascading Style Sheets">CSS</acronym> are thus easier than, e.g., <a href="http://www.w3.org/TR/xml-names/"><acronym title="eXtensible Markup Language">XML</acronym> Namespaces,</a> which <em>are</em> lexically scoped.</p>
<p>It is different for those <acronym title="Cascading Style Sheets">CSS</acronym> implementations that provide a <a href="http://www.w3.org/TR/DOM-Level-2-Style/"><acronym title="Cascading Style Sheets">CSS</acronym> Object Model</a> (an <acronym title="Application Programming Interface">API</acronym> for manipulating a style sheet in memory). Those implementations <em>do</em> need to keep track of scope in some way, because adding or removing a line of the style sheet can make a previously redundant definition become meaningful.</p></blockquote>
<p>In order to use JavaScript to solve many of the shortcomings of <acronym title="Cascading Style Sheets">CSS</acronym>, as <em>huge</em> numbers of professional web developers do routinely, we use the very <acronym title="Cascading Style Sheets">CSS</acronym> Object Model whose prior implementation already exists for us to build upon.</p>
<h3><acronym title="Cascading Style Sheets">CSS</acronym> delegation doesn&#8217;t grow the size of the language</h3>
<p>For the sake of argument, let&#8217;s simplify our requirement somewhat so that our somewhat contrived example of design intent is to <em>create a relationship</em> between the <code>MainColumn</code> and the <code>SideBar</code> elements such that they are of equal height. This is more informally known as &#8220;making columns.&#8221;</p>
<p>Here&#8217;s what a natural, hypothetical snippet of <acronym title="Cascading Style Sheets">CSS</acronym> would look like if the language supported delegation features such that it could encode visual relationships.</p>
<pre><code class="css">#SideBar { height: #MainColumn; }</code></pre>
<p>This code theoretically says almost the exact same thing as the JavaScript shown earlier (save for the division, of course); it takes the computed value of the <code>MainColumn</code> element&#8217;s height property and applies that value to the <code>SideBar</code> element&#8217;s height property. In other words, &#8220;The SideBar&#8217;s (element B&#8217;s) height is always the same as the MainColumn&#8217;s (element A&#8217;s).&#8221; (Of course, this is a parse error in reality today.)</p>
<p>This extremely trivial example has some remarkably far-reaching implications, and yet there is really nothing radical about its syntax. Making this a reality significantly expands the capabilities of <acronym title="Cascading Style Sheets">CSS</acronym> without dramatically increasing the size of the language. This capability would not only <a href="http://mattwilcox.net/archive/entry/id/1030/" title="Why you should not use display:table; for layout.">beat the pants off</a> &#8220;<a href="http://www.sitepoint.com/blogs/2008/10/22/everything-you-know-about-css-is-wrong/" title="SitePoint's featuring articles and books about browser support for this."><acronym title="Cascading Style Sheets">CSS</acronym> tables</a>,&#8221; it also potentially obsoletes the arguably <a href="http://ejohn.org/blog/css3-template-layout/" title="Just because John Resig likes it doesn't mean it's good.">misguided efforts of the <acronym title="Cascading Stlye Sheets level 3">CSS3</acronym> Advanced Layout</a> and Grid Positioning modules, too.</p>
<p>We&#8217;ve long since abandoned <code>table</code> layouts because they force us to use presentational markup. That&#8217;s still what &#8220;<acronym title="Cascading Style Sheets">CSS</acronym> tables&#8221; force us to do, too. In other words, with <code>display: table</code>, the <code>SideBar</code> needs to be a child of the <code>MainColumn</code> element or, maybe worse and more likely, a child of a semantically meaningless wrapper element.</p>
<p><acronym title="Cascading Style Sheets">CSS</acronym> positioning was introduced with the promise of freeing us from source-order-dependent styling, without which there is no hope of efficiently abstracting presentation away from structure. Moreover, <strong>abstracting presentation away from structure is the single most important prerequisite needed to improve document reusability and strengthen the semantic Web</strong>. Absolute positioning works, but limitations elsewhere in <acronym title="Cascading Style Sheets">CSS</acronym> mean its use is problematic for many designs, so in practice it doesn&#8217;t gain widespread adoption.</p>
<p>Here&#8217;s a theoretical solution to a two-column and a footer layout using <acronym title="Cascading Style Sheets">CSS</acronym> delegation with this semantic HTML:</p>
<pre><code class="html">&lt;body&gt;
    &lt;div id="MainColumn"&gt;I'm the main column.&lt;/div&gt;
    &lt;div id="SideBar"&gt;I'm the right-hand sidebar.&lt;/div&gt;
    &lt;div id="Legalese"&gt;No one will read me.&lt;/div&gt;
&lt;/body&gt;
</code></pre>
<p>The <acronym title="Cascading Style Sheets">CSS</acronym> would look extremely familiar, possibly like this:</p>
<pre><code class="css">#MainColumn { margin: 0 25% 1em 0; float: left; }
#SideBar { width: 25%; min-height: #MainColumn; }</code></pre>
<p>Using the same <acronym title="HyperText Markup Language">HTML</acronym>, the same solution using the <acronym title="Cascading Stlye Sheets level 3">CSS3</acronym> Advanced Layout module would look something more like this, although to be frank I&#8217;m not certain I fully understand this syntax even after staring at it for months:</p>
<pre><code class="css">body {
    display: "a  b"
             ".  ." /1em
             "c  c"
             75% 25%
}
#MainColumn { position: a; }
#SideBar { position: b; }
#Legalese { position: c; }
</code></pre>
<p>Not only does there seem to me to be far more indirection in this method than there would be using <acronym title="Cascading Style Sheets">CSS</acronym> delegation, there is also an enormous increase to the size of the <acronym title="Cascading Style Sheets">CSS</acronym> language: a new (ASCII-art?!) value to the display property whose syntax is clunky at best. A similar story can be <a href="http://ajaxian.com/archives/w3c-css-grid-positioning" title="Ajaxian reports on a rumor that Internet Explorer 8 will add support for Grid Positioning and shows what that might look like in code.">said of the <acronym title="Cascading Stlye Sheets level 3">CSS3</acronym> Grid Positioning module</a>, which does lots more than just add a new (already complex) <code>gr</code> <acronym title="Cascading Style Sheets">CSS</acronym> unit.</p>
<p>The upshot is that the Advanced Layout and the Grid Positioning modules are doing <em>some</em> of the right things in <em>many</em> of the wrong ways. Both those modules add unnecessary complexity to <acronym title="Cascading Style Sheets">CSS</acronym> without giving designers a natural way to say what they mean. They do more to introduce obfuscation and indirection than simple delegation would, and they aren&#8217;t as broadly capable. Both of them try to solve a specific problem instead of dealing with fundamental deficiencies in the <em>toolset</em> designer&#8217;s have to work with.</p>
<h3>Designers want relationships via delegation, not variables</h3>
<p>Adding delegation such as that I&#8217;ve just shown is a natural, necessary addition to <acronym title="Cascading Style Sheets">CSS</acronym> because it is how designers create visual components&mdash;such as grids&mdash;in their designs. Variables (and constants, and macros, etc.), which simply reuse and modify pre-defined statements aren&#8217;t what designers care about. Adding them <em>will</em> bloat <acronym title="Cascading Style Sheets">CSS</acronym> without adding useful functionality.</p>
<p>&#8220;Okay,&#8221; you may be saying to yourself, &#8220;but delegation is itself a kind of variable, isn&#8217;t it?&#8221; Technically yes, however adding delegation resolves the core deficiency in the <acronym title="Cascading Style Sheets">CSS</acronym> language that designers need to use every day. Yes, it&#8217;s technically a form of variable, but that&#8217;s not how designers think of it. To say that one element&#8217;s visual properties is like another makes a variable only by creating a logical and visually appropriate mapping from the first element&#8217;s property to the second independent of markup, thereby avoiding indirection in the form of a variable name or other unfamiliar symbol.</p>
<p>Delegation like this doesn&#8217;t require the addition of anything other than what already exists in <acronym title="Cascading Style Sheets">CSS</acronym>. Class names and ID values are identifiers whose indirection people <em>already</em> have to deal with. Using them for delegation (to reference another element&#8217;s <em>style</em>) doesn&#8217;t increase the cognitive load any more than using them to reference <em><acronym title="HyperText Markup Language">HTML</acronym> elements</em> does. Though untested, the cognitive load might actually be even less since the <acronym title="Cascading Style Sheets">CSS</acronym> delegation&#8217;s references could be in the same (style sheet) file.</p>
<p>Moreover, delegation will increase the likelihood of document reusability by enabling style sheets to be more self-describing, more self-referential, in a similar way as good markup is. It satisfies a very fundamental need that designers have to define graphical relationships between elements. At the same time, it does so in a way that is natural to both their way of thinking and beneficial to the separation of concerns principle on which the &#8220;web stack&#8221; (the trifecta of <acronym title="HyperText Markup Language">HTML</acronym>, <acronym title="Cascading Style Sheets">CSS</acronym>, and JavaScript) is based.</p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2008/12/14/why-css-needs-delegation-capabilities-and-not-variables/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>WP-Oomph: Add the Oomph Microformat Overlay to your WordPress blog</title>
		<link>http://maymay.net/blog/2008/11/11/wp-oomph-add-the-oomph-microformat-overlay-to-your-wordpress-blog/</link>
		<comments>http://maymay.net/blog/2008/11/11/wp-oomph-add-the-oomph-microformat-overlay-to-your-wordpress-blog/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 12:44:02 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Crosspost]]></category>
		<category><![CDATA[Tech/Computing]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Standards]]></category>
		<category><![CDATA[Writing and blogging]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[Semantic Web]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=767</guid>
		<description><![CDATA[I&#8217;ve just developed a completely idiotic (by which I mean brain-dead simple) plugin for WordPress that will add the Oomph Microformat Toolkit to all WordPress-generated pages. If you use a WordPress template that encodes your data with valid microformats anywhere on your page, this means when you install the plugin your users will see the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just developed a completely idiotic (by which I mean brain-dead simple) plugin for WordPress that will add the <a href="http://visitmix.com/Lab/Oomph">Oomph Microformat Toolkit</a> to all <a href="//wordpress.org/">WordPress</a>-generated pages. If you use <a href="http://wordpress.org/extend/themes/tags/microformats" title="Check out the various WordPress themes that support microformats out of the box!">a WordPress template that encodes your data with valid microformats</a> anywhere on your page, this means when you install the plugin your users will see the Oomph microformat overlay and will be able to instantly export this encoded data.</p>
<p>This page is a live example, so if you&#8217;re using a JavaScript-enabled browser you should see a microformat icon on the top-left of the viewport that is pulling data from (at least) my &#8220;The bio&#8221; section in my sidebar. Go ahead, click it. I&#8217;ll wait.</p>
<p>Pretty nifty, isn&#8217;t it? Naturally, all of the credit for this functionality belongs to the Oomph team, not me. If you want to learn how to add <em>microformats</em> to your blog, I&#8217;d recommend <a href="http://www.ablognotlimited.com/articles/getting-semantic-with-microformats-part-1-rel/">Emily Lewis&#8217;s latest series of blog posts, <cite>Getting Semantic with Microformats</cite></a>. If you want to learn how to easily add the Oomph microformat overlay to your WordPress blog, read on.</p>
<h3>The backstory</h3>
<p>After <a href="http://arstechnica.com/news.ars/post/20081006-ask-com-rearms-with-semantics-rich-media-in-search-war.html">Ask.com&#8217;s announcement that they are adding semantic search capabilities to their search engine</a>, there&#8217;s little doubt in anyone&#8217;s mind that the semantic web is the future&#8217;s web. As far as I know, Google has yet to reveal similar initiatives but they are clearly in the know as well. Mark Birbeck, one of the smart folks who <a href="http://www.w3.org/TR/xhtml-rdfa-primer/">devised <acronym title="Resource Description Framework attributes">RDFa</acronym></a>, recently gave <a href="http://youtube.com/watch?v=mxE3FeOyS-E">a Google Tech Talk</a> that made the point that semantics are the next big thing in the Internet search engine game.</p>
<p>However, for semantic web <em>stuff</em> to really take hold, two things need to happen first. I think these things need to look like this:</p>
<ol>
<li>Developers must create tools, plugins, and other software that makes it possible for the wider community to create compelling, interoperable applications that support semantic encoding. Thankfully, we are already at this point, with toolkits like the <a href="http://visitmix.com/Lab/Oomph">Oomph Microformat toolkit coming out of MixLabs</a>.</li>
<li>Armed with these software tools, <acronym title="Content Management System">CMS</acronym> and other publishing platforms need to adopt semantics as first-class features of their platforms, and build interfaces that end-users can make immediate use of. This is where we still need to go, though some platforms like <a href="http://www.sitepoint.com/blogs/2008/03/05/drupal-7-a-living-breathing-semantic-web-citizen/">Drupal have begun to pave the way for this</a>.</li>
</ol>
<p>Drupal 7 will be fantastic, I&#8217;m sure, but we live in the here and now. I saw the Oomph microformat overlay on Emily Lewis&#8217;s blog and was more convinced than ever that if everyone—programmers and laymen alike—had easy access to these tools, they&#8217;d simply be pounding down the doors to use them. So that&#8217;s why I sat down and wrote a completely idiotic plugin for WordPress that makes it completely, utterly, brain-dead simple for anyone with <a href="http://wordpress.org/extend/themes/tags/microformats" title="Check out the various WordPress themes that support microformats out of the box!">a microformats-enabled WordPress theme</a> to add the overlay to their site.</p>
<h3 id="wp-oomph-download-the-plugin">WP-Oomph: Download the plugin</h3>
<p>My request to add the plugin to the <a href="//wordpress.org/extend/plugins/">WordPress.org Plugin Directory</a> has <del datetime="2008-11-12T14:45:28+00:00">not yet</del> been completed<del datetime="2008-11-12T14:45:28+00:00">, so in the mean time I&#8217;m hosting the plugin right here. (When/if it&#8217;s accepted it&#8217;ll end up being</del> <ins datetime="2008-11-12T14:45:28+00:00">The plugin is</ins> <a href="//wordpress.org/extend/plugins/wp-oomph/">hosted on that site permanently</a>.<del datetime="2008-11-12T14:45:28+00:00">)</del></p>
<p>The latest version is: <strong class="latest-version">0.1.1</strong>.</p>
<p>Download the <a href="http://wordpress.org/extend/plugins/wp-oomph/">latest version of the WP-Oomph plugin</a>.</p>
<p>Thanks to the Oomph team&#8217;s work, the plugin is a ridiculous 1-liner (for now) that uses <a href="http://codex.wordpress.org/Function_Reference/wp_enqueue_script">WordPress&#8217;s <code>wp_enqueue_script()</code> function</a> to call both its included <a href="//jquery.com/">jQuery</a> library and the Oomph library itself. And, well, that&#8217;s it. I told you it was idiotic, but at least now the whole process of microformat-enabling a WordPress blog is 100% point-and-click.</p>
<h3 id="wp-oomph-frequently-asked-questions">WP-Oomph: Frequently Asked Questions</h3>
<dl>
<dt>I installed and activated the plugin, but nothing is different. How come?</dt>
<dd>
<p>First, view the source of your WordPres-generated page and make sure you see a line similar to the following near the top:</p>
<pre class="html" style="white-space:normal;">&lt;script type='text/javascript' src='http://visitmix.com/labs/oomph/1.0/Client/oomph.min.js?ver=1.0'&gt;&lt;/script&gt;</pre>
<p>If you see that but there&#8217;s still nothing different about your page, then you probably don&#8217;t have any (valid) microformats. You might consider <a href="http://wordpress.org/extend/themes/tags/microformats" title="Check out the various WordPress themes that support microformats out of the box!">switching to a WordPress theme with built-in microformat support</a>, or modifying your theme&#8217;s code to add some of your own. You can <a href="http://microformats.org/wiki/wordpress">learn more about the support WordPress offers for microformats in the Microformat wiki</a>.</p>
</dd>
<dt>The plugin does let me do <var>X</var> thing that I want to do! Why not?</dt>
<dd>
<p>Most likely because I haven&#8217;t taken <var>X thing</var> into account. Sorry, I&#8217;m not a psychic (as much as I wish I were). However, you&#8217;re encouraged to leave a comment on this post or to contact me elsewhere to request that I add capabilities to the plugin. Better yet, if you&#8217;re comfortable doing so, send me a patch.</p>
</dd>
</dl>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2008/11/11/wp-oomph-add-the-oomph-microformat-overlay-to-your-wordpress-blog/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Add a post limit and output format to the WordPress Category Posts plugin v2.0</title>
		<link>http://maymay.net/blog/2008/09/19/add-a-post-limit-and-output-format-to-the-wordpress-category-posts-plugin-v20/</link>
		<comments>http://maymay.net/blog/2008/09/19/add-a-post-limit-and-output-format-to-the-wordpress-category-posts-plugin-v20/#comments</comments>
		<pubDate>Fri, 19 Sep 2008 15:24:25 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tech/Computing]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Writing and blogging]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=643</guid>
		<description><![CDATA[Tonight I wrote a quick (and idiotic) patch to the very simple WordPress Category Post plugin v2.0. This backwards-compatible patch features: parameter-based post limit to define how many posts the plugin function will print parameter-based format option to output the posts in real &#60;li&#62; elements The wp-category-posts.php patch file is available for download here. To [...]]]></description>
			<content:encoded><![CDATA[<p>Tonight I wrote a quick (and idiotic) patch to the very simple WordPress Category Post plugin v2.0. This backwards-compatible patch features:</p>
<ul>
<li>parameter-based post limit to define how many posts the plugin function will print</li>
<li>parameter-based format option to output the posts in real <code>&lt;li&gt;</code> elements</li>
</ul>
<p>The <a href='http://maymay.net/blog/wp-content/uploads/2008/09/wp-category-posts.patch'><code>wp-category-posts.php</code> patch file is available for download here</a>. To apply the patch, run the following commands at your shell promp:</p>
<pre class="shell">
cd <var>path/to/wordpress/installation</var>/wp-content/plugins/wordpress-category-posts
patch -p0 < <var>path/to/downloaded</var>/wp-category-posts.patch
</pre>
<p>I&#8217;m hoping this will get integrated as the next version of the plugin, perhaps version 2.1.</p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2008/09/19/add-a-post-limit-and-output-format-to-the-wordpress-category-posts-plugin-v20/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scrum-style Burn Down Chart in iWork &#8217;08 Numbers.app</title>
		<link>http://maymay.net/blog/2008/09/06/scrum-style-burn-down-chart-in-iwork-08-numbersapp/</link>
		<comments>http://maymay.net/blog/2008/09/06/scrum-style-burn-down-chart-in-iwork-08-numbersapp/#comments</comments>
		<pubDate>Sat, 06 Sep 2008 11:46:26 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Apple/Macintosh]]></category>
		<category><![CDATA[Crosspost]]></category>
		<category><![CDATA[Information & Communication]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tech/Computing]]></category>
		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=617</guid>
		<description><![CDATA[Ever since I was introduced to the Scrum methodology of software development, I&#8217;ve enjoyed my work so much more than before. Most of that enjoyment is due to a sense of visibility, of knowing what&#8217;s going on. I find working without an accurate awareness of the situation at large very disorienting, and software and web [...]]]></description>
			<content:encoded><![CDATA[<p>Ever since I was introduced to the <a href="http://en.wikipedia.org/wiki/Scrum_(development)">Scrum methodology of software development</a>, I&#8217;ve enjoyed my work so much more than before. Most of that enjoyment is due to a sense of visibility, of knowing what&#8217;s going on.</p>
<p>I find working without an accurate awareness of the situation at large very disorienting, and software and web development are notorious for being circumstances that change rapidly. That&#8217;s why one of my favorite things about Scrum is the <a href="http://en.wikipedia.org/wiki/Burn_down_chart">burn down chart</a>. This is nothing more complex than a simple graph that depicts how much work you bit off and how far along trying to chew it you actually are. The benefit, of course, is that it&#8217;s pretty obvious pretty quickly if you&#8217;ve bit off more than you can chew. ;)</p>
<p>So up &#8217;til now, my team and I have been doing this all on paper. There&#8217;s a certain tactile appreciation I have for doing this sort of thing on paper, but of course there are disadvantages, too. For instance, you can&#8217;t easily archive the information. You can&#8217;t easily share it with remote contractors. You can&#8217;t automatically mine this valuable data with software tools. You get the picture.</p>
<p>There are a few <a href="http://trac-hacks.org/wiki/ScrumBurndownPlugin">cool plugins to some tools like Trac</a> that do all this, but at first blush most of these tools seem to require that you move <em>all</em> of your Scrum&#8217;s planning into the digital world. That is, you can&#8217;t just do the burn down chart, you have to do all your estimation (MoSCoW desirability, sizing, estimating ideal hours) through some tool. That&#8217;s a big step, and I wanted something simpler.</p>
<p>So naturally, I came up with a spreadsheet in <a href="http://www.apple.com/iwork/numbers/">Numbers.app</a> as my solution. I mean, how much simpler can you get? Sure, it&#8217;s not exactly &#8220;well integrated&#8221; with other tools, but your non-tech-savvy boss will probably love it, and <a href="/blog/category/programming/applescript/">AppleScript</a> can be used to automate data extraction. Here&#8217;s what it looks like:</p>
<div id="attachment_618" class="wp-caption aligncenter" style="width: 310px"><a href="http://maymay.net/blog/wp-content/uploads/2008/09/example-burn-down-chart-in-numbers.png"><img src="http://maymay.net/blog/wp-content/uploads/2008/09/example-burn-down-chart-in-numbers-300x203.png" alt="An example Scrum-style burn down chart in Apple&#039;s iWork &#039;08 Numbers spreadsheeting application, complete with an actual chart." title="example-burn-down-chart-in-numbers" width="300" height="203" class="size-medium wp-image-618" /></a><p class="wp-caption-text">An example Scrum-style burn down chart in Apple's iWork '08 Numbers spreadsheeting application, complete with an actual chart.</p></div>
<p><small>(Click the screenshot to get a full-size view.)</small></p>
<p>As you can see, the Numbers sheet is a simple table and a line chart. I&#8217;ve embedded instructions for how to use the chart into the example itself, which I&#8217;ll quote here:</p>
<blockquote><p>
This is a sample Scrum-style iteration burn down chart for software development created by <a href="http://MeitarMoscovitz.com/">Meitar Moscovitz</a>. It can be used to plot a team’s progress throughout a development cycle (<acronym title="Also Known As">aka</acronym>. “iteration” or “sprint”). This sample chart depicts a 3-week iteration (15 working days) with a 150-point target goal.</p>
<p>The <em>X-axis</em> represents time, and is thus labelled <strong>Time in Days</strong>, while the <em>Y-axis</em> represents the work to be completed, and is labelled <strong>Points</strong>.</p>
<p>The <strong style="color: green;">green line</strong> shows the team’s <strong>ideal velocity</strong> based upon the total number of points—termed the <strong>Remaining Initial Value</strong>—scheduled for completion in the graphed iteration.</p>
<p>The <strong style="color: blue;">blue line</strong> shows the team’s <strong>actual velocity</strong> (or “completed work”), which is entered by the team leader (<acronym title="Also Known As">aka</acronym>. Scrum Master) after each day in the <strong>Done</strong> column.</p>
<p><strong>To use this chart:</strong> duplicate this sheet, enter your iteration’s total points in the <strong>Initial Value</strong> row of the <strong>Remaining</strong> column, and delete the values in the Done column except its initial value of 0. To add more days, copy and paste more rows into the table. Optionally, give the sheet and its contents new titles. ;)
</p></blockquote>
<p>Feel free to <a href='http://maymay.net/blog/wp-content/uploads/2008/09/example-burn-down-chartnumbers.zip'>download the <cite>Example Burn Down Chart.numbers</cite> file</a> and use it yourself. If you do use it, please leave a comment and let me know how you&#8217;re going. Thanks, and enjoy!</p>
<p><ins datetime="2008-09-08T08:25:58+00:00">(<a href="http://www.mountaingoatsoftware.com/alt_releaseburndown">Mike Cohn of Mountain Goat Software has got a similar spreadsheet for Excel</a> you can download.)</ins></p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2008/09/06/scrum-style-burn-down-chart-in-iwork-08-numbersapp/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How to use mod_rewrite rules to easily enable web site &#8220;maintenance&#8221; modes</title>
		<link>http://maymay.net/blog/2008/08/10/how-to-use-mod_rewrite-rules-to-easily-enable-web-site-maintenance-modes/</link>
		<comments>http://maymay.net/blog/2008/08/10/how-to-use-mod_rewrite-rules-to-easily-enable-web-site-maintenance-modes/#comments</comments>
		<pubDate>Sun, 10 Aug 2008 09:24:07 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Crosspost]]></category>
		<category><![CDATA[HOWTO]]></category>
		<category><![CDATA[Tech/Computing]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=574</guid>
		<description><![CDATA[When you&#8217;re administering a web site, sometimes you need to make changes that for whatever reasons require that the web site be temporarily unavailable for normal visitors. One obvious example is database maintenance. Unless you have the resources to do full-blown load balancing across a server cluster, you probably have to accept that your site [...]]]></description>
			<content:encoded><![CDATA[<p>When you&#8217;re administering a web site, sometimes you need to make changes that for whatever reasons require that the web site be temporarily unavailable for normal visitors. One obvious example is database maintenance. Unless you have the resources to do full-blown load balancing across a server cluster, you probably have to accept that your site is going to be down for a short period of time.</p>
<p>When this happens, it&#8217;s generally a good idea to show your visitors a web page that briefly explains the situation. This is typically a page that politely explains that the &#8220;site is temporarily down for maintenance&#8221; and so on. I&#8217;ve taken to calling such a page a &#8220;curtain&#8221; because it&#8217;s a little like putting a curtain up in front of construction work.</p>
<p>You put the curtain up, do whatever you need to do to fix or upgrade or maintain your web site in the background, then take the curtain down. For delicate servers, this has the added benefit of dramatically reducing server load while you do your maintenance tasks. You can even allow access to specific visitors, such as QA testers or remote admins while this curtain is up, while still redirecting normal users to the &#8220;down for maintenance&#8221; page.</p>
<p>Obviously, the first thing you need is the page that explains your site is down for maintenance reasons. This can be anything you like, but it&#8217;s simplest to make it a static <acronym title="HyperText Markup Language">HTML</acronym> page and place any and all resources you need for this page (like images) into the same folder. I often use a directory named <code>down-for-maintenance</code> and I place an <code>index.html</code> file in that folder to use as my &#8220;curtain&#8221; page. Images go straight into the <code>down-for-maintenance</code> directory, too.</p>
<p>Once you have that, you can then use the following Apache configurations to create an &#8220;on/off switch&#8221; for putting your curtain up and taking it down.</p>
<pre class="apache-config">
# To take the web site into a maintenance mode, create a file named
# maintenance-mode-on at the document (website) root, such as this:
#
#     touch maintenance-mode-on
#
# To bring the web site back, remove or rename the file, such as this:
#
#    mv maintenance-mode-on maintenance-mode-off
#
# To enable the site for your <acronym title="Internet Protocol">IP</acronym> address only but nobody else's
# uncomment the second RewriteCond directive.
&lt;IfModule mod_rewrite.c&gt;
    RewriteEngine On
    RewriteCond %{DOCUMENT_ROOT}/maintenance-mode-on -f
    #RewriteCond %{REMOTE_ADDR} !^<var>your.IP.address.here</var>$
    RewriteRule !^down-for-maintenance/.*$ /down-for-maintenance/ [R,L]
&lt;/IfModule&gt;
</pre>
<p>What this does, step by step, is:</p>
<ol>
<li>Determines whether or not you have <code>mod_rewrite</code> enabled. If you don&#8217;t, then nothing happens.</li>
<li>Enables the <code>mod_rewrite</code> rewriting engine.</li>
<li>Checks for the existence of a file called <code>maintenance-mode-on</code> at your site&#8217;s root. If such a file does not exist, nothing happens.</li>
<li>With the second <code>RewriteCond</code> directive uncommented, it also checks the visitor&#8217;s <acronym title="Internet Protocol">IP</acronym> address and if it does match the one listed nothing special happens. If it does <em>not</em> match the one listed, the next line, which is the redirect, is executed.</li>
<li>Checks the requested <acronym title="Uniform Resource Identifier">URI</acronym> and if it does not begin with <code>down-for-maintenance</code>, a temporary redirect (<acronym title="HyperText Transfer Protocol">HTTP</acronym> status code 302) is issued that points browsers to the <code>down-for-maintenance</code> directory you created earlier. Obviously, if you named this directory something else, you should change this <code>RewriteRule</code>.</li>
</ol>
<p>This isn&#8217;t perfect. For example, if a visitor is filling out a multi-page form then they might get interrupted half way through when you enable the curtain since the curtain takes effect starting at the next <acronym title="HyperText Transfer Protocol">HTTP</acronym> request after you enable it. That said, the only way to do truly graceful maintenance with zero downtime is load balancing, and that is beyond the capability of most simple sites, but this curtain is extremely simple and extremely effective.</p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2008/08/10/how-to-use-mod_rewrite-rules-to-easily-enable-web-site-maintenance-modes/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>How web designers can do their own HTML/CSS: Read Foundation Website Creation</title>
		<link>http://maymay.net/blog/2008/07/21/how-web-designers-can-do-their-own-htmlcss/</link>
		<comments>http://maymay.net/blog/2008/07/21/how-web-designers-can-do-their-own-htmlcss/#comments</comments>
		<pubDate>Mon, 21 Jul 2008 14:22:19 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Crosspost]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Hypertext Copywriting]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Maymay Media]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tech/Computing]]></category>
		<category><![CDATA[Usability]]></category>
		<category><![CDATA[Web Accessibility]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Standards]]></category>
		<category><![CDATA[Writing and blogging]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=476</guid>
		<description><![CDATA[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&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p>Last month, 37signals published a short but sweet post about why <a href="//www.37signals.com/svn/posts/1066-web-designers-should-do-their-own-htmlcss">web designers should do the <acronym title="HyperText Markup Language">HTML</acronym>/CSS implementations for their own designs</a>. The bottom line is, as we&#8217;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&#8217;re not going to do great work.</p>
<blockquote cite="//www.37signals.com/svn/posts/1066-web-designers-should-do-their-own-htmlcss"><p>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.</p>
<p>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 “<acronym title="HyperText Markup Language">HTML</acronym> 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 <em>around</em> stuff, never the <em>it</em> stuff.</p></blockquote>
<p>In other words, to do great web design you have to design <em>in</em> the Web, not in some other medium <em>for</em> the Web. I mean, serious magazine firm employs designers who don&#8217;t understand how to work with page layout programs like InDesign. Why, then, do so many web design agencies employ designers who don&#8217;t know how to work with web technologies, or even how to use programs like Dreamweaver? It doesn&#8217;t really make any sense, and it&#8217;s no wonder that the resulting implementation is rarely top-notch work.</p>
<p>But if you&#8217;re a graphic designer who doesn&#8217;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, <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&#038;location=http%3A%2F%2Fwww.amazon.com%2FFoundation-Website-Creation-XHTML-JavaScript%2Fdp%2F1430209917%2F&#038;tag=maymaydotnet-20&#038;linkCode=ur2&#038;camp=1789&#038;creative=9325">Foundation Website Creation</a><img src="http://www.assoc-amazon.com/e/ir?t=maymaydotnet-20&amp;l=ur2&amp;o=1" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />. It&#8217;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.</p>
<p>If I do say so myself, the chapters on <acronym title="eXtensible HyperText Markup Language; HTML reformulated as XML">XHTML</acronym> and <acronym title="Cascading Style Sheets">CSS</acronym> are exceptionally thorough. The book <em>doesn&#8217;t</em> try to turn you into an exceptional programmer. Instead, it will explain the foundational concepts you need to know to <em>understand how <acronym title="eXtensible HyperText Markup Language; HTML reformulated as XML">XHTML</acronym> and <acronym title="Cascading Style Sheets">CSS</acronym> actually work</em>, and in so doing will enable you to use the tools you already know to solve problems and get things done.</p>
<p>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&#8217;s why I recommend that, after you read <cite>Foundation Website Creation</cite> 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:</p>
<ul>
<li><a href="http://domscripting.com/book/"><acronym title="Document Object Model">DOM</acronym> Scripting by Jeremy Keith</a> — if you&#8217;re a designer that needs to add a behavioral layer with JavaScript and Ajax to your pages, you need to read this book next.</li>
<li><a href="http://www.amazon.com/Mastering-Dreamweaver-Voices-That-Matter/dp/0321508971">Mastering <acronym title="Cascading Style Sheets">CSS</acronym> with Dreamweaver CS3</a> &#8211; if you&#8217;re familiar with Dreamweaver and want to keep using it to create standards-based web sites, then I recommend you follow <cite>Foundation Website Creation</cite> with this book by <a href="//w3conversions.com/">Stephanie Sullivan</a> and Greg Rewis to take your Dreamweaver skills to the next level.</li>
</ul>
<p>As always, most of all, have fun. Because if you&#8217;re not having fun, you&#8217;re not going to make good web sites no matter what you know.</p>
<p><strong>Note:</strong> 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&#8217;s front cover lists the correct authors.</p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2008/07/21/how-web-designers-can-do-their-own-htmlcss/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Arbitrarily exclude posts from displaying in WordPress</title>
		<link>http://maymay.net/blog/2008/06/06/arbitrarily-exclude-posts-from-displaying-in-wordpress/</link>
		<comments>http://maymay.net/blog/2008/06/06/arbitrarily-exclude-posts-from-displaying-in-wordpress/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 18:11:08 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[HOWTO]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Writing and blogging]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=437</guid>
		<description><![CDATA[When hacking away at WordPress sites, often times you&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p>When hacking away at WordPress sites, often times you&#8217;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.</p>
<p>I came across <a href="//blog.gadodia.net/excluding-certain-categories-from-your-blog-main-page/">Vaibhav&#8217;s post on the topic</a> and noted that his solution uses the <a href="//codex.wordpress.org/Template_Tags/query_posts" title="WordPress documentation for the query_posts() function.">query_posts()</a> function to alter WordPress&#8217;s query object before <a href="//codex.wordpress.org/The_Loop">The Loop</a> 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&#8217;t provide you with the hook you need.</p>
<p>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 <em>that</em> 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.</p>
<p>Another advantage of this technique over simpler ones is that this method maintains the same behavior you&#8217;d expect to see in every other way. Most notably, this means that if you&#8217;ve told WordPress to display the 10 most recent posts on the home page (in the WordPress settings), you&#8217;ll still see ten posts on that page even after you exclude some of them.</p>
<p>To do something like excluding posts if they are in the &#8220;Uncategorized&#8221; category (traditionally the category with an ID of 1 in WordPress) and their title begins with &#8220;Some title&#8221;, you can do this:</p>
<pre class="php">
// original query runs in The (real) Loop first
while ( have_posts() ) : the_post();
    // detect pots matching our exclusion criteria
    if (in_category(1) &#038;&#038; (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.'&#038;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) &#038;&#038; (0 === strpos(the_title('', '', false), 'Some title')) ) { continue; }

// ...the rest of the WordPress template goes here...
</pre>
<p>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&#8217;ll probably want to extract the filtering code into a function. Using the above example, your new code might look like this:</p>
<pre class="php">
<strong>// define criteria for filtering
function matches_filtering_criteria () {
    if (in_category(1) &#038;&#038; (0 === strpos(the_title('', '', false), 'Some title')) ) {
        return true;
    } else {
        return false;
    }
}</strong>
// original query runs in The (real) Loop first
while ( have_posts() ) : the_post();
    // detect pots matching our exclusion criteria
    if (<strong>matches_filtering_criteria()</strong>) {
        $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.'&#038;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 (<strong>matches_filtering_criteria()</strong>) { continue; }

// ...the rest of the WordPress template goes here...
</pre>
<p>For more information on these functions, see:</p>
<ul>
<li><a href="//codex.wordpress.org/The_Loop">The Loop</a></li>
<li><a href="//codex.wordpress.org/Template_Tags/in_category">in_category()</a></li>
<li><a href="//codex.wordpress.org/Template_Tags/the_title">the_title()</a></li>
<li><a href="//codex.wordpress.org/Function_Reference/WP_Query">WP_Query()</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2008/06/06/arbitrarily-exclude-posts-from-displaying-in-wordpress/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>I&#8217;m getting a book published and it&#8217;s called Foundation Website Creation</title>
		<link>http://maymay.net/blog/2008/05/19/im-getting-a-book-published-and-its-called-foundation-web-standards/</link>
		<comments>http://maymay.net/blog/2008/05/19/im-getting-a-book-published-and-its-called-foundation-web-standards/#comments</comments>
		<pubDate>Mon, 19 May 2008 13:50:36 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Crosspost]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Maybe Maimed]]></category>
		<category><![CDATA[Maymay Media]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tech/Computing]]></category>
		<category><![CDATA[Usability]]></category>
		<category><![CDATA[Web Accessibility]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Standards]]></category>
		<category><![CDATA[Writing and blogging]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=436</guid>
		<description><![CDATA[For those who have been wondering what is keeping me so busy these days, the answer is that I&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p>For those who have been wondering what is keeping me so busy these days, the answer is that I&#8217;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)<acronym title="HyperText Markup Language">HTML</acronym> and <acronym title="Cascading Style Sheets">CSS</acronym>, specifically), but I am also technically reviewing the entire book.</p>
<p>My co-authors on the book, called <a href="//www.friendsofed.com/book.html?isbn=9781430209911"><cite><del datetime="2008-06-15T10:43:08+00:00">Foundation Web Standards</del> <ins datetime="2008-06-15T10:43:08+00:00">Foundation Website Creation</ins></cite></a> (you can <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&#038;location=http%3A%2F%2Fwww.amazon.com%2FFoundation-Website-Creation-XHTML-JavaScript%2Fdp%2F1430209917%2F&#038;tag=maymaydotnet-20&#038;linkCode=ur2&#038;camp=1789&#038;creative=9325" title="Buy on Amazon.com.">pre-order now</a>) and published by <a href="//friendsofed.com/">Friends of ED</a>, an <a href="//apress.com/">Apress</a> company, are <a href="//industryinteractive.net/">Jonathan Lane of Industry Interactive, Inc.</a> and <a href="//www.sanbeiji.com/">Joe Lewis, who blogs at Sanbeiji.com</a>. I&#8217;m not going to say much more until after the book is released in late July.</p>
<p>For the eager, here&#8217;s the description of the book posted on the Friends of ED website:</p>
<blockquote cite="//www.friendsofed.com/book.html?isbn=9781430209911"><p>Foundation Website Creation explores the process of constructing a web site from start to finish. There is more to the process than just knowing <acronym title="HyperText Markup Language">HTML</acronym>! Designers and developers must follow a proper process to flush out goals and objectives and determine requirements both prior to, and during project development.</p>
<p>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&#8217;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.</p></blockquote>
<p>It&#8217;s quite exciting getting a book out, and it&#8217;s quite a bit more work than I&#8217;d have ever originally thought. That being said, it&#8217;s extremely rewarding. There&#8217;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.</p>
<p>Now you all know where I&#8217;ve been spending my time writing.</p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2008/05/19/im-getting-a-book-published-and-its-called-foundation-web-standards/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>A web developer’s introduction to the Apple WikiServer (part 2)</title>
		<link>http://maymay.net/blog/2008/04/08/a-web-developer%e2%80%99s-introduction-to-the-apple-wikiserver-part-2/</link>
		<comments>http://maymay.net/blog/2008/04/08/a-web-developer%e2%80%99s-introduction-to-the-apple-wikiserver-part-2/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 09:12:18 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Apple/Macintosh]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=423</guid>
		<description><![CDATA[Last time, we checked out the Apple WikiServer from the user&#8217;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&#8217;s delve a little deeper into the WikiServer&#8217;s internals by (safely) messing around with [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://maymay.net/blog/2008/04/07/a-web-developers-introduction-to-the-apple-wikiserver-part-1/">Last time</a>, we checked out the Apple WikiServer from the user&#8217;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&#8217;s delve a little deeper into the WikiServer&#8217;s internals by (safely) messing around with a running instance and seeing how we can effect changes that aren&#8217;t available in the <acronym title="Graphical User Interface">GUI</acronym>.</p>
<h2>I’m going in!</h2>
<p>Apple&#8217;s WikiServer keeps each group&#8217;s data segregated. There&#8217;s currently no way in the <acronym title="Graphical User Interface">GUI</acronym> 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&#8217;s not that hard to move things around. Doing so doesn&#8217;t seem to cause any problems with the application, either—a testament to its apparent simplicity.</p>
<p>Most simply, say you have created a number of different wikis for different groups, and in so doing you&#8217;ve created segregated spaces for different parts of your organization. Now say you&#8217;ve got a wiki page in one wiki that you&#8217;d rather place in a different one, or that you&#8217;d like to copy. Sure, you can edit the first wiki&#8217;s page, copy the <acronym title="what you see is what you get">WYSIWYG</acronym> editor&#8217;s text, and paste it into a new page on the second wiki. But where&#8217;s the fun in that?</p>
<p>Instead, let&#8217;s move some files around to get a sense for how the Apple WikiServer stores its data.</p>
<p>First, recall that the Apple WikiServer stores its content inside the <code>/Library/Collaboration</code> directory on the computer hosting the wiki web site. Inside of this directory you&#8217;ll find four items:</p>
<pre>$ <kbd>cd /Library/Collaboration/</kbd>
$ <kbd>ls -la</kbd>
<samp>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</samp></pre>
<p>First, note that all of these files are owned solely by the <code>_teamserver</code> 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&#8217;re going to tamper anyway. To do so, you&#8217;ll need root permissions, which comes with a big caveat: <strong>be careful whenever you are root—one typo could erase your hard drive (and there is no undo)!</strong></p>
<p>Become root by saying:</p>
<pre>sudo su -</pre>
<p>and supplying your password. Once you are root, you can explore further into the depths of the Apple WikiServer.</p>
<h2>Inside the Apple WikiServer data store for wiki pages</h2>
<p>The Apple WikiServer, which runs under the username <code>_teamserver</code>, 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 <a href="http://python.org/">Python</a> scripts running under the <a href="http://twistedmatrix.com/trac/">Twisted networking framework</a>. We&#8217;re not going to cover Python or Twisted in this post, so for further information check out their respective homepages. There&#8217;s also <a href="http://www.onlamp.com/pub/a/python/2004/01/15/twisted_intro.html">a great introduction to Twisted at ONLAMP.com</a>.</p>
<p>To make the wiki go, the WikiServer runs these scripts to read and write data to these flat files. Let&#8217;s dig into this data store. Since the wikis are each associated with an existing group, all of the wiki files are inside the <code>Groups</code> subdirectory. In this directory, you&#8217;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:</p>
<pre># <kbd>pwd</kbd>
<samp>/Library/Collaboration/Groups/chiefs</samp>
# <kbd>ls -p</kbd>
<samp>discussion/	index.db	metadata.plist	resources/	wiki/
extrainfo	mailinglist/	public/		weblog/</samp></pre>
<p>The two regular files are <code>metadata.plist</code> and <code>extrainfo</code>. The <code>metadata.plist</code> file maintains the preferences of the individual wiki web site that you set from the &#8220;Group Settings&#8221; page on the wiki web site itself. That is, these settings are all editable via the web directly at <code>http://<var>your-server.local</var>/groups/<var>your-group-name</var>/settings/</code>. That page is also accessible to an admin user from the wiki home page under the &#8220;Admin functions&#8221; header in the sidebar of the web page (the key names in the plist file are pretty self-explanatory and map easily to the <acronym title="Graphical User Interface">GUI</acronym> options).</p>
<p>At the moment, the <code>extrainfo</code> file is a bit of mystery. It stores single lines of plain ASCII text in the form:</p>
<pre>groups/<var>your-group-name</var>/<var>web-service</var>/<var>page-id</var></pre>
<p>where <var>your-group-name</var> is the name of the associated group for the file, <var>web-service</var> is one of <code>wiki</code>, <code>weblog</code>, and I assume can also be <code>mailinglist</code> or <code>discussion</code>, although I&#8217;ve only seen the first two on my server in practice.</p>
<p>What we&#8217;re most interested in for the purposes of wiki pages is, unsurprisingly, the <code>wiki</code> 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 <em>not</em> deleted outright.</p>
<p>Each directory is named with the unique page identifier that the Apple WikiServer automatically generates followed by a <code>.page</code> extension. The exception is the <code>welcome.page</code> directory, special in that it contains the content of the wiki&#8217;s main (front) page. The <a href="http://images.apple.com/server/macosx/docs/Web_Technologies_Admin_v10.5.pdf">Mac <acronym title="Operating System">OS</acronym> X Server Web Technologies Administration for Version 10.5 Leopard manual</a> explains the contents of this directory as follows:</p>
<blockquote>
<ul>
<li>/Library/Collaboration/Groups/groupname/wiki/pagename.page/ contains the component files of a wiki page.</li>
<li>/Library/Collaboration/Groups/groupname/wiki/pagename.page/page.html contains the main text of the wiki (html content).</li>
<li>/Library/Collaboration/Groups/groupname/wiki/pagename.page/page.plist contains the metadata for the wiki page.</li>
<li>/Library/Collaboration/Groups/groupname/wiki/pagename.page/revisions.db contains the version history database for that wiki page.</li>
<li>/Library/Collaboration/Groups/groupname/pagename.page/images/ contains the images for that wiki page.</li>
<li>/Library/Collaboration/Groups/groupname/pagename.page/attachments/ contains all attachments for that wiki page.</li>
</ul>
</blockquote>
<p>Here are some additional details:</p>
<ul>
<li>The &#8220;page.html&#8221; file contains all of the (X)<acronym title="HyperText Markup Language">HTML</acronym> that appears inside the <acronym title="what you see is what you get">WYSIWYG</acronym> editor field when you click the &#8220;Switch to <acronym title="HyperText Markup Language">HTML</acronym> View&#8221; button (the arrow brackets). Nothing more, and nothing less.</li>
<li>The &#8220;page.plist&#8221; 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&#8217;ll find property list keys such as <code>commentUID</code> and <code>uid</code> 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 <code>author</code>, <code>createdDate</code>, page <code>kind</code>, a last <code>modifiedDate</code> and <code>lastModifiedAuthor</code> and, of course, the page <code>title</code>. The most interesting key in this file is the <code>versioned</code> 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&#8217;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&#8217;s associated plist file.</li>
<li>The <code>revisions.db</code> is the SQLite database in which all revisions are stored. The database contains a single table, <code>revisions</code>, that looks like this:
<pre>CREATE TABLE revisions(revision INTEGER PRIMARY KEY AUTOINCREMENT, editType, comment, lastModifiedBy, content, time DEFAULT CURRENT_TIMESTAMP);</pre>
<p>The interesting bit is the <code>content</code> field, which itself is just a string—but a string <em>stored as an Apple property list, in full</em>. Some keys in the property list inside the SQLite database are the same as those inside the <code>page.plist</code> file for the page, but with some differences. For instance, there is no <code>versioned</code> key in the plist in the database (for obvious reasons), and there is a <code>tags</code> key (which is missing from the filesystem equivalent). Most importantly, there is a <code>content</code> key, which stores the content of the <code>page.html</code> file.</li>
<li>The <code>revisions.db</code> file is created automatically only if the <code>versioned</code> key in the page&#8217;s <code>page.plist</code> file is set to true.</li>
</ul>
<h3>Finally: move a wiki page from one wiki to another</h3>
<p>Now that we understand some of the internals of the Apple WikiServer data store, let&#8217;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&#8217;s remarkably easy to do:</p>
<pre># <kbd>mv /Library/Collaboration/Groups/<var>your-group-name</var>/wiki/<var>page-id</var>.page /Library/Collaboration/Groups/<var>new-group-name</var>/</kbd></pre>
<p><strong>Be certain that there isn&#8217;t already an existing page in the <var>new-group-name</var> wiki with the same <var>page-id</var> as the one you&#8217;re moving. So far, Apple WikiServer <em>appears</em> to generate unique page IDs across the entire system (as opposed to just per-group), but I haven&#8217;t verified this yet.</strong></p>
<p>With the wiki page files physically moved into the new wiki, you can now access the page at the new wiki <acronym title="Uniform Resource Locator">URL</acronym>. Trying to access it in the old <acronym title="Uniform Resource Locator">URL</acronym> will result in an <acronym title="HyperText Transfer Protocol">HTTP</acronym> 404 &#8220;Not Found&#8221; error. However, the page at the new wiki <acronym title="Uniform Resource Locator">URL</acronym> has the same theme as the other, old wiki. To correct this, you need to edit the <code>page.plist</code> file in two places: the <code>uid</code> string value and the <code>commentUID</code> string value relative URLs need their <var>your-group-name</var> changed to the <var>new-group-name</var>, whatever it is.</p>
<p>After you save this this change, simply reload the wiki page in your browser. Voila. Page moved.</p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2008/04/08/a-web-developer%e2%80%99s-introduction-to-the-apple-wikiserver-part-2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A web developer&#8217;s introduction to the Apple WikiServer (part 1)</title>
		<link>http://maymay.net/blog/2008/04/05/a-web-developers-introduction-to-the-apple-wikiserver-part-1/</link>
		<comments>http://maymay.net/blog/2008/04/05/a-web-developers-introduction-to-the-apple-wikiserver-part-1/#comments</comments>
		<pubDate>Sat, 05 Apr 2008 10:10:29 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Apple/Macintosh]]></category>
		<category><![CDATA[Business & E-Commerce]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/?p=422</guid>
		<description><![CDATA[I absolutely love wikis, so when Apple introduced Mac OS X Server 10.5 &#8220;Leopard,&#8221; one of the new features I was really excited about was &#8220;WikiServer&#8221; (what the Apple marketing department calls &#8220;Teams&#8221;). I&#8217;m calling this specifically the Apple WikiServer in order to avoid confusion with the pre-existing wiki plus web server package called WikiServer. Apple [...]]]></description>
			<content:encoded><![CDATA[<p>I absolutely love wikis, so when Apple introduced Mac <acronym title="Operating System">OS</acronym> X Server 10.5 &#8220;Leopard,&#8221; one of the new features I was really excited about was &#8220;WikiServer&#8221; (what the Apple marketing department calls &#8220;Teams&#8221;). I&#8217;m calling this specifically the <em>Apple</em> WikiServer in order to avoid confusion with the <a href="http://wikiserver.org/">pre-existing wiki plus web server package called WikiServer</a>.</p>
<h2>Apple WikiServer: Mac <acronym title="Operating System">OS</acronym> X Server&#8217;s built-in Intranet builder</h2>
<p>At work, I&#8217;m finally getting the opportunity to try the Apple WikiServer out. Its strongest asset, by far, is the integration it has with Apple&#8217;s Mac <acronym title="Operating System">OS</acronym> X permission scheme. Apple WikiServer makes heavy use of the <acronym title="Operating System">OS</acronym>&#8216;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.</p>
<p>This is very important because many large (and small) organizations have sensitive material that they&#8217;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.</p>
<p>With Apple&#8217;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 <acronym title="Operating System">OS</acronym> 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&#8217;s Web Service will likely need to be stopped and started again for any changes you make to a wiki&#8217;s permissions take effect.</p>
<p>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 &#8220;Developers&#8221; and assigned individual developers, as well as the company executives (by way of the &#8220;Executives&#8221; 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&#8217;s publications, Apple refers to the wikis hosted by WikiServer as an &#8220;intranet website.&#8221;</p>
<p>It&#8217;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&#8217;ve compiled about how the Apple WikiServer works.</p>
<h2>Front-end Code Generation from the Apple WikiServer <acronym title="what you see is what you get">WYSIWYG</acronym> Editor</h2>
<p>The Apple wikis are very nice to use. Their functionality is relatively straightforward to find and activate. However, the <acronym title="HyperText Markup Language">HTML</acronym> code that the Apple wikis generate can be a little confusing.  By default, new page text is entered into a semantically meaningless &lt;div&gt; element. This can be changed by highlighting text and then selecting &#8220;Paragraph&#8221; from the formatting toolbar. Subsequent paragraphs that are typed seem to then use &lt;p&gt; elements. However, some paragraphs revert back to &lt;div&gt;s when I used it, and I&#8217;m still not sure why or when this occurred.</p>
<p>On the plus side, so far, all the browsers I&#8217;ve used with the Apple WikiServer function the same way. This include Firefox 2, Safari 3.1, and Internet Explorer 6 and 7.</p>
<p>Typing actual code and having it marked up as such can&#8217;t be done in the <acronym title="Graphical User Interface">GUI</acronym> formatting toolbar to select a &lt;code&gt; element. The &#8220;Monospace&#8221; item in the text formatting toolbar creates &lt;pre&gt; elements and &lt;pre&gt; elements only. However, Apple does provide a &#8220;Switch to <acronym title="HyperText Markup Language">HTML</acronym> view&#8221; button (the arrow brackets button) and one can enter standard <acronym title="HyperText Markup Language">HTML</acronym>, including &lt;code&gt;…&lt;/code&gt; 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.</p>
<p>Apple&#8217;s <acronym title="what you see is what you get">WYSIWYG</acronym> editor handles escaping special characters when those special characters have <acronym title="HyperText Markup Language">HTML</acronym> entity reference equivalents, such as double quotes (&#8220;), arrow brackets (&lt; and &gt;), and ampersands (&amp;). 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&#8217;s character set is UTF-8 (or UTF-16), which the Apple WikiServer specifies and supports out of the box.</p>
<p>Pressing the <em>Return</em> key twice causes the Apple wiki to generate an empty &lt;div&gt; or &lt;p&gt; element with an explicit break (&lt;br /&gt;) inside of it. One can deduce that this is a design choice in order to help transition users who are used to plain &lt;textarea /&gt; inputs to Apple&#8217;s <acronym title="what you see is what you get">WYSIWYG</acronym> editor. It&#8217;s also the only way to space paragraphs properly if the user hasn&#8217;t selected the &#8220;Paragraph&#8221; option in the text formatting toolbar. Otherwise, simply hitting the <em>Return</em> 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).</p>
<p>Interestingly, the &#8220;Enter <acronym title="Uniform Resource Locator">URL</acronym>…&#8221; 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 &#8220;mailto:&#8221; portion as part of the <acronym title="Uniform Resource Locator">URL</acronym>. In fact, you should omit this, else your final mailto link will actually read &#8220;mailto:mailto:your.email@address.com&#8221;.</p>
<p>This means linking to &#8220;mailto: links&#8221; is as simple as typing an email address. Similarly, the <acronym title="what you see is what you get">WYSIWYG</acronym> doesn&#8217;t complain if your fully-qualified <acronym title="Uniform Resource Locator">URL</acronym> doesn&#8217;t include a scheme, so you can enter <kbd>//apple.com/</kbd> and the subsequent link is generated as <code>&lt;a href="//apple.com/"&gt;Link text&lt;/a&gt;</code>. This is one step above and beyond even WordPress&#8217;s new <acronym title="what you see is what you get">WYSIWYG</acronym> editor, which forcefully prepends an http: scheme to URLs without one.</p>
<p>For the most part, copy-and-paste works as expected, except in cases where the <acronym title="what you see is what you get">WYSIWYG</acronym> 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 <em>appear</em> to show that the formatting (including links) is saved, but when you actually save the page, only the formatting that the <acronym title="what you see is what you get">WYSIWYG</acronym> 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 <acronym title="HyperText Markup Language">HTML</acronym> view of the page editor.</p>
<p>Inexplicably, the editor generates &lt;i&gt; and &lt;b&gt; tags for italics and bold, instead of the preferred &lt;em&gt; and &lt;strong&gt; elements. I&#8217;m not sure I understand why this is the case. There does exist a an &#8220;emphasis&#8221; option in the toolbar, as does an &#8220;important&#8221; option, but these generate strange spans instead. The &#8220;Important&#8221; item wraps the selected text inside a &lt;span class=&#8221;Apple-style-span custom_forecolor_important&#8221;&gt;…&lt;/span&gt; and the &#8220;Emphasis&#8221; item wraps the selected text inside a &lt;span class=&#8221;Apple-style-span custom_forecolor_emphasis&#8221;&gt;…&lt;/span&gt; element.</p>
<p>There&#8217;s also one other item, &#8220;Highlight,&#8221; which wraps the selected text inside of a &lt;span class=&#8221;Apple-style-span custom_backcolor_highlight&#8221;&gt;…&lt;/span&gt; element.</p>
<p>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 &lt;em&gt; and &lt;strong&gt; would imply from users who use a <acronym title="what you see is what you get">WYSIWYG</acronym> editor. This shows either a blatant distrust of users or incredible foresight. I&#8217;m not sure which.</p>
<h2>Page names and URLs</h2>
<p>Currently, the search functionality built into Apple&#8217;s WikiServer only searches on the text of a page&#8217;s title.</p>
<p>Apple&#8217;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 &#8220;Hello&#8221;, you might get an address in your web browser&#8217;s location bar that looks like this:</p>
<pre>http://your-server.local/groups/your-group-name/wiki/1d06a/Hello.html</pre>
<p>Most of this is standard <acronym title="Uniform Resource Locator">URL</acronym> 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 <acronym title="Uniform Resource Locator">URL</acronym> are the last two:</p>
<ul>
<li>1d06a</li>
<li>Hello.html</li>
</ul>
<p>Obviously, &#8220;Hello.html&#8221; came from the fact that you named your new page &#8220;Hello&#8221;. WikiServer appended &#8220;.html&#8221; on its own. The other bit, the short string of random characters, is a unique identifier used across all of this group&#8217;s web services (the wiki, blog, calendar, and mail list, if these other services are enabled) to uniquely identify this page.  What&#8217;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:</p>
<pre>http://your-server.local/groups/your-group-name/wiki/1d06a/Some-Random-Page.html</pre>
<p>you&#8217;ll still get the same &#8220;Hello.html&#8221; page from before, even though you&#8217;re seemingly asking for &#8220;Some-Random-Page.html&#8221;. In fact, it doesn&#8217;t seem to matter what you replace &#8220;Some-Random-Page&#8221; with. So long as there is some text in that part of the <acronym title="Uniform Resource Locator">URL</acronym>, that the <acronym title="Uniform Resource Locator">URL</acronym> ends with &#8220;.html&#8221; and that the unique identifier remains untouched, you&#8217;ll always end up retrieving the &#8220;Hello.html&#8221; page.</p>
<p>This means that if you change this page&#8217;s name later to, for instance, &#8220;Hello world&#8221;, old links that point to &#8220;…/1d06a/Hello.html&#8221; will continue to work, even while new links will start to point at &#8220;…/1d06a/Hello_world.html&#8221;.  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 <acronym title="Uniform Resource Locator">URL</acronym>. However, once page names change, it becomes a bit non-optimal, because the same page can be referred to by multiple names—a &#8220;no-no&#8221; in the <acronym title="Search Engine Optimization">SEO</acronym> world and a practice discouraged by most semantic-web types.</p>
<p>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&#8217;s WikiServer identifies the stored content on the filesystem. Read on for more details.</p>
<h2>Hacking the Apple WikiServer</h2>
<p>There isn&#8217;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:</p>
<ul>
<li><code>/usr/share/collaboration</code> - This has a few developer tool support files as well as the majority of the client-side code for the Wiki (javascripts, etc).</li>
<li><code>/usr/share/wikid</code> - This directory holds the Python sources and compiled bytecode for all the &#8220;Teams&#8221; components (including wiki, blog, calendar, etc.). It seems to run on Twisted and a number of other familiar-sounding components.</li>
<li><code>/Library/Application Support/Apple/WikiServer</code> - 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.</li>
<li><code>/Library/Collaboration</code> &#8211; This is the default data storage location for all the &#8220;Teams&#8221; components. The actual content of the wikis and blogs will be kept somewhere in this directory, which means that <strong>this is the directory you want to backup to backup the content of your wikis</strong>. This location is the only user-configurable one of the bunch. To change it, change the &#8220;Data Store&#8221; value in Server Admin. (A more detailed listing of this directory hierarchy is available on page 62 of the <a href="http://images.apple.com/server/macosx/docs/Web_Technologies_Admin_v10.5.pdf">Mac <acronym title="Operating System">OS</acronym> X Server Web Technologies Administration For Version 10.5 Leopard</a> manual.)</li>
</ul>
<p>If you take a peek at the /Library/Collaboration directory, and follow that into the Groups/your-group-name/wiki directory, you&#8217;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.</p>
<p>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&#8217;s templates or themes should be done by creating new files in the /Library/Application Support/Apple/WikiServer/Themes directory.</p>
<p>It&#8217;s interesting to note that the WikiServer seems to use <a href="http://python.org/">Python</a> for its back-end processing. This may open up some interesting integration possibilities for Python programmers in the future.</p>
<h2>More help eslewhere</h2>
<p>Even though Apple WikiServer is relatively new, there&#8217;s a load of helpful information about it on the web. Most of the good stuff is on Apple&#8217;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:</p>
<ul>
<li><a href="http://docs.info.apple.com/article.html?path=ServerAdmin/10.5/en/c4ws25.html">Server Admin 10.5 Help: Customizing Wiki Themes and Layouts</a></li>
<li><a href="http://discussions.apple.com/thread.jspa?messageID=6804477">Apple Discussions: How to customize Apple WikiServer templates and themes</a></li>
<li><a href="http://images.apple.com/server/macosx/docs/Web_Technologies_Admin_v10.5.pdf">Mac <acronym title="Operating System">OS</acronym> X Server Web Technologies Administration For Version 10.5 Leopard</a></li>
</ul>
<p>This was just a brief introduction to WikiServer from some notes I&#8217;ve been collecting in my experimentations, but I hope it&#8217;s helpful to someone somewhere. Cheers. Or, continue to <a href="http://maymay.net/blog/2008/04/08/a-web-developer’s-introduction-to-the-apple-wikiserver-part-2/">Part 2</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2008/04/05/a-web-developers-introduction-to-the-apple-wikiserver-part-1/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>No-Framework Ruby on the Web using eRuby on Mac OS X</title>
		<link>http://maymay.net/blog/2007/10/25/no-framework-ruby-on-the-web-using-eruby-on-mac-os-x/</link>
		<comments>http://maymay.net/blog/2007/10/25/no-framework-ruby-on-the-web-using-eruby-on-mac-os-x/#comments</comments>
		<pubDate>Thu, 25 Oct 2007 05:00:16 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[HOWTO]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tech/Computing]]></category>
		<category><![CDATA[Unix/Linux]]></category>
		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/archives/2007/10/25/no-framework-ruby-on-the-web-using-eruby-on-mac-os-x/</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>I have a suspicion that there are a lot of web developers out there who, like me, are eager to start learning more about <a href="//ruby-lang.org/">Ruby</a> but who are stunted by the incredible amount of unfamiliar conventions that are used in <a href="//rubyonrails.com/">Rails</a>. For many of us, our first introduction to Ruby was (or is) through Rails and the challenge of learning <em>both</em> Ruby and Rails at once should not be underestimated; frankly it&#8217;s damn hard.</p>
<p>Thankfully, there&#8217;s an easier way. Especially if you&#8217;re accustomed to &#8220;old-school&#8221; development workflows that you learned through, say, <acronym title="PHP Hypertext Preprocessor; an HTML-embedded scripting language">PHP</acronym> 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 &#8220;magic&#8221; of Rails will let you learn Ruby in a simple, yet fully-featured environment, much like the way you might have learned classic <acronym title="Common Gateway Interface">CGI</acronym> programming.</p>
<p>Specifically, by using <a href="//eruby.info/">eRuby</a>, the Embedded Ruby interpreter, you can make Ruby web development feel just like <acronym title="PHP Hypertext Preprocessor; an HTML-embedded scripting language">PHP</acronym> development. Install it, upload an <acronym title="HyperText Markup Language">HTML</acronym> file with some embedded Ruby code in it, and—voila—you have a single-page web application.</p>
<h3>Why this tutorial?</h3>
<p><a href="http://www.hiveminds.co.uk/node/3094">Hivemind&#8217;s Getting Started with Ruby on the Web</a> 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&#8217;t have to be governed by Rails and, being a web developer like the authors of <cite>Hiveminds</cite>, I wanted an easy way to use my Ruby knowledge on the Web.</p>
<p>However, I couldn&#8217;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 <acronym title="Operating System">OS</acronym> X 10.4 Tiger, I thought I&#8217;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 <acronym title="Operating System">OS</acronym> X instead of Windows (obviously). I imagine these instructions should be pretty similar if not identical for any other *nix-like platform.</p>
<h3>The Setup</h3>
<p>Getting eRuby installed and configured with your web server is actually pretty straightforward and won&#8217;t take an experienced web developer much time at all. All we&#8217;re going to need is the <a href="//httpd.apache.org/">Apache web server</a> and the <a href="//ruby-lang.org/">Ruby programming language</a> to start, both of which are already pre-installed on Mac <acronym title="Operating System">OS</acronym> X 10.4 Tiger. (And in Mac <acronym title="Operating System">OS</acronym> X 10.5 Leopard, Apple is even <a href="/blog/archives/2007/10/18/the-10-geekiest-leopard-features-i-will-probably-love/#li-1">shipping new Macs with Ruby On Rails preconfigured</a>, but that&#8217;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.</p>
<p>The easiest way to get a copy of eRuby (and an updated Ruby, if you want it) is with a package manager such as <a href="//macports.org/">MacPorts</a>. With MacPorts installed (which is a simple, standard package installation downloadable from the MacPorts home page), simply run</p>
<pre><kbd>sudo port install eruby</kbd></pre>
<p>from your terminal to download the latest stable Ruby and eRuby in one fell swoop. After this runs, you&#8217;ll have a new Ruby in <code>/opt/local/bin/ruby</code> and an eRuby in <code>/opt/local/bin/eruby</code>. Alternatively, of course, you could compile and install eRuby yourself. <a href="//eruby.info/" title="Scroll to the 'How do I get eRuby?' section.">Instructions for that</a> are on the eRuby homepage.</p>
<p>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:</p>
<pre><code class="ruby">Hello world! The time is now &lt;%= Time.now %&gt;.</code></pre>
<p>All this does is print out a &#8220;Hello world!&#8221; greeting and then announces the current time (as reported by your system clock, of course).</p>
<p>If you named the above file <var>helloworld.rhtml</var> then you can feed this file to the <code>eruby</code> interpreter as follows:</p>
<pre><kbd>eruby helloworld.rhtml</kbd></pre>
<p>Note that the file extension doesn&#8217;t actually matter. You could use <code>.erb</code>, if you like, or any other arbitrary file extension. The file extension is, as you&#8217;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 <code>.rhtml</code> or <code>.erb</code>, so I&#8217;d recommend using one of those. (I prefer <code>.erb</code>, myself, since I don&#8217;t necessarily only want to create <acronym title="HyperText Markup Language">HTML</acronym> pages. I might want to create <acronym title="eXtensible Markup Language">XML</acronym> documents like news feeds or even <acronym title="eXtensible Markup Language">XML</acronym> databases, so <code>.erb</code> seems a more reasonable file name extension, though most of the eRuby documentation uses <code>.rhtml</code>.)</p>
<p>If things worked properly, you should see output similar to the following:</p>
<pre><samp class="plaintext">Hello world! The time is now Wed Oct 24 21:58:54 -0400 2007.</samp></pre>
<h3>Serve it up!</h3>
<p>Now that eRuby is installed and working, the next step is to set it up as a <acronym title="Common Gateway Interface">CGI</acronym> 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 <acronym title="Common Gateway Interface">CGI</acronym> directory—that is, a directory whose contents are all treated as <acronym title="Common Gateway Interface">CGI</acronym> programs. You do this via Apache&#8217;s <a href="//httpd.apache.org/docs/1.3/mod/mod_alias.html#scriptalias" title="Documentation for Apache's ScriptAlias directive."><code>ScriptAlias</code></a> directive.</p>
<p>Conveniently, standard installations of Mac <acronym title="Operating System">OS</acronym> X already come with a <acronym title="Common Gateway Interface">CGI</acronym> directory. It&#8217;s located at <code>/Library/WebServer/CGI-Executables</code>. This directory is just like any other, except that Apache treats it specially. It treats it specially because Apache&#8217;s configuration file, <code>/etc/httpd/httpd.conf</code> contains a line of text that reads as follows. (On a standard installation of Mac <acronym title="Operating System">OS</acronym> X client, this is line 671 of the file.)</p>
<pre><code class="httpd-conf">ScriptAlias /cgi-bin/ "/Library/WebServer/CGI-Executables/"</code></pre>
<p>This line basically just tells apache, &#8220;Treat every file in the <code>/Library/WebServer/CGI-Executables</code> directory as though it were a <acronym title="Common Gateway Interface">CGI</acronym> program.&#8221; So, since that&#8217;s how we&#8217;re treating eRuby, we&#8217;re going to want to put our <code>eruby</code> binary in that directory. However, we don&#8217;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&#8217;ll make a symbolic link (or an alias to use the classic Mac terminology) to the binary.</p>
<pre><kbd>ln -s /opt/local/bin/eruby /Library/WebServer/CGI-Executables/eruby</kbd></pre>
<p>With our <code>eruby</code> <acronym title="Common Gateway Interface">CGI</acronym> 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 <a href="//httpd.apache.org/docs/1.3/mod/mod_mime.html#addhandler" title="Documentationf or Apache's AddHandler directive."><code>AddHandler</code></a> and <a href="//httpd.apache.org/docs/1.3/mod/mod_actions.html#action" title="Documentation for Apache's Action directive."><code>Action</code></a> directives.</p>
<p><code>AddHandler</code> simply tells Apache to treat files with a certain extension in a certain way. For instance, you can say something like, &#8220;Treat all files ending in <code>.php</code> as <acronym title="PHP Hypertext Preprocessor; an HTML-embedded scripting language">PHP</acronym> scripts.&#8221; Similarly, you can (and will) tell Apache, &#8220;Treat all files ending in <code>.rhtml</code> or <code>.erb</code> as eRuby <acronym title="Common Gateway Interface">CGI</acronym> pages.&#8221;</p>
<p>To do this, we add the following line to our <code>/etc/httpd/users/<var>username</var>.conf</code> file somewhere inside the <code>&lt;Directory&gt;</code> and <code>&lt;/Directory&gt;</code> block. Naturally, replace <var>username</var> with, of course, your <a href="//docs.info.apple.com/article.html?artnum=106824" title="Apple KBase Article number 106824 describes use short names in more detail.">Mac <acronym title="Operating System">OS</acronym> X user&#8217;s short name</a>:</p>
<pre><code class="httpd-conf">AddHandler rubypage .erb .rhtml</code></pre>
<p>Again, this just tells Apache that files ending in <code>.erb</code> and <code>.rhtml</code> should be treated the same way other <code>rubypage</code>s are treated. But how are eRuby pages supposed to be treated? They&#8217;re supposed to be handed off to the eRuby program, of course, so we need an <code>Action</code> directive that applies to the <code>rubypage</code> handler we just defined.</p>
<p>Right below the above line, add the following line, too:</p>
<pre><code class="httpd-conf">Action rubypage /cgi-bin/eruby</code></pre>
<p>This line tells Apache that any file that it is treating as a &#8220;rubypage&#8221; file should be sent to the program at the <acronym title="Uniform Resource Locator">URL</acronym> accessible at <code>/cgi-bin/eruby</code>, which we&#8217;ve defined earlier to be our symbolic link to the <code>eruby</code> interpreter.</p>
<p>Your completed user-specific Apache configuration file should now look something like this:</p>
<pre><code class="httpd-conf">&lt;Directory "/Users/<var>username</var>/Sites/"&gt;
&hellip;
    # Let eRuby files get parsed through the proper <acronym title="Common Gateway Interface">CGI</acronym> binary
    AddHandler rubypage .erb .rhtml
    Action rubypage /cgi-bin/eruby
&lt;/Directory&gt;</code></pre>
<h3>Are You Being Served?</h3>
<p>That&#8217;s it, everything should now be in place. To make sure, move your earlier <code>helloworld.rhtml</code> file into your user&#8217;s <code>Sites</code> folder, and now simply point your browser to <code>http://localhost/~<var>username</var>/helloworld.rhtml</code> (again, replacing <var>username</var> with your Mac <acronym title="Operating System">OS</acronym> X user short name, of course). Congratulations, you&#8217;re serving up Ruby-coded applications via eRuby.</p>
<h3>Additional Reading</h3>
<p>This is just the set up, of course. Now the real fun begins: learning Ruby. Here are some suggested places to start.</p>
<ul>
<li><a href="//www.ruby-doc.org/docs/ProgrammingRuby/html/web.html">Programming Ruby: Ruby and the Web</a> — A chapter out of the free book <cite>Programming Ruby</cite> all about Ruby as a <acronym title="Common Gateway Interface">CGI</acronym> programming language.</li>
<li><a href="//hiveminds.co.uk/node/3189">Hiveminds: eRuby: How to use Ruby <acronym title="Common Gateway Interface">CGI</acronym> and ERB templating for Web Pages</a> — a quick&#8217;n'dirty article explaining the basics of using Ruby on web pages in classic <acronym title="Common Gateway Interface">CGI</acronym> style where program logic and <acronym title="HyperText Markup Language">HTML</acronym> templates are kept separated, as opposed to classic <acronym title="PHP Hypertext Preprocessor; an HTML-embedded scripting language">PHP</acronym> style, where the two are mingling together on one page.</li>
<li><a href="//coolnamehere.com/geekery/ruby/web/cgi.html">COOLNAMEHERE: Simple Ruby <acronym title="Common Gateway Interface">CGI</acronym></a> — Like the Hiveminds example above, another quick&#8217;n'dirty Ruby <acronym title="Common Gateway Interface">CGI</acronym> how-to.</li>
<li><a href="//ruby-doc.org/stdlib/libdoc/cgi/rdoc/index.html">cgi: Ruby Standard Library Documentation</a> — Ruby&#8217;s standard library contains a rich set of features, and the <acronym title="Common Gateway Interface">CGI</acronym> objects are among them. They are well-documented in the official Ruby Documentation Project.</li>
</ul>
<p>Naturally, feel free to leave comments if you have more resources that you found helpful.</p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2007/10/25/no-framework-ruby-on-the-web-using-eruby-on-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Window and Element Resizing Annoyances in Internet Explorer</title>
		<link>http://maymay.net/blog/2007/05/24/window-and-element-resizing-annoyances-in-internet-explorer/</link>
		<comments>http://maymay.net/blog/2007/05/24/window-and-element-resizing-annoyances-in-internet-explorer/#comments</comments>
		<pubDate>Thu, 24 May 2007 22:30:21 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/archives/2007/05/24/window-and-element-resizing-annoyances-in-internet-explorer/</guid>
		<description><![CDATA[This has been an interesting day. In less than 8 hours, I&#8217;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&#8217;re in quirks mode. If you&#8217;re in standards mode, this property [...]]]></description>
			<content:encoded><![CDATA[<p>This has been an interesting day. In less than 8 hours, I&#8217;ve had to tackle the following <acronym title="Internet Explorer">IE</acronym> nuisances:</p>
<h3><code>document.body</code> vs. <code>document.documentElement</code></h3>
<p>In <acronym title="Internet Explorer">IE</acronym> 6, in order to access the current width of the window in JavaScript you need to get <code>document.body.clientWidth</code> only if you&#8217;re in quirks mode. If you&#8217;re in standards mode, this property not only still exists, but it means something entirely different! It instead refers to the width of the <code>body</code> element.</p>
<p>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 <code>document.body.clientWidth</code>, in standards mode, use <code>document.documentElement.clientWidth</code>. (<a href="http://www.quirksmode.org/js/doctypes.html" title="View QuirksMode's compatibility table.">Reference table at QuirksMode.org</a>)</p>
<h3>Internet Explorer crashes when attempting <code>min-width</code></h3>
<p>If you use <acronym title="Internet Explorer">IE</acronym>&#8216;s proprietary <code>expression()</code> syntax to script a <acronym title="Cascading Style Sheets">CSS</acronym> value, beware of calculating widths or heights that exactly match the value you&#8217;d like to set. If you do something like the following to set a minimum width on <code>#someElement</code>, <acronym title="Internet Explorer">IE</acronym> will crash when you actually resize that element to be 500 pixels wide.</p>
<pre>#someElement { width: expression(document.body.clientWidth &lt; <var>500</var> ? "500px" : "auto"); }</pre>
<p>Instead of doing the above, you should check for <em>almost</em> exactly the size you want, like so:</p>
<pre>#someElement { width: expression(document.body.clientWidth &lt; <var>501</var> ? "500px" : "auto"); }</pre>
<p>However, the really important thing to keep in mind is that the minimum width you&#8217;re testing (<em>501</em> in that second case) needs to be at least one pixel greater than the <strong>total content <em>and</em> padding width</strong> 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. (<a href="http://www.cameronmoll.com/archives/000892.html" title="Fixed: IE 6 min/max width hack">Reference on CameronMoll.com.</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2007/05/24/window-and-element-resizing-annoyances-in-internet-explorer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Importance of Naming Conventions in Collaborative Web Production</title>
		<link>http://maymay.net/blog/2007/05/03/the-importance-of-naming-conventions-in-collaborative-web-production/</link>
		<comments>http://maymay.net/blog/2007/05/03/the-importance-of-naming-conventions-in-collaborative-web-production/#comments</comments>
		<pubDate>Fri, 04 May 2007 03:02:13 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Information & Communication]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Site Optimization]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/archives/2007/05/03/the-importance-of-naming-conventions-in-collaborative-web-production/</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>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.</p>
<p>I&#8217;m beginning a new project at work where, for the first time, I&#8217;m working with a large team of developers, and not just integration developers but front-end developers like myself. Since I&#8217;m the new guy, I&#8217;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&#8217;s grown.</p>
<p>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.</p>
<p>It&#8217;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&#8217;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.</p>
<p>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&#8217;s collective understanding of the code, so clarity is and should be prioritized above optimizations.</p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2007/05/03/the-importance-of-naming-conventions-in-collaborative-web-production/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Making code maintainable: mind your edit-per-change ratio</title>
		<link>http://maymay.net/blog/2007/04/13/making-code-maintainable-mind-your-edit-per-change-ratio/</link>
		<comments>http://maymay.net/blog/2007/04/13/making-code-maintainable-mind-your-edit-per-change-ratio/#comments</comments>
		<pubDate>Fri, 13 Apr 2007 19:48:15 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/archives/2007/04/13/making-code-maintainable-mind-your-edit-per-change-ratio/</guid>
		<description><![CDATA[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&#8217;s certainly true, but that nugget of wisdom doesn&#8217;t actually tell us what [...]]]></description>
			<content:encoded><![CDATA[<p>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&#8217;s certainly true, but that nugget of wisdom doesn&#8217;t actually tell us what to do about all these inevitable changes.</p>
<p>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&#8217;t seem to think as much about this sort of thing because it&#8217;s relatively easy to change things. After all, everyone&#8217;s dealing in bits and bytes at a fundamental level. However, if you take a higher-level look, you&#8217;ll see that many times things are not as easy to change <em>correctly</em> as you might think, and the costs associated with these mistakes and after-the-fact edits can be enormous.</p>
<p>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)<acronym title="HyperText Markup Language">HTML</acronym> and <acronym title="Cascading Style Sheets">CSS</acronym> code.</p>
<p>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.</p>
<p>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&#8217;d need to edit the <acronym title="HyperText Markup Language">HTML</acronym> source of our page to change the order of the content boxes inside the floated columns, and second we&#8217;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 <acronym title="Cascading Style Sheets">CSS</acronym> declaration.</p>
<p>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.</p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2007/04/13/making-code-maintainable-mind-your-edit-per-change-ratio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TEDTalks: Inspirational, incredible, and moving ideas</title>
		<link>http://maymay.net/blog/2006/08/17/tedtalks-inspirational-incredible-and-moving-ideas/</link>
		<comments>http://maymay.net/blog/2006/08/17/tedtalks-inspirational-incredible-and-moving-ideas/#comments</comments>
		<pubDate>Thu, 17 Aug 2006 07:52:39 +0000</pubDate>
		<dc:creator>Meitar</dc:creator>
				<category><![CDATA[Apple/Macintosh]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Human-Computer Interaction]]></category>
		<category><![CDATA[Information & Communication]]></category>
		<category><![CDATA[Tech/Computing]]></category>
		<category><![CDATA[Usability]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://maymay.net/blog/archives/2006/08/17/tedtalks-inspirational-incredible-and-moving-ideas/</guid>
		<description><![CDATA[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&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>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 <a href="//ted.com/tedtalks/">TED.com web site</a>.</p>
<p>I&#8217;ve just spent the past three and a half hours at the site watching the presentations and I&#8217;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.</p>
<p>For those interested in Human-Computer Interface design, you absolutely must view Jeff Han&#8217;s talk on <a href="http://www.ted.com/tedtalks/tedtalksplayer.cfm?key=j_han">an &ldquo;interface-less&rdquo; touch-screen-like display</a> which will very likely obsolete the traditional mouse and keyboard.</p>
<p>For those interested in global health and economics, you absolutely must view Hans Rosling&#8217;s talk on the <a href="http://www.ted.com/tedtalks/tedtalksplayer.cfm?key=hans_rosling">myths of the third world</a>.</p>
<p>And for those who just want more proof how much Apple Computer rocks our socks, you must view David Pogue&#8217;s excellent <a href="http://ted.com/tedtalks/tedtalksplayer.cfm?key=david_pogue">presentation on the woes caused by software frustration</a> (and it&#8217;s partially set to music).</p>
<p>My personal favorite (so far) was Sir Ken Robinson&#8217;s almost stand-up comedy approach to <a href="http://ted.com/tedtalks/tedtalksplayer.cfm?key=ken_robinson">explaining to us why the current state of the world&#8217;d public education systems will not serve us</a> for our future.</p>
]]></content:encoded>
			<wfw:commentRss>http://maymay.net/blog/2006/08/17/tedtalks-inspirational-incredible-and-moving-ideas/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

