netrenaissance.net

this.code();

Site Redesign

It's taken some time, but I have done a site redesign by creating a new theme for Drupal.

I'm tweaking a bit as I notice oddities, but overall I'm pretty happy with my results! It's completely fluid, and seems (to my eyes at least) to be fairly legible.

I think I want to use some technology like cufon or sIFR to make the title prettier, but that can come later.

More Sitecore Thoughts

I have been working on a variety of Sitecore projects during my immersion in the CMS world, and I have some interesting conclusions.

Firstly: Successful Sitecore development companies are sparked by the configuration over convention principle.
This is mostly due to the client indecision problem. Illustrated in full; when a client asks you to change something once, you change it. When they ask you to change it a second time, a successful development company will create a configuration option so that the client can do it themselves. This saves effort in that you are reasonably sure that the client will ask for a third option later, thus validating your time spent.
Since there is tendancy for Sitecore clients to be indecisive (why do you think they were sold on Sitecore in the first place), this rule works in general for dealing with these companies.

Secondly: Sitecore clients enjoy creating needlessly intricate Governance strategies.
Companies know levels of heirarchy, it is their folly that they expect to replicate this complexity inside of a modern day live website update process. Generally, updating a website becomes a needless beaurocracy to perform basic changes. Unless end users are involved from the start, these valient folks will generally hate you, so try to get them involved in a meaningful way from the start. These are the people who will object to email notifications at all workflow steps, or having to have 15 levels of approval for a textual change.

Thirdly: Sitecore documentation is insufficent, the API is redundant, and often unintuitive.
I looked for the ability to send Emails under the Sitecore.Mail namespace, and found it under the Sitecore.MainUtils.SendMail() method an hour later. Enough said.

UPDATE Alex is correct, I should have been looking under the System.Net.Mail namespace.

There are others, but I'll leave it at that for now.

Thoughts on Scope

I have been thinking about when I learned an object oriented vs a procedural language. My teachers of the day (two guys who knew Java) started into the basic "this is a car" speech that I'm sure many of you had when you went to an object based language. At the time, I was confused. I could easily replicate this with a procedural based viewpoint. The thing that these teachers missed teaching me was that *objects keep their own scope*. At the time, I would have had no idea of what scope was, but I like to think that I would have learned through curiosity, rather than being stuck on Turing and its somewhat basic environment (and yes, I know that there was the OOT alternative, but we weren't that advanced yet at my backwoods highschool).

In my opinion, scope is a very important thing that is often overlooked. Minimization of scope is the coding equivalent of tidying up a room once you have left it.

Also, knowledge of linguistic scope is important to avoid unexpected consequences.

For instance:
Javascript:

  function myTest(){
    if(1==1){
      var i = 1;
    }
   alert(i);
  }

If you do not know i == 1 at the point of the alert, you are setting yourself up for a more probable likelihood of hard-to-debug errors. So, I personally think scope is a very important factor in learning a new language or coding style.

In Sitecore news, never try to perform a paged operation in Sitecore without a search engine index backing you up. We've tried this multiple times @ my work now, and Lucene or a similar index always performs so much better than a traditional XPath or Sitecore query that we are no longer reccomending anything else to clients.

jHaml Update

Just a quick note that I have updated the jHaml page so that there is a live demo on the page. Feel free to give it a shot, it gives an example of attaching a click behavior to do in-page Haml processing. Once again, feel free to check out or download the jHaml source.

Javascript Global Definitions: A Parallel

So as mentioned in my last post, I've been reading about some awesome javascripty stuff lately, and I came to what I believe is a fairly good analogy between statically-typed land and javascript global variable/scoping issues.

Many people wonder why it is that you should scope your functions in such a way as to minimize your global variable footprint. To recap: when you define a function in javascript, generally it is lexically scoped, which means that if you do not attach your function to an existing object, your function is defined in the global scope.


function myAnnoyingFunction(someOperand){
  alert('I am annoyingly adding myself to the global scope');
}

What this means is that your function is now there, sitting in the global scope with all the other javascript fragments your end consumer may have running there as well. This is bad for a variety of reasons including but not limited to: possible interference with other javascript code, security implications for your code and generally being sloppy.

Here is my statically typed analogy: Every time you define a globally scoped variable, you are effectively creating a new namespace declaration in your assembly.

Nobody likes that kid.

You know the one, you import their assembly and you get namespaces like "Random_Junk.MyClass1" and "Vendor.MyClass" and there is no intellisense defined for them, and it just makes you want to scream.

"This is not the way to define a publicly accessible API!" you mumble to yourself... forcefully... with vehemence.

In any case, don't do it. If you are worried about your javascript, or aren't very good at determining your scope, check out the JSLint tool, it will warn you about this sort of antisocial behavior.

In other news, there is a great coding convention for jQuery which involves starting your files with a semicolon. I highly recommend people get into this habit, as it protects you from a variety of nastiness which can happen if the server or your end users concatenate javascript files together for their clients.

Great Book, Javascript: The Good Parts

Over the weekend I picked up Douglas Crockford's new book, Javascript: The Good Parts. It's a great read, and presents a lot of interesting Javascript concepts like closures, functions, prototypes in an easy to understand manner.

I have been looking for a book to really understand prototypes in particular (how they differ from a statically typed class approach), and this book is a great help on that front. Additionally, the state diagrams for how Javascript interprets code is, I think, visually very easy to grasp.

In other news, I learned that Sitecore's built-in image library has some issues with resizing GIF files with transparent backgrounds. In particular, attempting to do so will render the resized version's background non-transparent (tests are currently showing that the background ends up black). I am currently unsure of why this is, or if there is a way to fix it (maybe one of the thousands of web.config Sitecore setting lines, for instance). So, for now, avoid resizing transparent GIF files in Sitecore.

Phoning it in - Thoughts on Coffee

I like my coffee.

Over the years I have discovered that one of the benchmarks for a new employer has become:

  1. How good the coffee is
  2. Whether or not the coffee is free

My current work-coffee situation has been deteriorating. They do not use the correct size of filters, which oftentimes causes the pot to become filled with coffee grounds. This does not make for an incredibly wonderful cup of coffee, let me tell you.

Additionally, the coffee is left out on the counter after it has been opened. I am not sure, but I am in the habit at home of chucking the canister into the freezer after opening it. This more or less ensures my coffee grinds don't go rancid and suck. I made the mistake of smelling the work coffee canister today. It currently smells like something between garbage and vomit, and caused me to repress a gag.

I think I'm going to start bringing in my own thermos.

Configuring Views in Bind9

One of the first IT projects I undertook was building my own DNS server. This has a host of benefits, from being able to define other local computers by name (and not relying on Windows' computer name property anymore) all the way up to increased mobility between Internet Registrars.

One of the problematic parts about hosting your website locally is that you want to expose a different IP address to your local network than what is exposed externally. Luckily for us, Bind9 has a method for doing this called Views.

In our example, we will be setting up a domain name called "mydomainname.com". Our local network is 192.168.0.0/24 (which means 192.168.0.0 - 192.168.0.255).

The first thing we want to do is open up the named.conf file and ensure that it is importing the named.conf.local file.

  sudo nano /etc/bind/named.conf

You should see the following at the bottom of this file:

  include "/etc/bind/named.conf.local";

Great, close named.conf, and we will now go and edit named.conf.local.

  sudo nano /etc/bind/named.conf.local

Great, add the following, replacing the 192.168.0.0/24 with your local network address range, and the "mydomainname.com" with your domain name:

acl internals {
  192.168.0.0/24;
  127.0.0.0/8;
};
view "internal" {
  match-clients {internals;};
  recursion yes;
  zone "mydomainname.com" {
    type master;
    file "/etc/bind/zones/internals/mydomainname.com.db";
  };
};
view "external" {
  match-clients {any;};
  recursion no;
  zone "mydomainname.com" {
    type master;
    file "/etc/bind/zones/mydomainname.com.db";
  };
};

Now, we need to set up the zone files for our internal and external people.

  sudo nano /etc/bind/zones/mydomainname.com.db

Enter the following, replacing the Serial with the date in the form yyyyMMddxx, where the xx refers to the time you have edited the file today (use 01 today). Replace 60.60.60.60 with your external IP address. Replace "mydomainname.com" with your domain name.

$TTL 604800
mydomainname.com. IN SOA dns.mydomainname.com. root.mydomainname.com. (
  2000022301 ; Serial
  604800 ; Refresh
  86400 ; Retry
  2419200 ; Expire
  604800 ) ; Negative Cache TTL
mydomainname.com. IN NS dns.mydomainname.com.
    IN A 60.60.60.60
@   IN A 60.60.60.60
dns IN A 60.60.60.60
mydomainname.com IN A 60.60.60.60
www IN A 60.60.60.60

Next, edit the internal version of this file.

  sudo nano /etc/bind/zones/internals/mydomainname.com.db

Then enter the following, replacing the 192.168.0.100 with your internal server IP address, and mydomainname.com with your domain name.

$TTL 604800
@ IN SOA dns.mydomainname.com. root.mydomainname.com. (
  2009022301 ; Serial
  604800 ; Refresh
  86400 ; Retry
  2419200 ; Expire
  604800 ) ; Negative Cache TTL
;
mydomainname.com. IN NS dns.mydomainname.com.
@   IN A 192.168.0.100
www IN A 192.168.0.100

Now restart your bind server. Your internal network will now resolve to your internal server IP, and external people will resolve to your external IP.

  sudo /etc/init.d/bind9 restart

jHAML Alpha Is Up

For all of you keeners, I went ahead and threw up my alpha code for jHAML. So, feel free to check out the plugin code for jHAML.

If it's too opaque for you, you can check out my quick demo on the jHAML homepage. Essestially the code will go off and grab a HAML file at the /HAML/basic.haml location and render it out into a div tag #main. Currently it alerts out the response so you can see it, but I'll likely change the format so that you can see it visually on the page through the use of embedded code tags.

If you are curious, you can check out the original HAML file I created for testing this too. It's fairly basic, but it covers most of the bases which I've implemented.

I'm going to continue to refine it, and hopefully make it a little less hacky than it is now, but doing this exercise has taught me a bunch about HAML and jQuery already (including how much I need an actual regular expression scratchpad tool).

I also learnt more about Bind syntax when I had to set up the zone entries on my DNS server, and fixed some niggling internal resolution errors I'd been having (as I am using internal and external views). As I am primarily from a Windows/.NET background, all this playing in Linux is actually helping me get a lot of familiarity with setting up IT infestructure.

Response Types and Sitecore

Currently, a good design choice is to use div tags with background images instead of actual img tags. Unfortunately, this doesn't gel very well with Sitecore, as it is much easier for a content author to do an upload of a new image, rather than doing a detach/attach operation on an individual image which already exists in the CMS. This essentially means that when the image is changed, a more technical person has to crack open the CSS file on the server and modify the path to the new image.

This is not an optimal situation, so I threw together a Layout for the frame, and then a Sublayout to parse through the Media Library and output CSS class definitions for each image in the Media Library in the following form:

.imagename {
  background:url(/pathtoimage) 0 0 no-repeat;
  39px;
  40px;
}

Now our designers are happy too! However, the important part I learnt from this process was the following:

In order to 'finish the process', I made the Layout change the response type to "text/css" (because I'm a completionist like that, apparently). Much to my surprise, Sitecore changed the extension of the emitted item to have the .css extension without me having to do anything.

Clever, Sitecore....very clever.