netrenaissance.net

this.code();

jQuery and HAML

I have often read that the best way to learn a language is to write an interpreter for it. So, with this in mind, I have begun work on writing a jQuery interpreter for HAML.

Does this make any practical sense? Well, I suppose it does, if you want an alternative to tossing around AJAX responses in HTML, XML or JSON. Mostly, however, I am doing this to learn more jQuery and HAML. If it goes really well, I may extend it to handle CSS assignments by SASS (now wouldn't that be SASS~y!).

As of where I left it today, it will parse simple HAML statements as well as attribute hashes.

The things I still need to work on include:

  • Respecting whitespace compressing and formatting rules
  • Implementing some counterpart to RHTML statements. I am trying to decide what makes sense for jQuery. Maybe eval statements?
  • Boolean attribute values (eg: selected = "selected")
  • Attribute methods and definition statements (have to play with the scoping for this...I don't want to make it globally scoped)

So yeah, that's just a taste of what's to come, but it's already super neat that I can take something like:

  #great
    %p.paraclass
      Some nice text
    %p#secondpara{:class => "greatness"} Some paragraph text

And it all works!

SASS is Awesome

I have been investigating HAML and I came across SASS, its CSS counterpart.

How many times have you wanted to associate CSS definitions for descendant elements in your CSS files? Here I am talking about something like:

body div p{
  color: #DEDEDE;
}
body div p a {
  color: #000000;
}

With SASS we can make it oh so much sexier with the following syntax:

  body
    div
      p
        :color #DEDEDE
        a
          :color #000000

Note that the levels are delimited by two spaces per level. This is amazingly cleaner, especially as the descendant rules become increasingly complex. Furthermore, the syntax visually follows the actual structure of the associated XHTML, HTML, or if you are truly into this, HAML file.

For those of us .NET folks, there is a great project called nHAML initiated by Andrew Peters. I'd check it out.

There is even some help for using HAML in Sitecore. Check out Alexey's Blog Post on HAML, or the now Sitecore MVP Alistair Deneys. Incidentally, Alistair Deneys' post about HAML in Sitecore was what got me started looking into this concise markup language in the first place.

Twitter Request Limits and You

A few weeks ago, I decided to challenge myself and write a .NET interface to some basic Twitter functions which I then used to populate a Sitecore installation. However, that is a story for another day. The important issue here is that there are many people using third-party Twitter plug-ins and libraries (or even in extreme cases T-SQL queries), and they should know some basic information about how Twitter lets external parties access its services.

Twitter has an hourly request limit which is currently set at 100 requests per hour. They monitor this in one of two ways: either by IP address or by authenticated account. For the average user, this isn't a big deal, but be wary of client-side AJAX-driven plug-ins. If these are not using a caching mechanism locally on the server (writing to your database for instance), they are likely eating up at least one request every time someone accesses your page! If you surpass the 100 request limit, Twitter will deny your API request.

So, you ask all wide eyed and curious, how do I tell if my library is doing this?

The first thing you will need is cURL. Download the non-SSL version for your OS of choice (we won't need SSL functionality for Twitter), and then extract it and go to the directory.

Next, run the following command (on the client and server, hopefully they have separate public IP addresses):

curl http://twitter.com/account/rate_limit_status.json

This will return a result like the following:

{"remaining_hits":100,"hourly_limit":100,"reset_time":"Wed Feb 18 00:10:40 +0000 2009","reset_time_in_seconds":1234915840}

The important number here is the remaining_hits number. This represents the number of API hits you have left this hour. Next, try visiting your website's Twitter feed, and re-run the command to see how many hits you have left now. If the number goes down, this is bad. Your plug-in or library is using the non-authenticated method of accessing your Twitter feeds and it is performing no caching. Essentially, this means that if 100 people visit any twitter-enabled page of this sort (on your website or anyone else's) in an hour from the same IP address (or the same person 100 times), your plug-in will stop working. If the number goes down on the server, this means the client AJAX requests are asking the server to perform the call for them, which means you have a global 100 request per hour limit for all visitors of your website, instead of 100 requests per client's public IP Address.

If the number does not decrease, try running the following command (again on client and server):

curl --head -u username:password http://twitter.com/account/rate_limit_status.json

If this number goes down, this means that the plug-in or library is calling Twitter in authenticated mode. If this is on the server, this again means that all visitors of your website have a global limit of 100 calls to Twitter.

However, if this is on the client, this is the absolute worst case. This means that clients are calling the Twitter API directly using your credentials. Worse still, since these are sent in plain-text, anyone accessing your site can use a tool like HttpFox to grab your login credentials from the Request Header. If this is your case, I would change your Twitter password immediately and discontinue use of the affected plugin or library.

I hope everyone has learned something about Twitter and request limits today!

PHP & sIFR Investigations

Gripe of the day: I have a local DNS box, and every time I reboot it, I have to log into it and restart bind9, or else my DNS will not resolve. I have no idea why!

I have been looking into PHP IDEs in preparation for the CakePHP project I'm going to be working on coming up. At the moment, the nicest one I've found is PhpED by NuSphere.

I've read a bunch of great CakePHP tutorials by the guys at Switch on the Code (incidentally, I love what they did with their name/logo to make it completely an inside programmer joke).

I've been looking into sIFR techniques at work lately. Is it just me, or are they either fraught with poor performance and/or non-compliant to some browsers?

MySQL Interfaces

So today I looked into different interfaces to dealing with MySQL databases. I played around with Navicat and it seems pretty intuitive and solid. Unless I find a compelling reason to shift to something else, I think this will be my replacement for my current PHPMyAdmin tools. They're decent as far as remote tools go, but they are nowhere near as performant as an actual desktop application.

A thought has been mulling about in my head which I think I might look further into tomorrow. It should be fairly trivial to set up a JSON generator for Sitecore items. I am thinking of having my current Ajax frame (which is basically a blank .aspx page with a Sitecore placeholder inside it) and then using either an xslt rendering or a sublayout (if necessary) to generate the JSON. This should allow for AJAX requests for true Javascript versions of Sitecore items on the client side. Additionally, since the client's credentials would be passed through the AJAX call, it would be trivially secure (as it would be delivered over the device framework, which respects user security levels).

I'm pretty excited; bring it on, Sitecore!

Anchors and URL Parameters

I have become very interested in accessibility and the practice of progressive enhancement as I get more and more into jQuery mixed with Sitecore. I think it is important that a RESTful URL be presented to the end user for any interaction with the server for any GET operations.

As I've found today, there are many accepted methods for doing so, involving URL parameters and anchors, which provide a Deep Linking mechanism for use of bookmarking and back/forward button use inside AJAX driven pages.

<Warning, Sitecore specific talk>
I currently have my server emitting URL parameters for any AJAX hyperlinks, and then rendering out over a device pipeline when it encounters the ajax=1 query string parameter. However, when performing asynchronous operations from my jQuery, the browser URL would not update upon completion of the operation. This is because we are forced to abort the click event from the hyperlink, in order to prevent the page from *actually* reloading. This can be solved with the use of anchors for these operations instead of url parameters. Note that we cannot update the URL path directly without causing a browser refresh for browser security reasons (phishing, etc.), we can only update the anchor programatically.

So to recap:
Our accessible users are fed static hyperlinks with URL parameters which function normally - browser state is trivially managed
Our javascript enabled users have these overridden to call the server dynamically to prevent postbacks - browser state is managed by anchor tags

Tying up loose threads:
Our javascript enabled users now have bookmarks with anchor tags. We can use either the History Plugin or something custom to manage this, and get the page state back to the way it was.
Our accessible users get trivially functional URLs, and can share with our javascript users.

Seeing this coming?
One remaining problem:
Our javascript users cannot share URLs with our accessible users!

Why?
The anchor tag is not sent in most cases to the server. It is intended to be a client-side only tag, and thus it does not get sent (again, in most cases) as part of the request to the server. This means we cannot rewrite the anchor tag into a URL parameter for our accessible users.

Also, our accessible users cannot take advantage of our dynamic javascript which handles anchor tags because they have no javascript.

I'm going to keep thinking about this, but for now I feel like I'm at a dead end, and this is the best solution available.

...and it irritates me that this case slips through.

IE 7.0 Problem with Nested Form Elements

I learned the hard way today that IE 7.0 does not handle nested form elements *at all*. In fact, after the location of the nested form, my input=submit elements refused to submit either form!

Of course, Firefox worked correctly, adding to my confusion.

Hope this helps someone out there!

Blog

First Blog Entry on the new Netrenaissance