Create an XSL stylesheet for your RSS or Atom feeds

Internet Explorer 6 and, curiously enough, Google’s Chrome browser, don’t display RSS or Atom feeds in a particularly helpful manner. IE6 displays neatly-formatted XML, with color-coding and indentation, whereas Chrome displays the text node of all the XML tags without so much as a linebreak:

Slashdot's RSS feed in IE6 and Chrome, respectively
Slashdot's RSS feed in IE6 and Chrome, respectively

Either way is completely intimidating to an RSS novice. Fortunately, we can change that.
Continue reading Create an XSL stylesheet for your RSS or Atom feeds

Javascript textarea counter

I’ve been thinking more about the textarea counter issue that I mentioned in my previous post (“Users Paste Differently“).

First of all, I noticed that some of the textarea counter scripts date back to at least 2000, so this has been a problem that developers have been looking to solve for 8 years. I checked the HTML 5 specification and found that in HTML 5, the textarea element has a maxlength attribute. Presumably user agents will build in the most elegant solution.

But what is the current most elegant solution? Continue reading Javascript textarea counter

Users Paste Differently

Paste
Paste!
I’ve been using a relatively generic Javascript textarea counter for several years to restrict the input length on form textareas. I’m not sure where the specific version I’m using came from, but you can find dozens like it on Google.

Almost all of them rely on the onKeyDown and onKeyUp events to trigger the script. However, some users still manage to submit text that exceeded the limits, even though the application required Javascript. I could not for the life of me reproduce this issue…until today.
Continue reading Users Paste Differently

Selecting the newest row in one-to-many on mySQL

This one was quite a sticky wicket. So what if you have two tables in mySQL, with a one-to-many relationship (say a forum and comments in that forum), and each of the comments is dated. Now let’s say you want a result set containing each forum’s name, and with it the text of the newest comment in that forum.

The obvious way to do this is with a subselect, which mySQL doesn’t have. So how does one do it?

At first I thought that it might be impossible, but I have figured out the answer:

SELECT f.forum_id,
       max(c.created_on) as last_date,
       c2.created_on as created_on,
       c2.text
FROM   forum f
       LEFT JOIN comment c ON (c.forum_id = f.forum_id)
       LEFT JOIN comment c2 ON (f.forum_id = c2.forum_id) 
GROUP BY f.forum_id, c2.comment_id
HAVING created_on = last_date OR last_date IS NULL;

See, it’s pretty clever actually, though it leans on the “HAVING” option, which is sort of crappy. The trick is to join the comment table with the forum table twice. One of those joins gets grouped by forum id so that you can use the max function on it. The other doesn’t get grouped (by adding its primary key to the group by clause) so that you can still pull data out of it. Then you use the having clause to find only the row that has the max date.

I am also accepting values with a max value of NULL so that if a forum has no comments, it still comes back in the results.

Hope this helps someone, somewhere.
Happy Hacking

New Project, New Codebase, Urgent Timeline

I landed a new project about 5 days ago, and it had a 21 day timeline when I landed it. I’m the only developer on this project, but I do have a designer and, I’m going to recruit a tester as well. The money looks good for it, and the “client” is actually _another_ project manager who sits between us and the actual client. You may have remembered me bitching a lot about my last project (which turned into a horror show)

The idea is that I have walked away with several lessons from that, and that this project will be shorter and more lucrative (both!) as well as more fun to work on. I’m pretty happy with it so far, having finally found a place where inheritance was _really_ useful in site, rather than something I just sort of forced things to use for no good reason (other than a desire to be programming OO)

The codebase I inherited was, for a wonder, not a train-wreck (something that I was getting really sick of) Though I can see why they pulled the previous developer, based on timeline. (I would say he was about 10% done at the halfway mark on the schedual.) He does a lot of things diffrently from the way I would do them, but I can (almost) always repect his design choices while disagreeing.

I also got a chance to write a cool little 3 line javascript “form extender”. I have done this before in _much_ more complmicated ways, but I think I finally figured out the trick to it. Hopefully I will post a how-to as another post soon.

Weird little MySQL error.

So I just moved some code onto a new server, and I’m suddenly getting the warning:

mysql_query(): 14 is not a valid MySQL-Link resource in <bla bla bal> on line 47

A few other people seem to have gotten this error, but no one has posted a solution. (though one guy oh-so-annoyingly posted “I figured it out, so never mind” … Grrr. I mean, if you’re going to post a question, the answer should be in that thread if you ever figure it out….

So as soon as I figure out the answer I’m going to post it here.

I’m back with the solution:

I got clued onto it from this page: http://bytes.com/forum/thread638479.html . The error is coming because mysql_close was being called by the destructor, and because I was in safe mode the same MySQL resource was being used for each instance. What threw me even more though was that the destructor was being called at all, because I thought I only _had_ one instance. Turns out that there is a spot in my code where I (accidentaly) passed my DB object by value rather than refrence. This made a new copy of the object, which ran mysql_connect again, because it was in safe mode it returened the _same_ refrence. Then the object got unloaded, the destructor ran and closed the refrence, even though there was another instance of the object out there still using the same refrence.

Icky!

javascript’s parseInt is pretty evil

Javascript uses the + symbol for both addition and concatenation. This means that if you want to add a numeric value to data pulled from a user, you need to cast it to being a numeric type, like for instance an Int. Makes sense, so I use the parseInt function to cast with. OK, that’s fine so here is the kicker, if you pass it “09” it generates the value 0, not 9.

Hrmm, well that’s odd. If you pass in “9” it returns 9, but if you pass in “09” you get 0. I’m lucky I caught that in testing. It turns out that if you lead with a 0 then parseInt interprates as the value as an octal number. There is a way to deal with it though, you can pass in a second variable telling it what base the numbers it should be reading are.

So really you want parseInt(var, 10) not parseInt(var)

Testing Tools

A couple of useful testing tools I thought I’d share:

The latter seems a little buggy, but still easier to use than removing and installing different Flash versions yourself.

Brochure Ape 3.0 (alpha)

Over the Last several days, have been pounding away on a CMS that really takes it’s inspiration from some of the work that Chris did for U-Penn. (It is also partially inspired by cake, and by joomla.) The idea is for the app to be as easy to install and use as is humanly possible. At the same time I expect that some more impressive things will need to be done by more advanced users, so I have sub-divided usage patterns out into 5 levels.

Installation: I’m hoping to get this as simple as possible. I took the time to write up a custom script “installer_helper.php” that drags the user kicking and screaming through the installation process. Hopefully this is enough, though a few steps still seem to hard. (Rather horrifically, the first one is the worst.)

Publisher: Hopefully this will be so easy that an ape could do it. You can either be logged in as an admin, or visiting the page. If you are logged in and visit a page that doesn’t exsist, you get the option to create the page, by selecting from a list of templates. The new page is automatically added to the master navigation. Each of the templates has areas of text, Images, and other sundry that can be edited by clicking on the little “edit” button next to them. Publishers will never need to touch the web server, or HTML.

Designer: New templates useing the smarty mark-up rules. Their are a few additional calls that can be made to put in editable fields, but for the most part it just straight HTML. The new template is simply deposited in the “view” directory, and then becomes an avalible option for the Publishers. Javascript, Images and CSS can all be put in their respective directories in “webroot”

Developer: If you need to add some actual functionality to the site, Brochure Ape can act as a rough and ready framework as well. Custom PHP code can be written, and put in files in the “controler” directory. At any point if a page is created that matches the name of a controller, it will run both the CMS code, and the controler code. There is also a pretty cool table-object that can be used to deal with specific database tables.

Extender: The ultimate idea is for the core code to be broken out into modules, which have been divided up sanely. Something a little bit more like a micro-kernal approch. At this point it’s just not true, and the extender roll would be a hard and unsupported one. I do however intend to keep on cleaning this up.