Archive for June, 2007

The wonders of mod_rewrite

When I wrote about tidying dynamic URL’s a little while back, I had no inkling that that would be a second part to the tale. My discovery of mod_rewrite, an Apache module that facilitates URL translation. The effect is that one URL is presented to the user in the browser address bar, and the exact same URL is also seen by search engines, while another is passed to the server for processing. It might sound like subterfuge but it works very well once you manage to get it set up properly. The web host for my hillwalking blog/photo gallery has everything configured such it is ready to go but the same did not apply to the offline Apache 2.2.x server that I have going on my own Windows XP box. There were two parts to getting it working there:

  1. Activating mod-rewrite on the server: this is as easy as uncommenting a line in the httpd.conf file for the site (the line in question is: LoadModule rewrite_module modules/mod_rewrite.so).
  2. Ensuring that the .htaccess file in the root of the web server directory is active. You need to set the values of the AllowOverride directives for the server root and CGI directories to All so that .htaccess is active. Not doing it for the latter will result in the an error beginning with the following: Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden. Having Allow from All set for the required directories is another option to consider when you see errors like that.

Once you have got the above sorted, adding this line to .htaccess: RewriteEngine On. Preceding it with an Options directive to ensure that FollowSymLinks and SymLinksIfOwnerMatch are switched on does no harm at all and may even be needed to get things running. That done, you can set about putting mod_write to work with lines like this:

RewriteRule ^pages/(.*)/?$ pages.php?query=$1

The effect of this is to take http://www.website.com/pages/input and convert it into a form for action by the server; in this case, that is http://www.website.com/pages.php?query=input. Anything contained by a bracket is assigned to the value of a system-named variable. If you have several bracketed sections, they are assigned to sequentially numbered variables as follows: $1 for the first, $2 for the second and so on. It’s all good stuff when you get it going and not only does it make things look much neater but it also possesses an advantage when it comes to future-proofing too. Web addresses can be kept constant over time, even if things change behind the scenes. It means that returning visitors will find what they saw the last time that they visited and surely must ensure good karma in eyes of those all important search engines.

Forcing FAVICON.ICO to appear on the browser address bar

Here’s a piece of code that should really be unnecessary when you put the favico.ico into the root of your website directory:

<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />

The favico.ico should automatically appear there and in your browser bookmarks (favourites in IE) but there are occasions when the above has to sit in the header section of your web pages. I know because I am doing it for this blog.

More useful WordPress plug-ins

Apart from a widget that puts a login form onto a blog sidebar, I am not really on the lookout for WordPress plug-ins but here are two that came to my attention recently. I have found them to be useful; maybe you will too.

The first is WordPress Admin Themer. This allows you to store wp-admin.css in your blog’s theme folder, out of harm’s way from future upgrade cycles. A neater way of otherwise storing your customisations of admin pages – I keep changing the logout destination to the front page of my blogs – would be a bonus but the style plug-in is a good step forward.

One use to which I was going to put WordPress Admin Themer was to hide some elements of the WordPress dashboard page but I happened accross another plug-in that does just this kind of thing: Dashboard Editor. Activating this gets you an extra admin page where you can select the components that you want to see using the tick (check) boxes. You can even take things further by having your very own dashboard instead of what WordPress offers or by activating widgets for using with your dashboard. It’s all good stuff and I have got rid of extraneous pieces such as Planet News and the getting started section (I have using WordPress long enough that I should know my way around by now…).

IE6 and JavaScript performance

Having been exposed to an application at work that uses a lot of JavaScript, I fully appreciate what some mean when they talk about IE6′s inefficient handling of JavaScript. After seeing a web page taking an age to reload and your CPU taking a hammering because of JavaScript processing, the penny does tend to drop… Needless to say, this very much impacts the world of AJAX-driven web applications with their heavy dependence of client-side JavaScript. While IE7 does come to the rescue, there remain plenty of IE6 users still out there and this is reflect in website statistics. This reflects a certain level of inertia in the browser market that not only afflicts the uptake of IE7 but also the likes of Mozilla, Opera and Safari. It also means that anyone developing AJAX applications very much needs to continue testing in IE6, especially if the product of their labours is for wider public use. An example of such an application is Zimbra, an open source web application for messaging and collaboration, and the people behind it have generously share the results of their browser performance benchmarking. They did comparisons of IE6 vs. IE7 and Firefox 2 vs. IE7. IE6 easily came out as the worst in these while Firefox 2 was the best. I suppose that the next question to be asked centres around the type of code that is processed inefficiently by IE6. I wouldn’t be at all surprised if a list emerged but here’s one: using Microsoft’s proprietary innerHTML object to update the DOM for a web page format. Having a quick trawl on Google, this came up for mention as a cause of memory leaks. It is also a Microsoft innovation that never got taken up by those overseeing web standards, hardly a surprise since a spot of DOM scripting achieves the same end. It may be faster to code than any alternatives, and it does have some support from other browsers, but it does seem to have got a bad name and so should be avoided if possible. That said, it would be interesting to see a performance comparsion between innerHTML and DOM methods in IE6.

A tale of two reviews

Olympus E-410

I have two very different reviews of the newly launched Olympus E-410 DSLR in Which Digital Camera? and Practical Photography, respectively. The review in the former was a positive affair, though it was a first look at the camera, but impression formed by the latter reviewer was lukewarm in nature. The camera features a live electronic viewer on its back, a carry over from digital compacts and a feature that I may never use. While that might be the unique selling point for the camera, good image quality and the fact that it possesses a cleaning mechanism for its sensor are of more interest to me. Ironically, the Practical Photography review spent most of its time talking about the very feature of the camera that interests me the least with only a scant mention of quality; to be frank, I didn’t find it a very useful appraisal even if the electronic viewfinder may not be all that it’s cracked up to be and it’s picture quality and camera handling that ultimately matter to the photography enthusiast. In contrast, Which Digital Camera? seemed to give a more rounded view and proved to be of more interest and I’d be interested to see what the likes of Photography Monthly and Amateur Photographer might have to say. I also shall be awaiting the Which Digital Camera? appraisal of Ricoh’s Caplio GX100 in their next issue.

WARNING: The quoted string currently being processed has become more than 262 characters long…

This is a SAS error that can be seen from time to time:

WARNING: The quoted string currently being processed has become more than 262 characters long. You may have unbalanced quotation marks.

In the days prior to SAS version 8, this was something that needed to be immediately corrected. In these days of SAS character variables extending beyond 200 characters in length, it becomes a potential millstone around a SAS programmer’s neck. If you run a piece of code like this:

data _null_;

x="[string with more than 262 characters (putting the actual string in wrecks the appearance of the blog)]";

run;

What you get back is the warning message at the heart of the matter. The code is legitimate and works fine but the spurious error is returned because SAS hasn’t found a closing quote by the required position and the 262 character limit is a hard constraint that cannot be extended. There is another way though: the new QUOTELENMAX option in SAS9. Setting it as follows removes the messages in most situations (yes, I did find one where it didn’t play ball):

options noquotelenmax;

This does however beg the question as to how you check for unbalanced quotes in SAS logs these days; clearly, looking for a closing quote is an outmoded approach. Thanks to code highlighting, it is far easier to pick them out before the code gets submitted. The other question that arises is why you would cause this to happen anyway but there are occasions where you assign the value of a macro variable to a data set one and the string is longer than the limit set by SAS. Here’s some example code:

data _null_;

length y $400;

y=repeat("f",400);

call symput("y",y);

run;

data _null_;

x="&y";

run;

My own weakness is where I use PROC SQL to combine strings into a macro variable, a lazy man’s method of combining all distinct values for a variable into a delimited list like this:

proc sql noprint;

select distinct compress(string_var) into :vals separated by " " from dataset;

quit;

Of course, creating a long delimited string using the CATX (new to SAS9) function avoids the whole situation and there are other means but there may be occasions, like the use of system macro variables, where it is unavoidable and NOQUOTELENMAX makes a much better impression when these arise.

  • As is commonly the case with places like these, all the views that you find expressed on here in postings and articles are mine alone and not those of any organisation with which I have any association, through work or otherwise. With regards to any comments left on the site, I reserve the right to reject any that are inappropriate. Otherwise, whatever is said is the sole responsibility of whoever is leaving the comment.