Drupal development, project updates, occasional knee / head slappers

Feb 22, 2011

Note: If you want to really bend this block to your will, you might need to learn some module building skills. Check out Build a for clean video tutorials on modifying the output of a page, theming and lots more.


Download and install the Taxonomy Menu module.

Download and install the Menu Block module.

Optionally create a new parent menu where all the taxonomy-based menus will reside by going to /admin/build/menu/add. I named mine Taxonomy.

Go to /admin/content/taxonomy and click the edit vocabulary link next to your tag vocabulary

Scroll down to the Taxonomy menu fieldset

Select your new menu for the Menu Location

I use the following options:

Most of the other options are there so that you can customize the paths to the taxonomy terms if you use Views, for example.

Click Save.

Go to the block administration page at /admin/build/block and click the Add menu block tab.

Start working your way down the form. Here's what I used for the Parent item settings:

I changed the custom visibility settings:

Then click the Save block button.

You'll see the menu in the disabled section of the page, and it will look something like this:

Set where you want the block to display, and then you've got your block! Here's what mine looks like:

If you want to really bend this block to your will, you might need to learn some module building skills. Check out Build a for clean video tutorials on modifying the output of a page, theming and lots more.

Jul 19, 2010

Today I assigned a couple of tasks to my new VA team in India, and heard back from the state-side VA. I'm kind of excited to see the results of this first assignment, a little apprehensive about what happens if the results feel like they're not worth it.

One thing I'm realizing is that passing a task onto a VA requires a tight coupling to feel effective. For one, before I assign the task, I need to be committed to it. Then, when it comes back I need to be committed to doing something with the results. If I let the distance between me and the task drive in a bit of apathy about the result and I lose enthusiasm for acting on it once the task is complete, then it will have been a waste of money and somebody's time.

An associate read my initial post on outsourcing, and had some interesting thoughts to share:

"My biggest hurdles in outsourcing is finding the right person to work with and defining the tasks that I would feel comfortable having someone else take care of.  Those tasks often reveal themselves through experience.  Like you, I'm a do-it-yourselfer and usually try things once.  I remodeled our bathroom and realized the savings in money wasn't worth the cost in time and happiness.  So when it came time to finish our basement, I outsourced it to a proper contractor and found it was well worth it.  Same goes with taxes and hiring a CPA.  On the reverse side, I enjoy sending emails to my wife far too much to delegate that to a PA in India.

One area I would love to outsource, would be the initial base installation of Drupal, hosting environment, repository setup and post-launch client support of sites.  Any thoughts on that?  Have you used any services or tools that would help with this?"

It sounds like we've had some of the same experiences. I also remodeled our bathroom and have had the sense that it's not something I want to do twice. I've also been very happy with hiring a CPA to outsource the particular method of emotional torture that is the most memorable result of filling out complex tax forms. I did like the idea of using a VA / PA for sending personal e-mail on occasion for the novelty factor, but it probably would be supplementary rather than a replacement.

In regards to outsourcing the base installation of Drupal, probably the best service I've seen for this is WebEnabled. At WE, you can spin up an instance of various versions and distributions of Drupal, and save your site at any point to use as your own personal distribution later. One issue with this is that you still need to keep modules and Drupal core updated. One additional plus is that WebEnabled has built-in SVN support, and when you spin up a new instance, it pulls it into a new repository automatically.

The other solution is to automate as much of the process as you can yourself, and come up with a good, repeatable workflow. One method is using a multi-site so it's much easier to maintain core and module updates across multiple sites. I know some folks have had success using Aegir to deploy new sites, but I haven't had the chance to play with that yet. Using a combination of install profiles and Features can reduce the amount of work in the initial setup as well.

As far as post-launch support goes, I don't have much experience with outsourcing this. Finding good, skilled service providers seems tricky, and often a matter of working through multiple providers until you find one that is a good fit. When I hear of people having good success with outsourcing skilled web development work, it's for simpler cookie-cutter sites. I personally didn't have a lot of success with it, but I also didn't try for very long.

Jul 20, 2010

My use case was that I had a super long blog entry that I didn't want to hog my blog's front page. So I needed to shorten it down to a certain pixel height, and add a link that would expand it completely.

First, we need a couple of jQuery bits:

  // Go through each item in the main blog page and shorten if bigger than 1500px
  $('.view-blog .views-row').each(function (i) {
    var div_height = $(this).height();
    if (div_height > 1500) {
      $(this).append('<input type="hidden" class="item-height" value="' + div_height + '" />');
      var id = 'expando-num-' + i;
      $(this).attr('id', id);
      $(this).after('<a href="' + id + '" class="expando-div">This is a long blog post, click here to view the rest</a>');
  // Add the 'click to expand' behavior to the links
  $('.expando-div').click(function () {
    var $div = $('#' + $(this).attr('href'));
    var div_height = $div.find('.item-height').val();
    $div.animate({height:div_height}, 1000);
    return false;

I added this code inside of a function called Drupal.behaviors.custom_misc()Click here to read a bit more about Drupal behaviors.

Note that your selectors might be different. I'm using a Drupal view to display the blog, so I can rely on certain selectors.

Next, we need to add a couple of styles to our CSS (or LESS) file:

.view-blog .views-row {
.expando-div {

The only really necessary part there is the overflow:hidden, which makes it so the hidden content doesn't overlap on other stuff.

My result (with a little more CSS styling) looks like this:

Jul 19, 2010

Not too much happened today physically in moving towards outsourcing, but since it was on the mind, I had some small epiphanies and thoughts that may be worthy of sharing.

On the logistical front, I awarded my virtual assistant job on Elance to two providers, a company in India who can provide a team of folks for $5 / hr and an individual in the states fo r $8 / hr. The India-based team got back to me later in the day, but I haven't heard back from the state-side one yet.

I think taking physical steps towards trying something like this is probably the way to get into the right mindset. Just like I mentioned in Day 1, it seems like actually getting your hands dirty with a task is the way to pull your mind into it.

Here are some outsourcing thoughts I had today:

My original plan was to have the two virtual assistants complete the same tasks so I could measure them against each other. However, a lesson came to mind which I learned playing Mastermind one day with my father-in-law. My idea was to apply an algorithm to the challenge - doing all yellow pegs, then purple, then pink, and identifying without a doubt what colors were on the board. What my father-in-law suggested was that every move should be a possible solution based on what you know. So, if you try all yellows and you find out that one of pegs is yellow, all of your guesses from that point forward should have a yellow peg. The lesson being that every step you make should move you forward as much as possible. My guess is that I can move forward faster by having the two VAs do different things, even if I sacrifice the ability to isolate variables and have a more scientific experiment.

Often, what takes the longest amount of time when accomplishing a task is the exploration around the task, getting sidetracked and exploring other things. Sometimes this is good, but sometimes it distracts us from what's the most important to us. By outsourcing, we end up telling someone to take the shortest route to accomplishing the task, which might be way more efficient than the way we'd go about it.

One thing that makes outsourcing a hard concept for me is that I've tried to simply my life as much as possible. Part of this appeals to my sense of minimalism and portability. If the s**t hits the fan and we all have to fend for ourselves in some world of post-apocolyptic chaos, I want to know I can handle my life. I want my needs to be simple. But, what I might not realize is that the skills you develop in being able to guide people, in being creative enough to distribute meaningful tasks to others, might also prove a very useful skill in that kind of situation.

Sometimes the most important things you learn when doing your own research are not associated at all with what you're researching. You'll miss out on these things if you outsource them. I wonder you can find the right people that will also share stuff that they learned along the way.

Having a VA is like having a nanny of the mind. You can use them to augment your time in a good way, or take over responsibilities that you really shouldn't be delegating. I think that this is a bit of a fear for me, that I may end up outsourcing things that would actually help me grow into a more interesting person.

Jul 20, 2010

I received a comment on one of my posts which reminded me about one of the concepts in The 4 Hour Workweek that I didn't really internalize: the idea of outsourcing. Tim Ferris talks about this in Chapter 8, offering some anecdotes and suggestions on tasks that might be good candidates for outsourcing.

Overcoming fear

I've had a sense for a while that I land in the DIY camp more often than the Outsourcing one. The assumption that these two camps as mutually exclusive says a lot to me now that I'm re-evaluating my outlook. 

The feedback I get from the work I do is important. When I actually fulfill a task myself, I get a sense of how difficult the task was, get thoughts on how to improve my workflow, and with experience start to develop patterns that have the potential of making almost anything I do enjoyable. If I delegate a task to someone else, I have a sense that I'm robbing myself of this experience and the skills that come with it. What I'm learning instead is how to manage other people, and this doesn't interest me nearly as much as learning more about managing myself.

I also have a feeling that one of the most difficult and time-consuming parts of many tasks is identifying if the task is actually important enough to be done at all. So often I start building something and only after plugging in a sizable chunk time figure out that it's not necessary. But, the only way I come to that conclusion is by starting to work on it and setting my mind to the task. I wouldn't get in this mindset if the task was delegated, and because there wouldn't be as much on my plate, I wouldn't have the same pressure to find a way to remove the unnecessary from my life and automate as much as I can.

I've had a couple of experiences outsourcing my work - mostly design work - and the results have been less than stellar. So, the combination of the DIY attitude combines with a lack of success to form a fairly strong resistance to leaping in and experimenting with outsourcing.

But I want to change that. If I don't outsource I want to know it's not out of fear, and that these reasons I have to not do it are genuine and not an example of forming arguments to support an emotional reaction. So, I'm going to give it a shot.

What's likable about outsourcing?

Let me summarize briefly how the 4HWW articulates the benefits of outsourcing:

  • The ability to practice remote management skills without incurring the high cost of an employee in the states
  • Having a parter - someone who can take on stuff when you don't feel like it, give encouragement, and be there for you when you need them
  • The sense of power that comes from sitting in the boss' chair
  • The ability to focus on what you find most important or interesting and delegate the rest

There are examples of outsourcing all kinds of things, from very personal tasks like sending an e-mail to one's wife to full-on business proposals.

Step 1: What can I outsource?

After reading the chapter again, one take-away was that I might not know exactly how I could employ outsourcing until I start doing it. That it's like pretty much anything, the more you play with it, the more you realize what it's real purpose and potential is.

An idea that's iterated and re-iterated in the 4HWW is the idea that if a task is not well defined and important, no one should do it, and that delegation and automation multiplies any existing inefficiencies. So, it's important that the tasks you delegate are ones that you're committed do doing, and that you've at least taken the time to define what they actually are.

Coming up with ideas out of the blue that meet these criteria was a little tricky, but there are a few things that came up for me:

  • Transcribing the training videos on Build a for searchable textual content.
  • Finding out the relationship between the sale price and appraised value of homes in Boise, Idaho (we're considering buying a home there)
  • Where can I syndicate articles from my blog to improve readership and get posts like these to people who would be most interested in them?
  • Where can I get floss business cards for my company (I love those things, get some from my dentist at every cleaning)
  • Sending random encouraging e-mails to myself to see if it has any effect on bolstering enthusiasm.
  • Finding places in the handbook for some of my tutorial posts.

These are all things that are going to take a back seat for a while if I have to plug in the time to do them, but I know I want to do them at some point. So, they seem like good candidates for outsourcing.

Step 2: Finding a virtual assistant (VA)

The next step was to find a virtual assistant for me to start outsourcing tasks to. So, I posted a job on, paid $15 for a premium listing, and in a couple hours I had four bids from $5 to $8 an hour, three of which seem like they have potential.

Over the next day or two I'll review any incoming bids and choose at least two to work with, one in the states and one outside of the states, then I'll give them a shot and start delegating. The idea here is that maybe it would be good to have a native English speaker for certain tasks, but it seems like you can get a better return overall by hiring out of the states.

Hopes and questions for the future

Now that I've committed to giving this a shot, I have some hopes that are bubbling to the surface. If this works out well, then I could expand my ability to get things done upwards of 50%. I can foresee that after a while, certain tasks will start to scream "outsource me!" and it could become a natural part of my workflow to delegate particular items. There's a whole slew of things I would never outsource because the experience seems to valuable to me, but I also know that I can learn a lot from other people doing something if they can tell me how they did it. Could having a virtual assistant be like having a personal trainer? Someone who can show you how they found something, where they looked, how they made certain decisions? And then you can take it from there, having a nice little boost towards your end goal? What would it feel like to have a partner on board who is on call, ready to plug into virtually anything you need help with?

But, I'm apprehensive as well. What should I expect from these folks? What happens if time after time I end up completing tasks I originally delegated because I'm not happy with the results? Will I be able to identify a task suitable for delegation from those that aren't? Will I be able to provide the right kind of encouragement to have my assistants appreciate doing the work? Can I be a boss without being a lame boss?

I guess I'm about to find out.

What happens next?

Read more about what happens in Day 2 of Outsourcing My Life, and Day 3 of Outsourcing My Life.

Jul 17, 2010

I decided to jump into Views Alpha 3 because I wanted to explore the Views Infinite Scroll module, and I have a friend using it on a large production site without any problems. Here are some notes from the upgrade experience.
No update.php run was required - nice.

I did get a WSOD on the /admin/build/views page, but I CTFC and all was good.

Here's the new interface, which looks a lot like the old one:

On one of my side blocks, a pager suddenly appeared, so I had to change the pagination settings here:

This is cool, the number of items and pagination settings have merged into a single setting.

I also started to notice that the configuration blocks are ordered a bit differently. There are basic and advanced settings panes now, and the new ordering does seem to make more sense, though it's hard to tell if it would make more sense to someone new to Views.

Ah, I've been wanting this feature, the ability to re-order the displays.

When setting pagination options, you can expose inputs for the number to show and the offset. Even though I think this is usually clutter, it's a common request from clients to have the ability to set the number displayed.

I installed the Views Infinite Scroll module (and the associated jQuery plugin, after some wheel spinning), and selected it as the pager option for my view. At that point, it said that it was incompatible with Ajax, which makes the search box above my view less responsive. So, I'll have to leave it to the default Views pager. I also kept getting this error, even after turning Ajax off on the view:

My friend also suggested that I upgrade Views Bulk Operations to the latest 6-3 dev release, which at the moment is here. No problems there, and it also didn't require an update via update.php.

Jul 16, 2010

If you don't use Navigate you could be missing out on some rather nice tools for rapidly setting up a site and helping clients and site users get comfortable in Drupal. Navigate is all about customizing the navigation experience to easily find menu items and content if you don't know where they are, and quickly build a set of personal menus to areas of a Drupal site that you use the most.

I use Navigate every day and it saves my bacon. 

The problem

The problem we're trying to solve here is that Drupal's navigation is deep and complex. Menus in menus in menus, and it takes a while to figure out how to find what you need. Navigate brings together a set of tools in an reasonably un-intrusive package that helps you get around. I'll take you through the features and how to set it up below.

Getting started

First, download the Navigate module and install the associated modules you see below:

Once installed, here's what you'll see in the top left corner of the screen:

Something's hiding there. Click it and it will expand to show you this:

This is Navigate. Navigate is a box that contains widgets. You can hide Navigate by clicking the steering wheel icon one more time. Above, you can see it has two widgets, one called Search and one called Favorites.

Let's play with these for a minute. Test out search by typing user in the search box and pressing enter. Navigate will search content and the menu to find any matches to your search and load them via AJAX. You'll see something like this:

One nice thing about Navigate is that it retains state. That means that if you click on a link, the same search results will display on the next page.

If you click the little cog wheel highlighted above, you'll see some settings for this widget:

TIP: I use the search widget to find menu items added by newly installed modules when I don't know where they are.

Here you can set the widget to search for content (the Full option uses Drupal's search engine), the menu and / or users. You can even set which types of content to search.

Why would you want to do this instead of searching everything? Well, Navigate lets you have as many widgets as you want, and you may want to keep one search result set open from page to page while using the other one to search around. You also might want to have a search widget for the menu, and another for content. Let me demonstrate.

Click the big cog wheel to display Navigate's settings:

This opens up some new options. I'll walk through this bit by bit. You should see something like this:

Here are the new areas that displayed, marked so we can reference them later

Our first goal here is to add a widget. To do so, all we need to do is click on an item in the "Add widgets" section. We want to add a new search widget, so we'll click the search item.

This will add a new search widget below the others, so you'll see something like this:

Now we have two search widgets we can set individually to search for particular things. One problem, though. They're both called Search. No biggie, we can change the title of each of them by double-clicking the title, typing the new title, and pressing enter:

Here's what they look like re-titled:

Now, it might make more sense to have the two search widgets next to each other, so grab the Search users title  to move the widget and drop it below the Search content widget.

Using the favorites widget

Now let's explore the Favorites widget. The idea of the favorites widget is to create bookmarks to commonly visited places. When you are on a page, you can add the page to your favorites by typing a name for the page and clicking the Add button.


Once you have a number of favorites, you can re-order them by dragging and dropping. You can delete items by clicking on the X that displays when hovering over an item. You can't see it because we're just using screenshots, but everything is done via AJAX and saved behind the scenes, so this is very quick process.

For complex shortcuts, I'll add a divider just by entering a series of dashes as a favorite:

Just like any other widget, you can have multiple favorite widgets and rename them as you'd like.

If you create a set of shortcuts that you'd like to use for another site, there's good news! Click the settings cog wheel for the widget, and you'll see an import / export form. Click the Export button to generate the data you can use to import into another site's widget:

Using the menu widget

Okay, let's explore another widget. The Menu widget provides a collapsible tree of any menu, and just like the search, it has a saved state so that you don't lose your place between pages. Let's see what that looks like.

Just like we did above, click the settings cog wheel to open up Navigate's settings, then click the menu item:

A new widget will appear below the others with a simple form to let you pick the menu to display:

Select the menu (I picked the Administer menu) and click the Load button. What displays will look something like this:

Every + sign denotes an expandable menu. Click it to expand or collapse a menu. Here's what happened when I clicked the one next to Reports:

Simple enough. I typically add a menu widget for the Create content menu when I start working on a site.

One of the big challenges of Drupal is teaching clients how to use it. There's just a lot to wrap your mind around. And often, there is more than one kind of person using the site, so the ability to have a customize set of navigation tools for each individual or role is useful.

With Navigate, you can set defaults for roles, or modify an individual user's widget set. Let me walk you through how to create a default set for a role.

Setting default widgets for a role

Let's take the widget set we've just created and set it for the default widget set for new administrative users. First, click the cog wheel to display the settings, then click the "Set" link next to the role you want to assign the widget set to:

Once you do this, when a user of that role logs in for the first time, if they don't have their own widget set already they'll get the default. Once you've set the defaults, some of the gray-ed out options become available:

Load - loads the widget set as your current widget set so you can modify it
Unset - Unsets the defaults for the role
Set all users - This will set the defaults for all users of that role, even if they have a widget set already.

Setting defaults for a single user

In the "Search name / UID" box, start typing a username or UID. Once you've typed something in, the gray-ed out options become available:

This works the same as the role. You can either set the user's widgets to be what you see on your current widget set, or you can load theirs to modify them.

One tricky thing here is that when we load a widget set, it replaces our current one. So, we need a way to export and import a widget set to save our settings while we work on the widget sets for other users.

Exporting and importing widget sets

In the settings pane, you'll see a couple of boxes like what you see below. When you click the "Export widget set" button, the textarea will be populated with the code you would need to paste into the "Import widget set" box in order to import.

You can use this tool to create a number of widget sets to use across multiple sites. In Navigate, everything is portable.

A few special features

Keyboard shortcuts

You can enable keyboard shortcuts to easily use Navigate. Click the "KEY" link at the bottom of the widget set to enable it (it will be white and non-italic when enabled):

CTL+SHIFT+N - Toggles Navigate visibility
CTL+SHIFT+S - Moves the cursor to the last search widget for rapid searching


Double-click the Navigate title to hide all inputs and just show links (to free up some space):


Hovering over virtually anything in Navigate will give you some helpful information. For example, hovering over the Navigate title displays this:

Hovering over a link in a favorites widget displays this:

You can also click the HELP link at the bottom of Navigate to display the help page:

That's it, enjoy!

Jul 20, 2010

You can't get syntax highlighting in Evernote directly, but what you can do is use an online syntax highlighting service and copy the highlighted content straight from the page.

First, I went to and pasted in some code:

  for ($i=0; $i<4; $i++) {
    echo 'This is a test of syntax highlighting in Evernote using Pastebin';

Then, I copied the resulting code from the output, which you see here, and paste it into an Evernote note. 

You could also use the Evernote Firefox plugin to create a note straight-up, but it's a pain trying to undo the CSS styling to get some plain text in before your code, so I would create a new note, add a couple of blank lines to the beginning, and paste in the code after that.

The result is what you see below. This works because Evernote stores HTML as HTML, and if there's embedded style tags, those will get copied over too. I first tried this experiment with Pastebin, but it didn't work because the styling is not inline.

  for ($i=0; $i<4; $i++) {
    echo 'This is a test of syntax highlighting in Evernote using Pastebin';
Jul 16, 2010

Below is a list of things I own and like, curtesy of an Amazon aStore. There's stuff that I can't find on Amazon, so at some point I'll have to create a post with those.

Syndicate content Syndicate content Syndicate content Syndicate content Syndicate content