Ethan's blog

Fixing Textmate's PHP Commands with MacPorts PHP

Ethan's picture

For anyone else who's having trouble with include path errors when trying to run PHP-based bundle commands in Textmate like this one:

PHP Warning: require(/lib/beautify.php): failed to open stream: No such file or directory in /private/tmp/temp_textmate.4tD2ED on line 19

It looks like the problem has to do with php.ini configuration settings that ship with MacPorts (may be the production sample ini file, in particular). In order to environment variables to populate the $_ENV global that Textmate uses for settings, etc, be sure you've got the letter "E" at the front of the "variables_order" setting value, like this:

variables_order = "EGPCS"

Reluctant hat-tip to an article on Experts Exchange for this one.

Today I learned: about max() array magic

Ethan's picture

Today I learned:

  1. That there's always more tricks in the PHP bag
  2. That the max() command will return the element with the highest-value key when returned an associative array. So, given $a = array(1 => "red", 5 => "green", 10 => "blue");, max($a) will return "blue".

Symfony and svn:externals... super-slick the easy way

Ethan's picture

(If you already know about Symfony and just want to use svn:externals to install it, you might want to skip here)

We've begun using the Symfony MVC framework for some small projects and really getting into it. If you're not familiar with MVC frameworks, then...well, you probably are more familiar than you know: the MVC patternis the design pattern at the heart of well-known development frameworks like Rails and Django. PHP has its own varieties of MVC frameworks, and Symfony ranks along with other popular options such as CakePHP and Code Igniter.

Like most MVC frameworks, a large part of what makes Symfony such a powerful tool is it's meticulously organized codebase. Placement of each piece of the stack is exquisitely thought-out, providing the foundation for an extensive plugin-architecture capable of interfacing with and incorporating numerous third-party libraries and tools. Like any intricate protocol, however, the organization of Symfony's code can be somewhat daunting and labyrinthine, contributing to its fairly steep learning curve.

Luckily there are some great tutorials and references out there, including the freely available version of the commercially published Symfony Book, the Getting Started Guide and a bunch more.

Drupal Internationalization: Part I, and introduction

Ethan's picture

We've recently begun putting together the infrastructure for a number of upcoming projects which will organize people around the world toward some pretty powerful, ambitious goals. While the details of those sites are still in the works, working with Drupal to create multi-language sites has been a great experience involving a great deal of learning. This is the first of a two part series covering how Drupal works with multiple languages and the best practices/tricks of the trade for making the most of the Drupal Local, i18n and L10n systems.

What the h3l is this i18n/L10n c2p all about, anyway?

Don’t be scared by the geekspeak! “i18n” and “L10n” are just abbreviations for “internationalization” and “localization”, the engineering methodologies used to create software packages and websites which can be used by speakers of different languages. i18n is the process of engineering an application so that it can be adapted for use by speakers of different languages or in different regions without needing major modifications and L10n is the related step of providing conversions between languages, date formats, etc. so the software or site can be accessed in any particular language (see the Wikipedia article on i18n and L10n for more).

Setting up Eclipse to Debug Drupal with XDebug

Ethan's picture

Every 6 months or so I take a stab at setting up line-level, breakpoint style debugging for PHP. In the past I've been able to get the debugger installed, but the lack of a decent interface to use in setting breakpoints and watches has limited the value of a debugger (one thing that I have found helpful is XDebug's profiling feature that lists all function calls in a nested format along with performance timing). The recent announcement of a new XDebug client for OS X got me back on that track, and while I wasn't able to get MacGDBP working as I wanted, it did lead me to re-evaluate the newest Eclipse offering for PHP coders: PDT. PDT has come a long way, and the combination of a robust IDE, nimble 'jumpt to' shortcuts and killer debugger integration are more than I can pass up. Here's how I got everything working on a Mac OS X 10.5 box.

Much of what follows was made possible by and incorporates instructions from these very good tutorials:

A Poor Coder's Devel Themer Port for Drupal 5

Ethan's picture

Let me start by saying I’m not proud of this, it is one of those awful awful hacks which I should be ashamed of and appalled that I would even consider, one of those hideous violations of every coding standard known to good coders throughout the world.

What is this horrid, monstrous bit of code hackery I’m referring to? It’s a simple hack to the theme function which provides a very rudimentary version of some of the theme-level information so elegantly and profoundly usefully exposed by Moshe Weitzman’s Devel Themer module. For various reasons, this hack actually isn’t that egregious; for one it is ONLY FOR USE ON DEVELOPMENT SITES, and therefore does not all into that more loathsome category of coding dark secrets which are injected into codebases in the 11th hour to make Drupal conform to non-Drupal-tuned functional specifications. In addition, the hack allows custom processing of theme output to be included in the info dump for themed blocks, and therefore makes incredibly arduous tasks like finding the source of a missing </div> tag a great deal less awful. Let’s face it (with relish): sometimes hacking core is just the best way to debug difficult problems.

So, enough stalling, just what is this horrible, awful, shameful hack I’ve devised. Well, it’s anticlimactically simple, actually. Just insert the following code into the function theme() declaration in theme.inc just above the return call_user_func_array($functions[$function], $args) call:

Node Import Part 0: the prequel

Ethan's picture

I thought I'd share some lessons learned in the node creation wild as a follow-up to Tom's recent post surveying the options available to prospective content importers who need to get a slew of nodes into Drupal from some far off place such as the land of flat HTML, custom CMSes or even the fabled Drupal 4.6.

For a very exciting upcoming site we had to import a few hundred old blog posts from a Drupal 4.6 install, along with 30 authors and around 2000 taxonomy associations. While these numbers are nowhere near as big as content migration figures can crawl, the complexity of the data structure was multiplied by the specific requirements of the various node importing schemes available in Drupal. This multiplicative factor yielded a somewhat dizzying array of alternatives that had to be evaluated, with the vast majority of them leading down paths that involved exporting nodes, importing with old legacy data attached then iteratively importing the author and taxonomy data one piece at a time using custom scripts and translation tables.

Scary.

Synergy: more than keyboard sharing

Ethan's picture

I have recently started using synergy to control my Mac and PC using a single keyboard and mouse. Synergy is a pretty impressive piece of Open Source software: it’s impressive enough that it can use a standard LAN network to share input devices between computers. What I didn’t realize until setting it up was how much more it can do.

While Synergy is fairly easy to set up, being a geek-centric piece of open-source software it requires some editing of configuration files and the like (though on Windows machines a straightforward GUI is provided to facilitate this). Configuration files specify not just what machines are going to be controlled and how their monitors are laid out in physical space, but also allow for a plethora of configuration options. While many of these options are basically just advanced setup parameters, there’s one class of options that makes Synergy incredibly powerful:

Through Synergy’s configuration file one can map keystrokes entered while controlling any machine to (not necessarily identical) keystrokes on a specific machine!

first post: how the shell made me go !h:7 !!

Ethan's picture

Hi I'm Ethan, the new guy. This is my first post, but beyond that brief bio and the unequivocal denial of any claims that I don't change my shirt on a daily basis, this post isn't going to be about me.

It's going to be about the totally off the hook tricks I leaned about the "previous command" shell shortcuts I learned today from this post and how they totally rocked my world a second ago.

So here's the situation: I downloaded a file and couldn't remember whether it was a zip or a tarball, so I ran this command:

tar -xzf ~/downloads/google-sitemap-generator.3.0b7.zip

Why did I try to unzip a tarball, you ask? Because I'm lazy, and when autocomplete says "press enter", I ask "how fast"? Needless to say, the result was some mumbo-jumbo that I'm sure must have had ample amounts of bit-level impatience buried somewhere underneath it.

Remembering the tricks from that post I tried this:

unzip !^

I was thinking that maybe the first argument (referenced by !^) would be recognized as the argument after the flags. But no go, it resolved to unzip -xzf

Now I had a bit of a dilemma: I couldn't use any more of the cool tricks because they all referred to the command prior to the last...unless. What if all the argument referencing commands could be prefixed with a pattern!?! Sure enough, this gem worked like a charm...gem...:

unzip !tar:2

Which basically reads unzip {the second argument of the last command matching the glob-string 'tar'}

To my total, complete astonishment it actually worked. Brilliant.