Posts tagged: html

Reading Schedule Generator

Or: some stuff I worked on over break.

This is a small solution to (some would say) an even smaller problem: I used to ignominiously return unread books to the library, and face new issues of magazines after having only read a few items in the previous one. My to-be-read pile was only getting taller.

I found I was able to read more “reliably” if I had a specific daily page goal for each item. Somehow having an “official” schedule helped me overcome my affliction.

I’ve been doing this for a few years, and have written code to help out. (Certainly there must be a name for the psychological quirk that compels me to “write code to help out”. Let me know if you come across it.)  What follows is my current “solution”: a CGI-backed web form that accepts the schedule parameters for a single reading item (book or magazine) and generates a small HTML calendar schedule that I can print from a web browser, cut out, and use as a bookmark for the item.

This seems conceptually easy, if not trivial, so I imagine similar code is “out there somewhere”, but cursory Googling didn’t turn up anything.

Anyway: the finished product appears like this (specific example is the book Freedom™ by Daniel Suarez):(Not that I recommend this book: it's pretty bad so far.)

Yes, cut on the dotted line. So my goal for today (January 6) is to get up to (or past) page 127. And I should be finished in a couple weeks.

Now I’m not psycho about this: it’s OK to get ahead of the goals if the material is compelling and I have the time. It’s also OK to fall behind if there’s just too much other stuff going on. (However, in my experience, just knowing that I’ve “fallen behind” is just enough motivation to carve out some extra time to catch up later.)

Enough for the mechanics, on to the code. For a long time I ran a Perl script from the command line to generate an HTML schedule as a static file, which I would then open/print in a browser. But over break I decided that it would be (slightly) more flexible to do the whole thing from the browser, using an HTML form to get the schedule parameters, calling a CGI backend to display the result.

The form is here (hosted on my workstation). What it looks like:

It’s a very rudimentary form, with few bells or whistles. Well, OK, one bell: the Javascript jQuery UI datepicker widget for getting the schedule’s start and end dates. I didn’t know nothin’ about jQuery before I did this. (And I only know slightly more now; if you examine the source code for the form, it’s not very complicated.)

So you fill out the form. Using our example (and showing the datepicker in action):

… hit the submit button and the resulting page should produce the appropriate schedule. (I’m pretty sure it would work for you if you want to try it.)

The real work is performed by the Perl CGI script, which relies heavily on the smarts contained in the CGI, Date::Manip, and HTML::Template modules. (What’s left: some date arithmetic that’s only tricky if you’ve done it wrong a few times. I think it handles edge cases and DST changes correctly, although I haven’t checked lately.)  If you’d like to look at the script, the plain-Perl file is here, and the html-prettyprinted version is here. The HTML template used by the script is also important and that’s here.

Website Accessibility

Paul Irish tends to say smart things; he does it again when considering web content accessibility.

As he concludes, accessibility shouldn’t be an opt-in proposition, it should be opt-out, if anything. Browsers should have better accessibility built in; wouldn’t the world be a better place if accessible renderings were more often the default?

multipart/form-data: Gets Me Every Time

Every single time I try to implement file uploads via the web, I forget the ‘enctype’ attribute that needs to be in the form tag in the HTML:

<form enctype="multipart/form-data" method="post" action="/path_to/my_script">

If you forget that like I do, your server side program will receive the filepath information from the ‘file’ input on the form…

<input type="file" name="attachment">

… but it won’t receive the file data itself. I struggle with this every time, thinking something is wrong with the code on server, until it dawns on me. I’m really just writing it here in hopes I never, ever forget again.

To complicate matters, Perl’s CGI module accepts the parameter from the form…

my $attachment = $cgiobject->param('attachment');

…with both values, the file path and the file data itself, stuffed into the same variable (here called $attachment), which coughs you up the file path when used in scalar context…

# prints the local filepath the file was uploaded from
print $attachment;

…and the file data when used in a filehandle context. Here is the piece where I save the file data to a directory on server:

open (UPLOADFILE, "> attachments/$final_filename") or die "$!";
binmode UPLOADFILE;
while(<$attachment>) {
     print UPLOADFILE;
}

Notice we are still just referencing that same $attachment variable which was grabbed from the CGI input. This is hard to wrap your head around at first and frankly I’m not even sure how this magic is accomplished. A scalar variable with two values depending on context is whacky, but it does work.

Panorama theme by Themocracy