potatoDie Web Development Scrapbook
Assorted thoughts about web development
To hell with SEO-motivated content
It is ridiculous to write website content motivated by search engine optimization (SEO) issues. The motivation to inform, interest or convince people is enough! Lacking this motivation, why write at all?
The search engine makers have to sort it out for us. How can we help?
At first I thought social media’s Likes and Thumb-up‘s could help search engines a bit. Then I imagined, if SE would pay attention to these, soon Like Farms would emerge, providing Likes for money. People would earn a living ‘Liking’ webpages, clicking all day cheerfully on selected buttons…
Maybe we can help by not confusing the search engine and just write like we normally would. Then the search engines could come up with a kind of Turing test, to separate the engine pleasers to the righteous men. Without that confusion, they could evolve much faster!
Look-alike input and link elements
Problem: same style for input and link elements does not work
Forms often use input elements (<input>) and link elements (<a>) side by side. For example, to submit a form you’d use
<input type="submit" value="Submit">
and to cancel
<a href="page-you-come-from.html">Cancel</a>.
It turns out it’s not so easy to have the two elements look the same. You might be tempted to use two input elements or two link elements instead of one of both. That would however mean your page would require javascript to work. Well, I sold my soul to Progressive Enhancement, so I could never do that.
Apply the same style to both
To have <input> and <a> look alike you could style both elements with:
.button
{
background-color:#d8d2d0;
border-width:0px;
padding:4px;
}
And it would look like this:
Unfortunately, the ‘Cancel’ button is a little smaller in height than the other one. A minor issue perhaps, but for a professional site it’s unacceptable.
A small improvement
A recommended method is to add
display: inline-block
to the style for the button class. I agree, makes sense. Now I’ve got:
Instead of being 2 pixels to small, it’s now 1 pixel to big. So hurrah!
Progressive enhancement
So I decided people without javascript have to deal with that pixel extra. To solve the problem in the general case I just transform the link element into a button (using javascript).
And here’s the code that does that (using jQuery to save a line of code or two).
$('form a.button').toButton();
$.fn.toButton = function()
{
var url = $(this).attr('href'); // remember url
// create a button
var inp = document.createElement ('input');
$(inp).attr ( { type : 'button', value : this.html(), class : 'button' }).click ( function () {
// Direct to url. I use ajax here
sendRequest ( url, updateWerkblad );
});
// replace it
$(this).replaceWith( inp );
}
I hope you like it!
Hiding elements from users using javascript, with hidden hiding
document.write() does not belong to my favourite javascript functions, but sometimes it is useful.
Suppose you have an element on a webpage that’s just there for fallback for users without javascript. For example a form that submits itself at onchange or onclick events of it’s elements.
Removing the button after the page is loaded (which is easy: element.style.display=’none’) may cause noise on the page. It’s there, then it’s gone, maybe causing containers to be redrawn too.
Changing the rules of a CSS file is cumbersome (http://www.quirksmode.org/dom/changess.html).
So in this case I use document.write() to ‘manually’ add a style for javascript users:
document.write("<style>#submit{display:none}</style>");
Take care this script is run as early as possible. Writing a link to a separate CSS file is also possible, of course.
jQuery
Using the jQuery ready handler, the hiding of the elements also seems to be in time (you won’t see it).
Combining row striping and jQuery UI Sortable plugin
Using row striping to improve the display of a list of items, and combining it with the jQuery UI Sortable plugin, I noticed a little confusion when adjusting of the alternating row striping took place immediately after dropping the item. A dark-coloured row may change to a lighter shade, so you may doubt the operation succeeded.
You could decide to forget about readjusting the row colouring, but that would look clumsy: the striping becomes chaotic. In that case better to not use row striping at all.
I found that using the option revert helps. It defines a small animation (I chose 200 ms) that gives enough reassurance the operation succeeded.
Automating setup webdevelopment projects
I’m experimenting with shell scripts to set up a project’s directory structure, config files, database etc. Batch scripts in the command shell also run python and php scripts. Something like this:
rem echo off set p=%1 python pythons/makedirs.py %p% php phps/createdb.php %p%
It takes one or two actions and I have a running website template.
At that point a graphical tool is used to shape the project further (database/information design). This tool is the CMS itself, in developer mode.
jQuery: what’s in a name?
Suddenly the meaning of the name jQuery struck me: The function jQuery – alias $ – queries the HTML structure for elements matching a selector.
The result of the query contains the matching elements, wrapped in an object that allows to perform methods to these elements. It is easy to extend this wrapper with your own functionality, by programming plug-ins.
PHP scope trouble with require_once
Better not use include_once or require_once inside a function: scope trouble! Use include or require instead.
Locating directories using cron jobs
My php scripts orient themselves on the server most often with $_SERVER['DOCUMENT_ROOT']. Having established that variable, it’s easy for the script to find the include directory, for example.
When you run a script as a cron job it may not work as expected. There’s no web server in this scenario, and the array $_SERVER differs accordingly. Printing the values out, e.g.
<?php print_r ( $_SERVER ); ?>
will make it all clear.
In my case I decided to use the HOME and LOGNAME variables when using cron, so now the script knows how to find it’s way no matter how it is called.
define ( "CRON", empty ( $_SERVER['DOCUMENT_ROOT'] ) ? TRUE : FALSE ); define ( "DOC_ROOT", CRON ? $_SERVER['HOME'] . "/" . $_SERVER['LOGNAME'] : $_SERVER['DOCUMENT_ROOT'] );
SCRIPT_FILENAME, which is the same in both scenarios is also a good candidate to work with.
Dealing with outdated browsers
Here’s my strategy against old, ‘bad’ browsers.
I build websites for modern web-standards-compliant browsers. Other browsers, that are used a lot (at this moment IE7 and 8), will render the site near-perfect. They may miss a rounded corner or drop shadow, but have complete functionality.
Optional extra work
If the client so wishes, I will add code, graphics or whatever it takes, to fix problems with IE that come from the browser not understanding CSS3 or other quirks. This is extra work, and also costs extra.
Why not serve any browser?
What’s wrong with the principle ‘render the site perfectly in any frequently used browser’? Well, it takes a lot of time to cater the special needs of specific, old browsers. This time can be better spent improving the site for everyone, not just helpless/conservative IE-users.
Sketchup layer concept
Sketchup is an easy-to-use 3D modelling tool. At least at first. Once you start to try to work accurately, like designing your new bathroom, things get mixed up. Especially the layer concept is odd. It is important to get this right!
- Always work in layer0.
- Group entities in groups or components.
- Organize by associating grouped entities to layers.


