Textmate quickie: CSS opacity
November 11th, 2007Opacity using CSS isn’t supported very well in every browser (particular with one Internet “exploration” themed browser). It’s possible to get opacity right if you know the right people, but personally, I can never remember exactly what I need to do to make it work. Tonight, I was about to look it up once again, but I decided to see what Textmate would do if I typed “opacity” and hit tab, the usual bundle activation key. Sure enough, when I hit tab, Textmate responded by giving me this:
opacity: 0.5;
-moz-opacity: 0.5;
filter:alpha(opacity=50);
Not only did Textmate give 3 different options for making opacity work, when I changed the first 0.5 value to something else, the other 2 values changed as well. Textmate to the rescue again!
Textmate word completions or almost Intellisense™
November 10th, 2007At work I use Visual Studio to develop web applications, and I’ve gotten very accustomed to using Intellisense. Perhaps, a little too accustomed. I’ve also been developing with PHP a lot on the side and I usually use Textmate. However, until recently, I hadn’t been using the word completion functionality that Textmate offers for PHP. It’s not exactly Intellisense, but it provides a lot of the same functionality and has really sped up my PHP development time.
There are two types of word completion that Textmate offers for PHP (that I know of). The first type allows you to type a word and then hit a key to scroll through a list of terms match that word. For example, let’s say I have a function in my class called “checkTheFrontDoor”. I don’t feel like typing that function name all the time. In Textmate I can type “$this->c” and then hit the esc key. The first time I hit esc, “$this->c” will change to “$this->checkTheBackDoor”, the name of another function in my class. That’s not what I want. So, I hit esc again. Now Textmate switches the text to “$this->checkTheFrontDoor”. That’s what I want, so I go ahead and keep typing. You can also use word completion to scroll through the names of variables that you have defined and to scroll through built in PHP functions that match the text you have entered.
The other type of word completion that Textmate offers is more similar to Intellisense. Let’s say I was looking for the name of the function that pushes an item onto an array. My guess would be that the function name starts with “array”, so I type “array”. If I just hit the esc key I can scroll through all of the built in functions that start with “array”. There are a lot of them though, so that could be tedious. Instead I can hit alt + esc and get a pop up menu of suggested function names. Even better, when I choose a function name, it will automatically give me a list of parameters that the function accepts. So, for example, if I type “array”, hit alt + esc and then choose “array_push” from the menu, Textmate gives me the following:
array_push(array stack, mixed var, [mixed ...])
Textmate gives me the name of the function and the parameters for the function and, like most bundles, it lets me tab through each parameter as I put in the values. As far as I can tell, Intellisense doesn’t give you the option of filling out the parameters, so, in some ways, Textmate’s word completion offers even more functionality.
Textmate offers word completion for many other languages in addition to PHP. If there’s a bundle for a language it probably has some form of word completion with the same esc and alt + esc key combinations. If you’re using Texmate for development, make sure to check if it has word completion for the language you’re developing with.
Some CakePHP requestAction….action
November 6th, 2007I’ve spent the last few months writing a portfolio system for Columbia College using CakePHP. One of the requirements was a template system that would allow students to choose different templates for their personal sites. I thought it would be a nice feature for users to have a template preview page that allowed them to choose a template from a menu and see what the template would look like with their data.
Initially, I built two separate views. One for the displaying the actual live site, and one for displaying the preview of the site. The two views were nearly identical, aside from a small menu bar at the top of the preview page. I didn’t like the idea that the code was repeated, so I thought that an element might be the solution. However, the templating system required some setup in the controller before the view was actually rendered. This was a problem because the template preview page was not in the same controller as the view for the user’s public page. More repeated code.
I started looking into the requestAction method, but I couldn’t find a whole lot of information about it. Some of what I did find was pretty negative. The manual suggests that one of the uses of requestAction is to retrieve data from another controller. I’m not so sure about using it for that sort of thing. To me, it seems like common data retrieval functions should go in the model. But rendering one action inside of another seemed like the perfect use of requestAction.
To create a dynamic preview page, I created a view with the menu bar that I wanted to appear above the site when it was being previewed. Then, where I wanted the templated page to be rendered I used requestAction to call the action that displayed the public site:
$this->requestAction("/$site_url/$preview_path",
array('template_id' => $template_id));
URLs for the site are structured with the student name and the name of the action being called: /student_name/action_name. Using requestAction I can call those urls, which get handled by the public controller. One caveat is that a view called by requestAction will render without a layout. In this case, that was exactly what I wanted, because the preview page was providing the layout for view.
But how does controller choose which template to render? That’s where the second parameter to requestAction comes in. The preview controller sets a template id based on the template the student chooses from the preview menu. The public controller also uses a template id, but that template id is stored as part of the user’s profile. To get the public controller to use the template id from the preview controller, I needed to pass it on somehow. The second parameter to requestAction allows you to pass an array of extra parameters on to the controller being called. Those extra parameters show up under $this->params in the controller being called. On the preview page I pass on a parameter called template_id. In the public controller I check for that parameter and if it’s not present I default to the user’s selected template:
$template_id = isset($this->params['template_id']) ?
$this->params['template_id'] :
$this->user['Options']['template_id'];
Aside from the template id change, the public controller behaves like it normally would, allowing the user to see a templated preview of their site.
So far, I haven’t seen any other practical uses for requestAction that couldn’t be better addressed by other features of CakePHP, but I’m curious about what other reasons people can find to use it.
Freedom of regular expression
November 3rd, 2007The concept of regular expressions is one of those computer science ideas that still feels like magic to me. You take what looks like a string of nonsense, feed it into a computer and, suddenly, strange and wonderful things begin to happen. I still feel a sense of fascination when I come up with a regular expression that gives me exactly what I wanted. Does that mean I’m not experienced enough yet?
Tonight I wrote this magic spell:
/{\s*(\w+)\.*(\w*)\s*([\w=\[\]"'_-\s]*)}/
What is it used for? Well, I’m rewriting a simple template system for a CakePHP site and I wanted to do it the right way with regular expressions this time instead of the original find and replace method I used the first time through.
For example, if a user on the site entered a template tag like this:
{Collection.images ul_attributes[id="images"]}
My template parser would use the regular expression to find that tag and replace it with this:
<ul id="images">
<li><img src="..." /></li>
<li><img src="..." /></li>
</ul>
I made the expression overly complex to account for linebreaks and other extra spacing that the user might add when entering the keys. And it works! That’s the exciting part. Every time I get a regular expression right I feel like this
Textmate Hyperlink Helper Menu
October 30th, 2007The Hyperlink Helper menu is another fun bundle that I had never noticed in TextMate.
Ctrl + Shift + L - Wraps the selection in an anchor tag with a default href attribute, pretty simple.
The real interesting stuff is the Google and Yahoo web lookups:
Ctrl + Shift + Apple + L - Performs a Google search for the selection and links to the first result found
Even better:
Ctrl + Shift + Y - Pops up a menu with 4 different Yahoo search options. Then performs your selected search and pops up a menu with the option to link to any of the top 10 search results.
Be wary of JavaScript reserved words and globals
October 29th, 2007If you’re writing some JavaScript and suddenly it stops working without any warnings or errors, make sure you’re not stepping on any reserved words or global objects. Tonight, I had a script that was working perfectly in Firefox, but as soon as I tested it in Safari it completely failed. It took me a little while to realize that I had named a property on an object “default”. Stupid mistake, but Firefox didn’t warn me about it and instead happily ran the script. I guess it goes to show that even standards compliant browsers don’t always behave the way you expect them to.
The Core JavaScript Reference is a good place to start if you’re looking for a list of keywords. Particularly the sections on Global Objects and Reserved Words. This list also wrapped many of them up nicely.
Align Assignments in TextMate
October 27th, 2007This is a cool feature that I didn’t realize TextMate had until today. Say you have a series of assigmnents like this:
var administrator = "Dave";
var guest = "Matt";
var blocked = "Tim";And you want to have all of the assignments aligned. Select the code and hit Apple + Option + ]. It will automatically align the statements like this:
var administrator = "Dave";
var guest = "Matt";
var blocked = "Tim";
I love you TextMate.
JavaScript Mouse Tracker
October 20th, 2007A while ago, I was thinking about software programs like Camtasia that allow you capture a user’s activity as they work on a computer. Screen capturing programs are useful for usability studies because they allow you play back a user’s activity later on when you are evaluating their performance on a set of tasks. I started to wonder if their were any options for capturing a user’s activity remotely through the browser. When I didn’t find anything I thought was compelling, I decided to try writing my own.
What I came up with was a JavaScript class I called MouseMovie that could be used to record the mouse movements a user made while on a page. The first draft is pretty rough, but it will allow you to create a new mouse tracker, start tracking the mouse movements a user makes on a page and then stop the tracker. Once data has been captured by the tacker, you can use the mouse timeline to replay the user’s movements or trace the path of the user’s movements.
/* Create a new tracker,
start it and stop it and then use
the timeline to animate
and trace the mouse path. */
var MyTracker = new MouseMovie.Tracker();
MyTracker.start();
MyTracker.stop();
MouseMovie.Animate({TimeLine : MyTracker.TimeLine});
MouseMovie.Trace(MyTracker.TimeLine);
Currently, there is no way to persist the user’s movements to a file or database, but I’d like to make it possible to store the movements and play them back at another time. A simple demo of the mouse tracker can be found here