Sunday, May 25, 2008

PHP and AJAX *head desk*

So, Thursday afternoon I broke my brain for the weekend trying to figure out why the heck a script that is working perfectly well on one server isn't working right on another server. Day one was wasted trying to figure out HOW to figure out what the heck was going on. The logs told me nothing. The page itself was not giving any hints. Since the whole thing was happening in AJAX land, behind the scenes and without giving any useful output to the browser, I couldn't use debugging tricks like echo and print_r to figure out what was going on with my variables. This morning, however, my brain was in better gear than it was Thursday afternoon, so I started the day off by actually doing something useful.

When you need a script to give you useful information in the browser, and the page in question is using AJAX to send information (but not, at the moment, receive information), then (DUH!) use AJAX to give you the information you need!!!

In my case I had a handy editor box in which to plunk the response text from the AJAX request.

xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4) {

document.forms["editorbox"].editorBox.value = xmlhttp.responseText;
}
}

At one point, I used alert(xmlhttp.responseText) instead of the editorbox, but that wasn't as useful because the alert box doesn't let you select and copy stuff if you need it. Also, my editorbox had a handy-dandy scroll bar, and the errors coming out of my responseText were numerous.

In order to make the responseText useful, you may want to echo out certain variables and then exit; so that the info you want -- and only the info you want -- will show up where you need it.

Now, as to what was actually wrong with the script I was messing with today... It appears that a difference in php.ini files was my problem. In the version of the script that was NOT working, all the quotes were getting escaped as they got soaked up into the PHP script. When I then tried to dom->loadXML($myXML) the script was complaining that my XML was no good. Well, of course it's no good, there's all these darned escape characters before the quotes!

I don't want to change the php.ini on the server, so I have to get rid of those escapes some other way. preg_replace to the rescue!


$pat = '/\\\"/';
$rep = "'";
$myXML = preg_replace($pat, $rep, $myXML);


All better. :)

Tuesday, May 13, 2008

Good User Interfaces

I have a friend who loves to complain about the user interfaces in current technology. He has a million great things to say about how things should be made, and he says them with a cantankerous grumble. I adore him for so many reasons, but this is definitely one of them. He opens my eyes again and again to my own tendency to develop for geeks like me instead of the person on the street who really should be getting a better thought out and better built product. Because of him, I also notice even more when someone does something really right.

A couple of weeks ago he and I were in an elevator and he hit the wrong button by accident. He grumbled and hit the correct button and then said, "You know, if elevators were made correctly, I'd be able to cancel that wrong choice. I should be able to hit that button again and make it turn off."

Today, when I got into the elevator at work, someone else got in, pressed the wrong button, noticed the mistake and pressed the button again to cancel the request. Then they pressed the floor they really wanted. Oo! I was so excited I had to twitter it right there in the elevator.

It turns out that all new Mitsubishi elevators have that functionality. Way to go Mitsubishi.

Another one of my friend's pet peeves is that you have to save files. Why should you have to do an action to save a file? It should be automatic, right? Why would I create a file if I didn't want to save it? Well, it's getting to be automatic in some places like Google Docs for instance. Well, today I found another really cool app that deals with the saving thing right along with at least a dozen other major UI annoyances.

Skitch is unfortunately a Mac only application and it's still in beta, but it looks absolutely awesome. They get so many things right. They have a great way to share things, to snap screenshots, to draw and manipulate images, and you don't have to save your file from a menu or a keystroke. You can just drag it to where you want it to live, or drag it to an email to share it. Very, very nice.

Monday, May 12, 2008

Having Trouble Importing Drupal Translation Packs?

OMG I just spent way too long pulling my hair out over the Drupal 6 translation import feature. To put it simply, the handbook and help information is very UNCLEAR about what you are supposed to do.

The instructions say to download the translation pack into your install directory and unzip it. So, if, like me, you don't have access to the server that will allow you to unzip a folder on the server, logic says that you should be able to unzip the folder on your own machine and simply ftp the folder into place, right? Wrong. Well, at least sort of wrong.

Let's say you have the he-6.x-1.0 translation pack. You've unzipped it, and now it's sitting on your PC's desktop. You want to move it to your server. DO NOT copy that whole folder over to the server so that you end up with something like /webroot/drupal/he-6.x-10 on your server.

What you DO want to do is copy the CONTENTS of he-6.x-10 over onto the server so that the internal directory structures plop into place inside the existing directory structure in drupal. That way you will have something like /webroot/drupal/modules/aggregator/translations/modules-aggregator.he.po and so forth.

As you can see here, each directory that has translations (modules, themes, etc. anything that has t() strings, really) gets it own translations directory and language po files go in there.

The easiest way to get all of those files to plonk into the right place is, in fact, to un-zip the file insitu at your server rather than trying to ftp the files over post-expansion.

Thursday, May 1, 2008

Interesting tidbit about PHP objects

I'm doing some XML stuff right now, using SimpleXML in PHP. One of the element groups I need to create is a list of descriptions in different languages. My original attempt looked like this:

$descriptions = array(
'en' => 'An awsome app.',
'es' => 'Una aplicacion chevere.',
'he' => 'אפליקציה מעולה',
);

foreach($descriptions as $loc => $desc) {
$d->addChild('description', $desc);
$d->description->addAttribute('locale', $loc);
}
echo $xml_post->asXML();


But that gave me an error:
Warning: SimpleXMLElement::addAttribute() [function.SimpleXMLElement-addAttribute]: Attribute already exists in...


When I looked at the code, the attribute was only getting plunked into the first <description> tag. The PHP engine thought that each time I went through the loop I was talking about the same $d->description when I asked it to stick a locale attribute in there. Weird. I expected the object to be treated like any other variable and get treated as a fresh thing. Nope.

If you put

echo $d->description . "<br />"

after the addChild() above, you'll see that it echoes out

an awesome app.
an awesome app.


If, however you change that block of code to

foreach($descriptions as $loc => $desc) {
$tag = $d->addChild('description', $desc);
echo $tag . "<br />";
}

you'll see that $tag prints out the correct description line for that pass through the loop:

An awsome app.
Una aplicacion chevere.
אפליקציה מעולה


So, the correct code to create the XML I want is

$descriptions = array(
'en' => 'An awsome app.',
'es' => 'Una aplicacion chevere.',
'he' => 'אפליקציה מעולה',
);
foreach($descriptions as $loc => $desc) {
$tag = $d->addChild('description', $desc);
$tag->addAttribute('locale', $loc);
}
echo $xml_post->asXML();


And then the XML comes out right.

<description locale="en">An awsome app.</description>
<description locale="es">Una aplicacion chevere.</description>
<description locale="he">אפליקציהמעולה</description>