Category Archives: views

Drupal gotchas: watch out for Views dependencies

One of the downsides of writing all configuration changes as update functions in .install files is that you need to watch out for static or cached variables and module dependencies.

For example, I just finished helping a teammate debug an elusive Views problem. The symptom: some views with blocks didn’t show up in the blocks table, even after a _block_rehash in the update function. Other views were there. If we ran the update function independently, all the blocks appeared in the blocks table. What was going on?

hook_views_default_views is a great way to programmatically define views. By using the Views Export function, you can interactively create the view, then export the code so that you can make the view available on your production site without manual administration.

However, if your new view requires a table ($view->requires) that doesn’t exist, then _views_get_default_views discards it. By the time you enable the module in another update function (and you’re using update functions to do things like that instead of manually enabling modules on your production site, right?), has cached the (incomplete) views list and won’t recognize that the requirements are now available.

To get around the view dependencies, comment out the $views->requires line. It’s a hack, but it’s probably better than hacking all the functions that cache data in static variables.

Drupal in the Trenches: Fighting with Views

The other developers have bought into the idea that all behavior-related changes should be in the source code. It’s the only thing keeping us sane with four developers and three environments: local, testing, and production. It has its own challenges, though, like this one:

Problem: Blocks based on views with dependencies on custom tables sometimes don’t show up when we refreshed from the database dump, although things work if we update the database one revision at a time.

After far too much pain and suffering, I figured out that _views_get_default_views was caching the results. When it checked our newly-enabled modules for default views, it found some views whose dependencies hadn’t gotten enabled yet, so it didn’t cache those. The next time _views_get_default_views was called, it used the values it had stored in a static variable available only in that function.

_views_get_default_views did not provide a way to reset that static variable, so once it was called, the data was practically written in stone.

_views_get_tables is similarly evil. (ARGH!)

This might’ve been fixed in a Views update (and we’re still using Drupal 5, in any case), but I’m not going to suggest updating the module this close to external acceptance testing.

So our options were:

  • Make sure _block_rehash and similar functions never get called before the update function that enables the module. Problems: Not only do we need to untangle the order of update functions that get called and be hyper-aware of what other modules do, but we’ll also need to change old update functions if we ever need to do this for another view in the future.
  • Hack _views_get_default_views and _views_get_tables to accept an optional parameter that resets the static variable.

When there are no clean alternatives, you just gotta get your fingers dirty and hack code.

Was that really only one hour of my life? It felt so much longer.