22 January 2007

A date to behold!

I have updated the code with a much cleaner one, which can be changed easily if you want to alter the order or anything else. If you have one, you don't need to update, but first time users might as well take the new one.

Also, if someone has trouble finding the correct date format, see the picture below. It's the second last format in the list :)

This was something that I wanted to have when I saw it on Lifehacker. Their dates look, well, different, and I thought it'd be really cool to let your dates stand out than the normal one line dates that Blogger forces us to have. It is basically a function that takes in the Blogger date as an input, does some fancy splitting and slicing, and outputs the day, the month and year in it's own seperate line, or if you like it, as a picture. There is a catch to the niceness.

Before you jump in

If you want to use pictures, like I have, you'll have to put in some time and photoshop work. Since there is no scripted way of generating pictures (not without much hallabaloo at least), you will have to make the picture for all days, months, and a few years. That means, you will need a picture with the numbers 1-31, month names January to December, and a few years from 2006-2008 (or from whenever you started your blog). This can be quite a job, so I'll suggest you go with the first method.In case you want the pictures, you'll need to modify the document.write statement to output image tags, with the source set to in a format of url/"+array-element+".png. This will generate an image for every value held in the array. That will take a bit of template modding as well, with some knowledge of CSS to make the styles. Don't say I didn't warn ya! :P

The code

Let's get hacking. Begin by changing the date format output of your dates from the blog settings. Change it to show dates as '23 January 2007' (with the spaces, no commas). Then put in this bit of code in your <head> area:

function date_replace(d){
 var da = d.split(' ');
 day = "<span class='theDate'>"+da[0]+"</span>";
 mon = "<span class='theMonth'>"+da[1].slice(0,3)+"</span>";
 year = "<span class='theYear'>"+da[2]+"</span>";

Now, you'll need to find the place where the date tag is in your template. The date tag looks like <data:post.dateHeader/>. You'll have to replace that line, and anything else within that <b:loop> tag, except the conditional statement (<b:if>) with this:

<div id='post-date'>

That's all you have to do at the template hacking level. The next to do will be to define styles for your newly generated date. Your three parts of the date are held in three <span> elements as you can see from the function up there, with the class attribute set to 'theDate' (for the day), 'theMonth' and the 'theYear'. You can style all of them the way you like it by defining classes in your CSS named as div#post-date span.theDate and so on. You should set a display: block; to begin with so that they all come up in a seperate line. Other CSS style attributes can be applied as per required. The parent element will be styled with a div#post-date to hold the background. It can be a picture or a simple colour, it's up to you. Here's a sample CSS definition which you can use in case you're lazy:

div#post-date {
  display: block;
  float:left;        /* set this to right if you want it go to the right */
  padding: 1em;       /* to keep the text away from the edges */
  background-color: #555555;  /* you can change this to hold a picture, will make it look nicer */
  border: 3px double gray;   /* a border to make it look nice */

div#post-date span.theDate {
  display: block;       /* to put this in a different line */
  font-size: 3em;       /* to make the date stand out */
  background-color: transparent; /* to let the background show through */
  color: white;

div#post-date span.theMonth {
  display: block;
  font-size: 1em;       /* smaller compared to the date */
  background-color: transparent;
  color: white;

div#post-date span.theYear {
  display: block;
  font-size: 1em;       /* smaller compared to the date */
  background-color: transparent;
  color: white;

All that will go within your <b:skin> tags in case your wondering. If you know what you're doing, go around and play with the attributes to get what you'll actually looking for.

That's pretty much it! It'll be a little hard to use images with this for those who don't know Javascript, so if you want, I could modify the function for you to output the images. You'll need to give me the URL to your images though. Do 'not' use Blogger Image hosting to upload your pictures. The path is never constant, and this function requires that the path always be constant, with only the names of the images changing. The names themselves should be 1.png, 2.png and so on for the days, January.png and so on for the months and 2007.png for the years. All in the same format! You'll need to make 31+12+1 (atleast) = 44 images. I did it twice :P Once for my old blog, and then again for this new one. I'm beginning to not like this look too, so a third round might be imminent!

But now you know how to get it done! So go ahead, make your dates look great!


Singpolyma said...

Shouldn't span#theYear be span.theYear, etc (classes, not IDs) ;)

Aditya said...

Damn! That's what happens when you post a draft after a 'very' long time and you try to edit it!

Thanks ;)

Brice said...

Yo man, great blog design! I was wondering if you did it all in CSS, and if so, if there are any sites that you can recommend to help me out with CSS Design.


cyberbuff said...

thanks so much...i love you :P cant wait to implement it...

Aditya said...

@Brice: Most of it is CSS, almost 95%. I try to keep things fast :) As far resources go, there is no real 'one stop' solution for that, but W3Schools seems to be a good place to start!

@Cyberbuff: Thank you! You flatter me way too much! :P

Deepak said...

I have custom dates like this implemented in my upcoming template. :)

I have a question though. I have no idea how document.write is working in XHTML. Is it because the Blogger parser is not exactly a strict XHTML parser? If I remember right, XML parsers don't support document.write due to well-formedness aspects.

Regarding the use of pictures for dates, you can create a single picture with all months (similarly for date) in it, and then use js to change the CSS and show only the area of the image with the relevant month. Basically, play around with the margin and width attributes, if you understood what I mean.
I cannot say for sure, but I have a hunch that this will load faster as you don't have to load and decode N number of pictures now.

Aditya said...

Second part first. Yes, it'd be faster, but not easier. For the reason that you'll have to have a different CSS class for every image ... which will add a tremendous amount of lines, hence negating to some extent the drop in loading time. Ofcourse, I might be missing out on a easier way here!

document.write was the method used before DOM functions became the tried and tested best way of working with the DOM. It works because it spits out the string which is basically the same as you writing the tag yourself (seeing how pages are compiled by a browser top-down). If you look at the code in Firebug, you'll see the script code above the 'span' tags being generated. That should give you a better idea of how it works :)

Deepak said...

Sorry I wasn't clear. I meant that you can use the image as a background image at that location and change the background-position using DOM/javascript.
I'll give an example for the month case. Create a banner image for 12 months, say 12*100 pixels wide.
In your CSS for the month class, you can specify the width as 100px and background image as the one you have. So it will show only 100px of the imager at any time.

Now change the xpos of the background-position according to the logic in your javascript. It will drill down to a simple arithmetic to calculate your xpos based on the month number.

It is not too much of an increase in code size.

Deepak said...

My question was not how document.write works...It was why it works in Blogger? It is not supported in XHTML.


Aditya said...

Ok, now I see :)

Yes, your method seems to be faster for sure! I'll try and revise my script with yours when you come up with it! Too lazy to sit and rework it at the moment.

And about the 'document.write' thing. I guess it 'is' because Blogger's templates aren't served directly as is. It is parsed through Blogger's servers, so some fancy work might be going on there. I am not entirely sure, but it's always worked for me :) Also, Blogger is 'not' XHTML Strict, as I have noted here, so that might answer something too?

Brice said...

I envy your top bar with the links to Blogger, About, and Search. If I wanted to create a menu (not for my blog, just for practice) and have an orange background on hover, how would I do that?

Aditya said...

Just set the 'background-color: orange' property to the ':hover' pseudo-class name :)

Deepak said...

I just found out an issue in this script.

Blogger has apparently implemented the navigation links to make a HTTP POST request asynchronously when you click on Older Posts. Only the post section is updated and page is not loaded fully.
I see a XMLHTTPRequest in Firebug Console.
The problem is, the date_replace script is not executed after this background load, so the date block is not displayed in this case.

You can check my test blog to understand the usecase.
From index page, press Older posts.

I am trying to find the issue, but you are the best person to find it, since it is your script. :)

In short, the script is executed whenever a synchronous page load happens, but not when the request is asynchronous.

cyberbuff said...

oh my! it didn't work for me. (I know I must have done something wrong.)
Ok here is what I have done...I wrapped the 1st part of the code in <script type="text/javascript"></script>
Then I added the css definitions. Finally replaced <data:post.dateHeader/> with the 2nd part of the code. But all I got was a '. That's all. Please tell me what have gone wrong...

Aditya said...

@Deepak: Sheesh! That 'is' a noodle! I can tell you 'why' it's happening, but it'll take some looking into to figure out how to fix it.

I'll look into it soon! I'm at home right now, so busy with friends and relatives! :P But I'll definitely look into it! Thanks for the headsup.

@cyberbuff: I don't see the code anywhere in your page. You'll need to put it in, and then I'll have a look. But what do you mean by a -'. -?

Are you sure you've fixed the date format in your settings tab? Change it to show dates as 'January 23 2006' (with the spaces, no commas). See if you missed that...

cyberbuff said...

ok i missed it the formatting part. But i have not found the format you specified here. That is january 23 2006. All of them has at least one comma. The one that doesnt have any comma has the date first. So I changed the document.write a bit. I placed <span class="theMonth">'+month[mon]+'</span> after <span class="theDay">'+day+'</span> But still not getting anything. :(

Aditya said...

It's the second last option in the list of date formats. And don't change the code to that, unless you want the month to show up before the day :P

cyberbuff said...

it's working now. Please take a look. I got some help from deepak's test blog, too. And thanks to both of you. Cheers! :)

x_pIOVE said...

great code!!! I've immediately updated my blog!!! great job!!!

Aditya said...

It looks absolutely wonderful! :) Well done! I've sent you a mail regarding my hack license, just a little formality. Thanks :)

I would like to know how can I set the format of Url/¨+array+¨.png
Can you explain me. it is more useful tool for me.:$

Aditya said...

To implement that, you’ll have to firstly name your images according to the date element. So days will be 01.png, 02.png, 03.png and so on. Months will be January.png, February.png, and years will be 2007.png, 2008.png … it’s a lot of work, I know. There is another way, but I’m not sure if it’s any faster.

So, once you have the images in place, modify your document.write to output image tags with the source set to:


where ‘i’ goes from 0–3, in the order you want the date elements to show. So for the day, and using my Googlepages account, the URL string should be:


Hope I’m clear enough :)