They say you learn something new every day.

Posts tagged ‘html’

Line Thickness (18/03/2012)

For a long time when I wrote CSS and needed to put a line around something, my go-to code was:

border:1px solid black

 I just loved one pixel of pure solid black. Here it is in action:


See. 1px of black border around everything! Then, when using IFTT I had a bit of a change of heart. I loved their bold blocks of large colour.


However, I felt there were two tricks they’d missed:

  1. They didn’t have any hover over effects. I’ve realised that this is really key on any sort of application, and web apps in particular. You really need to give the user some sort of feedback, or show them visually that they can interact with the button in some way. Not to mention it makes the site nice to use. The hover over effect on this page is my favourite part.
  2. They don’t have any borders.  I think this is a missed opportunity. Borders are a really nice effect. If I was designing this, I’d give those buttons a hover over effect and a thick border.

Now, I’m not saying they’re wrong, I’m just saying that is how I’d do it.

I was a bit inspired by the IFTTT page when I had to design a little application at work the other day for logging tasks. Each of the large buttons below has a hover over effect when you mouse over it.


The thick lines, I think, really bring this to life.

Browsing Tumblr themes the other day I found a really nice one that I’ve added to my personal Tumblr.

Personal Tumblr 

The thickness here is 5px. Which is thicker than I’d go – but actually I love it. 

Again, I feel there are a couple of tricks they’ve missed here. The border around the “About” box looks out of place, and the icons for the types are a different style to the rest of it. But I love this theme. I’ve been meaning to properly redesign my theme for this blog for a while, so I may do that soon. This style has inspired me.

Pimp my Tumblr Some More (08/01/2012)

I’ve quoted Steve Makofsky’s description of his blog as “a backup of my brain – a permanent online record so I wouldn’t have to write everything down” before, but I really like it. I’ve realised it’s exactly what I’m trying to do here.

It’s surprising how often parts of my brain become corrupted and need to be restored from the backup!

When I went home at Christmas I found this book:

My Favourite Childhood Book

As a child this was one of my favourite books about cartooning (I wanted to be an illustrator, you see). I pored over it for ages. And in particular one picture:

My favourite childhood desk

I loved the look of this desk and wanted to have one like it day.

I’ve had this picture half in my mind for a long time (when I first left home I bought two massive pieces of wood from Ikea and put together a corner desk a bit like this). However, it was really nice to see the original again since it had meant so much to me when I was little.

It was also really good to recalibrate my interests. Sometimes, we’re so busy going through life that we forget what it is we actually want. It was useful to put myself back into my childhood state of mind to remind myself what I like doing, and what I want from life.

This leads me back to the purpose of this blog. One of the reasons I’m keeping it is so that I don’t forget things. And I don’t mean things like buying some milk or writing a thank you note to Aunt Mavis for the knitted gloves. I mean useful things. The interesting, useful things you learn and read but then forget.

This Guardian article about “waiting-for-lists” sums up the sort of problem I’m trying to solve:

[…] multiple times a day, at work or outside it, most of us make requests of people – underlings, superiors, friends, service providers – and simply assume they’ll follow through. Even non-managers like me, whose work involves no formal delegation, “delegate” like this all the time: that’s what’s happening when you order a book from Amazon, ask a colleague for a piece of information or email a friend about your weekend plans. Yet based on an unscientific survey of my acquaintances, what proportion of people have a systematic way to keep track of who they’re waiting to hear back from? Zero per cent, approximately. (I suspect the same problem infects entire organisations, too.) And though aficionados of David Allen’s book Getting Things Done will be familiar with this issue, the vast majority of “productivity systems” are no help at all: they’re fixated on helping you remember and prioritise your own tasks – even though, in truth, you’re far less likely to forget about those.

It turns out that keeping a “waiting-for” list is like being handed a pair of x-ray spectacles for peering inside your colleagues’ lives. Based on what does or doesn’t get crossed off the list, as people do or don’t get back to me, I’m pretty sure I now know who’s on top of things, and who’s inefficient or just lazy, their email inboxes backed up like clogged drains. (It’s possible, I realise, that it’s just me they’re not responding to, out of icy contempt. I hope not.) The only downside is wondering how many loose ends I must have let slip before keeping the list: how many mail-order items ordered and never received, how many plans suggested to friends then abandoned, just because it slipped my mind that I’d ever asked?

I’m shocked to think of all the interesting ideas I’ve read or thought, insightful quotes, fascinating websites, things I’ve learnt and then just forgotten.

I learn things and then I forget them again. Trying to get less stupid is like filling a bath with the plug out. You’re filling it, but at the same time, information is running away.

There’s a bit at the beginning of each of the Head First Labs books explaining why this happens:

[…] what does your brain do with all the routine, ordinary, normal things you encounter? Everything it can to stop them from interfering with the brain’s real job—recording things that matter. It doesn’t bother saving the boring things; they never make it past the “this is obviously not important” filter.

How does your brain know what’s important? Suppose you’re out for a day hike and a tiger jumps in front of you, what happens inside your head and body?

Neurons fire. Emotions crank up. Chemicals surge.

And that’s how your brain knows…
This must be important! Don’t forget it!

But imagine you’re at home, or in a library. It’s a safe, warm, tiger-free zone. You’re studying. Getting ready for an exam. Or trying to learn some tough technical topic your boss thinks will take a week, ten days at the most.

Just one problem. Your brain’s trying to do you a big favor. It’s trying to make sure that this obviously non-important content doesn’t clutter up scarce resources. Resources that are better spent storing the really big things. Like tigers. Like the danger of fire. Like how you should never have posted those “party” photos on your Facebook page.

I’m not convinced that’s fully how your brain works, but it’s close enough. And the end result is the same.

Writing things down is all very well, but as Samuel Johnson says, there’s two parts to learning:

Knowledge is of two kinds. We know a subject ourselves, or we know where we can find information upon it.

So today I reviewed my tagging of my posts. More importantly I added the “categories” bar to the side of this page.

At first, I was a little annoyed that Tumblr didn’t add a list of tags to the side of the blog automatically, like, say, Blogspot or WordPress. However, this has given me an opportunity to organise my tags a little better.

I want to keep this up to date, and regularly check that I haven’t inadvertently mistyped or created any new ones, and that’s where today’s script comes in.

set xmlhttp = CreateObject(“MSXML2.ServerXMLHTTP”) “GET”, Page, false
xmlhttp.send “”
Fetch = xmlhttp.responseText
set xmlhttp = nothing

I’ve written this vbscript function that downloads the contents of webpages into a string.

Luckily, on Tumblr, the complete post of each article is displayed in the summary page, so I can just work my way backwards through the pages until I get to the first article:


All we need to do is hold some unique text from the first article I wrote. Something like the unique Disqus key (of course, I can’t post it in this article, or I’ll break my script!).

We end up with a script that looks a little like this:

DO UNTIL Done = “Done”

NewPage = Fetch(PageUrl & PageNumber)
PageContents = PageContents & NewPage
PageNumber = PageNumber + 1

IF INSTR(NewPage,EndContent) > 0 THEN
   Done = “Done”


Now that I’ve got all the contents of my Tumblr articles in a string I can do some interesting things with them.

It’s actually a backup (although not the backup, as the proper one has to be automatic, and I’ve already solved that problem), but I can do stuff with it.

The first thing I did was this, so that I could pull out all the links:

Links  = Split(PageContents,”href=”“http”)

Then I looped over the array and removed all the junk data:

ThisLink = “http” & Left(link,INSTR(link,”“”“)-1)

To leave me with just the link name. Splitting the text string into an array may seem strange, but I think it’s the neatest way.

Now that I’ve got all the links I can pull out all the tags, check them against the current list on the website and just display new ones:


// This checks if it’s a tag 

 INSTR(ThisLink,””) > 0

// This checks if it’s a duplicate 

 AND INSTR(TagList,Mid(ThisLink,50)) = 0

// This checks if it’s already on the site 

 AND INSTR(ExisitingLinks,ThisLink) = 0


TagList = TagList & “
” & Mid(ThisLink,50)


But what I can also do is run each proper link against this function:

set xmlhttp = CreateObject(“MSXML2.ServerXMLHTTP”) “GET”, Page, false
xmlhttp.send “”
PageStatus = xmlhttp.status
set xmlhttp = nothing

And check that they work!

I know there are some link checking services out there:

Are the two that jump to mind. However, I find they tend to get a bit confused.

I ran my website through Xenu recently, and it spent the rest of the day trying links. Hundreds of thousands of them. Now I know I’m generous with my links, but not that generous. I think it must have got into a loop and was trying the same page multiple times.

I mean, even running the W3C Link Checker on this Tumblr site now, it seems to check the standard pages and then click into each article and check them as well.

I don’t blame them. There’s no way that they can know that the text of this article will be duplicated on the summary page and on it’s own individual page  – but since I’m getting the data anyway, I can run my own check, and it can do it customised to my exact requirements.

Serving up a page (03/02/2012)

I spent yesterday morning working on a small web coding project. It’s for a relatively low traffic website that isn’t updated very often, but contains a gallery of pictures.

Now, the standard way to do something like this would be to use a database and a server side scripting language; the old:

$var = $_GET[q] ;

$result = mysql_query(“SELECT * FROM Database WHERE ID=’$var’”);

while($row = mysql_fetch_array($result)) { echo $row[‘Content’]; }

I was about to start doing this sort of thing, when I was reminded of something I wrote a few months ago. I had to do the same thing as this, but I didn’t have a web or database server. It was the standard situation: asked the impossible, need it now and, oh, since you ask, the budget is nothing.

The solution was to write some vbscript to render all the pages in advance, and then dump them on a shared drive.

It occurred to me that this system could probably be used elsewhere. For sites that are largely the same for most of the time, this would be much better than querying a database to get the data. It’s like compiling code before releasing.

  1. More secure. There’s no risk of SQL injections, since there is no SQL!
  2. More robust. It’s easier to test the code, since you’ve generated every possible page.
  3. More reliable. It’s also not going to go down if you have server problems.
  4. Portable. Since all your pushing out to the webserver is a bunch of flat html files, you can easily move them around.
  5. Faster. You completely cut out the server side request processing and all the database calls. All that needs to happen is to serve the pages. You can’t make a website any faster.

My old favourite, Jeff Atwood talks about performance being a feature, which is why they put the rendering time on each page of StackOverflow:

Stack Overflow Performance

Obviously, my system won’t work for every type of site: the site would need to have content that is rarely updated.

I have nothing against SQL, but I’ve read about projects like NoSQL without ever using them. It seems more effort than it’s worth given the low compatibility.

It occurs to me that you could probably write something to replace most SQL implementations that simply writes your edits out live to a flat html page. Obviously there’d be some issues about concurrency and locking, but nothing that couldn’t be easily solved. I suspect the biggest challenge would be searching.

Anyway, those are just idle thoughts, and I’m getting ahead of myself a bit. I decided to write my script in vbscript, not because I’m a big fan of it, but because it’s installed on every Windows machine. Jeff Atwood (again, if only he weren’t so right for so much of the time) made a good point about customization:

[…] if I learn to rely on a highly custom desktop, I’ve crippled my ability to work on a stock Windows XP or Win2k3 box. I can certainly bring my favorite apps with me on a USB key, but I also have to spend time setting them up on each box I touch.

Interestingly during the course of writing my script, I learnt a few unexpected things. Firstly, that pressing Ctrl + D in notepad2 duplicates the current line. Which is surprisingly useful. I’ve done this by mistake before, but now I can do it on purpose too.


I also put together this bit to round up a decimal to the nearest whole number:

Int(n) – CBool(CDbl(n) CLng(n))

By default, rounding rounds up or down to the nearest number, and I needed it to always round up.

The second thing was this script to sort an array:

FOR a = UBound(Array) – 1 TO 0 Step -1
FOR j= 0 TO a
IF Array(j)>Array(j+1) THEN
temp = Array(j+1)
Array(j+1) = Array(j)
Array(j) = temp

I have to admit, I pinched this from StackOverflow, although Googling it seems like a standard Bubble sort for Vbscript.

The final thing was this bit of script (courtesy of the scripting guys) to remove a trailing line break from a file:

  IF Right(PicList, 2) = vbCrLf THEN
PicList = Left(PicList, Len(PicList)2)

Thinking about this now, it could be a problem if there are two trailing line breaks, but since I’m providing the input I’m not too worried about this. The thing to do would probably be to remove duplicate line breaks first, and then run this.

Other than that, the code was straightforward:

‘ Code to pre-render website

‘ 02/01/2011

‘ Version 1  SET FSO           = CreateObject(“Scripting.FilesystemObject”)

‘ Open input files and templates

SET Pictures      = FSO.OpenTextFile(“titles.txt”,1)

PicList           = Pictures.ReadAll


SET Template      = FSO.OpenTextFile(“MASTER_picture.html”,1)

PicTemplate       = Template.ReadAll


SET Template      = FSO.OpenTextFile(“MASTER_full.html”,1)

FullPicListing    = Template.ReadAll


SET Template      = FSO.OpenTextFile(“MASTER_gallery.html”,1)

GalleryTemplate   = Template.ReadAll


‘ Check whether there’s a trailing line break and remove it

IF Right(PicList, 2) = vbCrLf THEN

PicList = Left(PicList, Len(PicList)2)


EachPicture       = Split(PicList,vbCrLf)

FinalPic          = ubound(EachPicture) + 1

FinalGallery      = Int(FinalPic/6)CBool(CDbl(FinalPic/6) <> CLng(FinalPic/6))

ArrayIndex        = 1

‘Counter to count each picture in each gallery

GalNumber         = 1

for EACH entry IN EachPicture

Parts           = split(entry,” “)

Number          = Parts(1)

FileName        = “picture” & Number & “.html”

Title           = Parts(0)

NEXTPic         = Number + 1

PreviousPic     = Number – 1

‘ Set the last picture to loop round to the first

IF NEXTPic      = FinalPic + 1 THEN NEXTPic = 1

‘Set the first picture to loop round to the last

IF PreviousPic  = 0 THEN PreviousPic = FinalPic

‘ Divide by 6 and THEN round up regardless of remainder

Gallery         = Int(ArrayIndex/6)CBool(CDbl(ArrayIndex/6) <> CLng(ArrayIndex/6))

NEXTGal         = Gallery + 1

PreviousGal     = Gallery – 1

GalleryName     = “gallery” & Gallery & “.html”

‘ Set the last gallery to loop round to the first

IF NEXTGal      = FinalGallery + 1 THEN NEXTGal = 1

‘Set the first gallery to loop round to the last

IF PreviousGal  = 0 THEN PreviousGal = FinalGallery

‘ Replace the template with information for each picture

PictureFile     = Replace(PicTemplate,“[NUMBER]”,Number)

PictureFile     = Replace(PictureFile,“[TITLE]”,Title)

PictureFile     = Replace(PictureFile,“[PREVIOUS]”,PreviousPic)

PictureFile     = Replace(PictureFile,“[NEXT]”,NEXTPic)

PictureFile     = Replace(PictureFile,“[GALLERY]”,Gallery)

‘ Output the picture file

SET OutputFile  = FSO.OpenTextFile(FileName,2,TRUE,0)

OutputFile.WriteLine PictureFile


‘ If this is a new gallery load the template and start replacing

IF GalNumber    = 1 THEN

GalleryFile   = REPLACE(GalleryTemplate,“[NUMBER]”,Gallery)

GalleryFile   = REPLACE(GalleryFile,“[PREVIOUS]”,PreviousGal)

GalleryFile   = REPLACE(GalleryFile,“[NEXT]”,NEXTGal)


‘ It needs to add the pictures regardless of which gallery file it is

GalleryFile     = REPLACE(GalleryFile,“[“ & GalNumber & “Pic]”,Number)

GalleryFile     = REPLACE(GalleryFile,“[“ & GalNumber & “PicTitle]”,Title)

SET OutputFile  = FSO.OpenTextFile(GalleryName,2,TRUE,0)

OutputFile.WriteLine GalleryFile


IF GalNumber    = 6 THEN

‘Set it to 0 so when the counter adds 1 it goes to 1 to start the loop again

GalNumber     = 0


‘Add one to Gal Number FOR NEXT loop

GalNumber       = GalNumber + 1

ArrayIndex      = ArrayIndex + 1


‘ This is a slightly messy hack to remove the template parts from the final gallery

SET OutputFile    = FSO.OpenTextFile(“gallery” & FinalGallery & “.html”,1)

DO UNTIL OutputFile.AtEndOfStream

strLine         = OutputFile.ReadLine

‘If the line contains a [ THEN it removes it

IF InStr(strLine, “[“) = 0 THEN strNewContents = strNewContents & strLine & vbCrLf



‘ Writes the new final gallery file on top of the old one.

SET OutputFile    = FSO.OpenTextFile(“gallery” & FinalGallery & “.html”,2)

OutputFile.Write strNewContents

‘ Sort the array into alphabetical order FOR the full picture listings page

FOR a = UBound(EachPicture)1 TO 0 Step –1

FOR j= 0 TO a

IF EachPicture(j)>EachPicture(j+1) THEN

temp              = EachPicture(j+1)

EachPicture(j+1)  = EachPicture(j)

EachPicture(j)    = temp




‘ Generate the picture listing data

for EACH entry IN EachPicture

Parts           = split(entry,” “)

PicListingData  = PicListingData & “<A href=”“picture” & Parts(1) & “.html”“>”& Parts(0) &“</a><BR><BR>”


FullPicListing    = REPLACE(FullPicListing, “[PICTURES]”, PicListingData)

SET OutputFile    = FSO.OpenTextFile(“full.html”,2,TRUE,0)

OutputFile.WriteLine FullPicListing


‘Copy Gallery1 file into Gallery because link points to gallery.html

FSO.CopyFile “gallery1.html”, “gallery.html”

wscript.echo “Done”


I’ve pasted it here in full so this page can act as a bit of a code repository. I’ve been very bad at source control in the past.

While looking for a way to post this code so that it would be readable, I came across It’s quite a nice site that converts the code into css (inline or otherwise). Seems to work here, although obviously, I have a proper with my page being so narrow. But maybe that’ll encourage me to shorten my code lines.

Tag Cloud