Giving Credit Where Credit is Due

One of the best things you can do for your project is highlight the contributors who are helping make it a success. Every patch counts, and every now and then you get someone in the queue who blows you away with a first patch that traces down some sneaky, hidden bug that you know took hours to track down. Attributing such patches has always been a matter of dropping the contributor's name into a commit message and thanking them in the issue in the past, but thanks to Git on drupal.org there is now a better way.

This may be old news for most folks, but I didn't discover this feature until just a couple months ago. It turns out that user profiles on drupal.org now include a Git attribution heading under which you can find the appropriate command line option to pass to git commit to attribute that user with a patch.

Attributing svendecabooter

By way of example, I recently committed a patch submitted by svendecabooter. I still formed my commit message using the tried and true format (including both the issue number and his username), but I also added the indicated text to the command:

git commit --author="svendecabooter <svendecabooter@35369.no-reply.drupal.org>" -m "Issue #1197512 by svendecabooter: pass the entity rendering language down to the linked fields when rendering product fields."

Thanks to Git, even though I am the one committing the code, he is the one credited with authorship of it. This is visible both in the log for that commit and on the committers page for Drupal Commerce. Many thanks to the team for working this all out and helping maintainers give credit where credit is due.

Minding my Peas and Queues

As it turns out, I really enjoyed my time in London. Getting to visit old, historic cities is quite a treat for someone from the Midwest in the U.S.A. There are no castle towers on hills or centuries old steeples gracing my skyline in Louisville, KY, and I'm quite a sucker for both. Getting to visit the Tower of London, which supplies arms to my local museum, turned out to be a special treat. I'm also a sucker for good food and drink (who isn't?), and while it's not the height of elegance, my first experience of fish and chips with mushy peas was good, too. Note to Americans: it's mush-y, not moosh-y.

Fish and chips with mushy peas. Mmm!
Fish and chips courtesy of The George.

My first couple of days in London were my busiest. I delivered a Drupal Commerce training to a room full of students with Greg Beuthin (a.k.a. smokinggoat), our in-house trainer par excellence. Unfortunately, he and I both had sniffles and scratchy throats, so I can only imagine what those reviews will say about our delivery... C'est la vie. We survived, but my day was only just getting started by the end.

For most of the next day and a half I was minding my queue in preparation for the 1.0 launch of Drupal Commerce. With the help of Bojan Zivanovic and Damien Tournoud (and a few others throughout the day), we were able to close out a variety of issues and ensure all of our automated tests were passing when we finally packaged the 1.0. In a feat of endurance sure to be remembered for ages to come, Damien and I outlasted Bojan's youthful energy to finalize the release after postponing dinner for a couple hours. That's what experience gets you, folks.

Excited Damien
An excited Damien is never too hungry to celebrate.
Proud father
It's a boy! He weighs 8 lbs. 6 oz. and is 22" long!

Coming to DrupalCon to collaborate with the other Commerce Guys and the various contributors from across Europe was the greatest part for me. Without the community, we wouldn't have the 1.0 that we do, a solid e-commerce framework that is not limited to a particular use case or locality. We're standing on the shoulders of Drupal core, the contributions of Merfago, and the dozens of patch contributors who have helped ensure Commerce can accommodate all those crazy taxes around the world. I also personally wouldn't have known that mushy peas are better with malt vinegar mixed in without John Albin Wilkins.

With the 1.0 out, my attention is now focused on ensuring our essential contributed modules are ready for use. I'm focusing specifically on making product administration simpler, ensuring Commerce Shipping supports calculated shipping quotes, and pushing code upstream from a local project into Commerce Addressbook. I always have a half dozen payment related projects in the works, too.

If you want to hear more about Drupal Commerce in person, I'll be talking about the project as an international community success story at DrupalCamp Atlanta. I'm busy compiling statistics on committers and contributions to share along with my usual hand-waving, mile-a-minute overview of the modules' functionality.

I'll also deliver a show-and-tell style training at this year's Do It With Drupal in NYC. I love DIWD as a more intimate gathering of module authors, core contributors, and web pros from outside the Drupal community. It's a great place for attendees to soak in a wealth of information and run their project needs by the folks writing the code they'll use. Today is the last day for early bird pricing, so if you're on the fence, you may as well make the impulse buy and come hang out in New York with us.

I hope to see many of you at those events and many more minding the queues.

Breathing British Air

At long last I'm breathing British air and getting psyched for tomorrow's Drupal Commerce training. I lived in the UK for four years as a child but only have vague memories of a nanny and getting AG Bear and My Buddy for Christmas. I didn't come back with a nanny, but I did bring along my wife to help take care of me and my daughter to carry the dolls. We spent a few days in Paris recovering from jetlag, ringing in our fifth year of marriage, and finalizing training arrangements before riding the Eurostar to London with the rest of the team this afternoon.

We'll have a total of fourteen Commerce Guys at DrupalCon London, meaning we'll have plenty of people on hand to talk about Drupal Commerce. In addition to tomorrow's training, we'll be presenting / discussing the Commerce modules and contribs in BoF sessions throughout the week. To see the line-up, check the BoF schedule under Room 334. If we can record or screen capture anything from these, they'll end up on the Commerce Guys Vimeo channel.

I'm looking forward to the Developing with Drupal Commerce session on Thursday, because it will be me first go at leading a panel discussion instead of introducing all things Drupal Commerce in a solo, hand-waving, water-guzzling presentation.

I'll be joined by several other developers and business owners who have been bidding on and building Drupal Commerce sites since the alpha and beta releases. We're now gearing up for a 1.0 release thanks to the hard work and contributions of everyone on the panel. It should be valuable and entertaining to hear them talk about what it's like to develop with Drupal Commerce and how the core modules have evolved since they've been working with them.

Last but not least, for everyone who doesn't care a lick about e-commerce but likes Indian food, I have discovered the best Indian place in Croydon. Look no further than The Spicy Affair for a fair-priced, keenly seasoned meal (with a surprisingly kid friendly wait staff!). That's probably the most controversial statement I made in this blog post, and I can't defend it as though I'm some sort of connoisseur. If you know a better place, feel free to link it in. Otherwise I'll see you there.

Using containers as #states enabled markup form elements

As part of the sprint we're holding in Paris right now to introduce new Commerce Guys to Drupal Commerce development, we devised a situation where we wanted a conditionally available message on the checkout form. We decided for a shipping scenario that we wanted to present a message to the user regarding shipping costs inline with the address form if the customer selected a shipping address outside of the free shipping country of the store.

Adding a random text message to a form is trivial. You can just add a markup element to the form, using a div tag to make sure it ends up in a fieldset if necessary:

<?php
$form
['message'] = array(
 
'#markup' => t('What a wonderful message!'),
);
?>

Additionally, adding a #states array that includes the instruction to hide a form element on the basis of a select list's value is trivial:

<?php
$form
['message'] = array(
 
'#markup' => t('What a wonderful message!'),
 
'#states' => array(
   
'invisible' => array(
     
':input[name="select_list_name"]' => array('value' => 'US'),
    ),
  ),
);
?>

Unless I botched my pseudo code, that #states array should instruct the Form API to include JavaScript to hide the element when the select list I specified has a value of US. Unfortunately, that code won't work. Shocked

The problem is that the JavaScript that hides the element depends on the element's ID to target the behavior, and a markup element by default gets no wrapping. This means you can't directly put a #states array on a markup element in general. You do have a few options to work around this, and I'll end with what we went with in our case... you can tell me if we're crazy. Sticking out tongue

  1. You could just hardcode a div wrapper that includes the ID and the form-wrapper class Drupal expects, but I can't say that I'd recommend it. Names change quite frequently during development and can easily be altered.
  2. You can also just put the markup element inside a container element and attach the #states array to the container. Containers are rendered as divs with proper IDs for targeting, so this works just fine.
  3. However, we wanted a compact solution, so what we did is turn the markup element into a container element and set its #children property to the message. This effectively makes the container element function as a markup element, but it actually wraps the markup in the appropriate div on output. Since #children is already set, this does mean that the container element cannot actually contain other elements, so there may be good reasons for you not to try this at home.

The gist of our solution was:

<?php
$form
['message'] = array(
 
'#type' => 'container',
 
'#children' => t('What a wonderful message!'),
 
'#states' => array(
   
'invisible' => array(
     
':input[name="select_list_name"]' => array('value' => 'US'),
    ),
  ),
);
?>

I suppose it would be nice if we didn't have to abuse the #children property name, but this seems like fair game to me unless it's a possibility to change the markup element to include the div and expected ID.

Pages