Helping the Cable Company Help me

Since the beginning of June I’ve been having intermittent issues with my Atlantic Broadband internet service.  When it works, it’s great (except that they still can’t get my name right), but when it’s not it’s really annoying.

After several hours on hold, 5 or 6 visits (I’ve lost count), and them testing everything in sight I finally started writing software to see if I can help find the problem.

It seems that at strange intervals there is a run of noise on the line that kills my service.  The noise eventually goes away and my service resumes. But figuring out those intervals has been a challenge since it turns out I don’t actually sit around 24 hours a day watching for service interruptions.

So after the last tech was unable to find a problem, and implied that it was my cable modem, I wrote a simple python script that pings Google every 5 seconds and records the response time (or failure).  I setup an old laptop to sit around and do nothing but ping Google 24 hours a day and record the results of each request.

I learned that my service interruptions tend to start and stop on the hour or half hour.  For example, the first night it started to be bad at noon and improved at 2:30 the next morning.  That pattern of human friendly times and data was enough to convince them to try again (although they aren’t willing to consider it’s something scheduled since they aren’t aware of any scheduled processes on the network).

So at the moment I have a loaner modem – which has ruled out my device as the problem – and they are closing on having replaced every piece of hardware between me and the nearest node.  To their credit, it has gotten much less bad.  Most outages now last five minutes (more or less exactly), and I have only have a few a day (instead of a few an hour).

Anyone have guesses about what processes run on cable networks that last five minutes and reattempt for a few hours at a stretch before giving up for roughly 13 or 14 hours.

My takeaway so far has been that if your internet provider is unable to figure out what’s wrong, offer them more data. Even if they don’t know how to use it, it got them to take the problem seriously again.

Controlling Block Visibility with a Custom Field in Drupal 8

Awhile back I wrote up a pattern for creating static blocks on Drupal 8 sites. This week I was working on a site where one of those blocks needs to be enabled or disabled on specific nodes at the discretion of the content author. To make this happen I’m adding a new feature to my pattern.

In older versions of Drupal there were a number of ways to go, like the PHP Filter, or custom handling in the block’s view hook, but I figured there were probably more appropriate tools for this in Drupal 8.  And I found what I needed in the Condition Plugin (more evidence that plugins are addictive). According to the change record they were designed to centralize a lot of the common logic used for controlling blocks, and I found it works quite nicely in this case as well (although a more generalized version might be useful).

I have the complete condition plugin at the end so you don’t have to get all the details exactly right as we go.

I started by adding a boolean field to the content type named field_enable_sidebar. Then I using drupal console generated the stub condition plugin:drupal generate:plugin:condition. In doing this the first time I also looked at the one defined in the core Node module to handle block visibility by content type.

The console will ask you a couple questions, obviously you can attach it to any module you’d like and call it whatever you’d like. For this example I have it in a fake module called my_blocks and the condition is named SidebarCondition. But the next couple questions are less obvious and more important.

Context Type should be entity

The context type should be set to entity since we are looking to work based on the node being displayed.

Context Entity Type should be Content

Next it’s trying to filter between entity types, and since we’re doing this based on content, select “Content” to get a list of content entities on your site.

Context Definition ID should be Content

Finally select “Content” again since that’s the label for your node content entities.  Of course if you have placed your field on another entity type, pick that entity here instead.

Once you run through the wizard you’ll have a new file in your module: my_blocks/src/Plugin/Condition/sidebarContition.php

The condition plugin contains two main elements: a form that’s attached to all block settings forms, and an evaluate function that is called by blocks to determine if this condition applies in their current context.

buildConfigurationForm() defines the form array elements you need. In this case that means a simple checkbox to indicate that this condition applies to this block. We also need to define submitConfiguration() to save the values on block save.

  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form['sidebarActive'] = [
      '#type'          => 'checkbox',
      '#title'         => $this->t('When Sidebar Field Active'),
      '#default_value' => $this->configuration['sidebarActive'],
      '#description'   => $this->t('Enable this block when the sidebar field on the node is active.'),
    ];
    return parent::buildConfigurationForm($form, $form_state);
  }

  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $this->configuration['sidebarActive'] = $form_state->getValue('sidebarActive');
    parent::submitConfigurationForm($form, $form_state);
  }

In the complete example you’ll see there is summary() which provides the human friendly description of the values that have been set for this condition.

Now let’s jump back to the top of the plugin and review the annotation. Conditions are annotated plugins and those questions I guided you through above were used to generate the annotation at the start of the file:

/**
 * Provides the 'Sidebar condition' condition.
 *
 * @Condition(
 *   id = "sidebar_condition",
 *   label = @Translation("Sidebar block condition"),
 *   context = {
 *     "node" = @ContextDefinition(
 *        "entity:node",
 *        required = TRUE ,
 *        label = @Translation("node")
 *     )
 *   }
 * )
 */

This is defining the context you’ll want passed to the condition for evaluation. In this case we are requiring that a node entity labeled “node” is provided when we need it.

The real work of the plugin is handled by evaluate():

  /**
   * Evaluates the condition and returns TRUE or FALSE accordingly.
   *
   * @return bool
   *   TRUE if the condition has been met, FALSE otherwise.
   */
  public function evaluate() {
    if (empty($this->configuration['sidebarActive']) && !$this->isNegated()) {
      return TRUE;
    }
    $node = $this->getContextValue('node');
    if ($node->hasField('field_enable_sidebar') && $node->field_enable_sidebar->value) {
      return TRUE;
    }
    return FALSE;
  }

The first condition ensures that this plugin doesn’t disable all blocks that aren’t using it. Next we ask for the context node value we defined in the annotation, which provides us the current node able to be displayed. Since not all node types are guaranteed to have our sidebar field we first check that it exists and then check its value and return the correct status for block display.

Now every time a user checks a box on the node, any blocks with this condition enabled will be displayed along with the node. And the best part is that the user doesn’t need to even have block display permissions, we’ve allowed them to bypass that part of the system entirely.

Time estimation: making up numbers as we go along.

Any experienced developer, and anyone who has worked with developers, knows that we’re terrible at estimating project times.  There are mountains of blog posts telling developers how to do estimates (spoiler alert, they are wrong), and at least as many telling project managers not to rely on the bad estimates from developers. Most of the honest advice doesn’t actually help you develop a number it helps you develop strategies to make a slightly better guess.

Any time I start to work with a new project manager on time estimates I try to make sure they understand any estimate is – at best – an educated guess not a promise. I’ve learned to give ranges to imply inaccuracy, and round up to offset my bias as a developer to underestimate (I recently noticed I’m doing that too well and badly overestimating but that’s another story). However, that still lead to greater faith in the estimates than they deserve.

A few months ago I was asked about this topic by a PM I really enjoy working with and who was trying to work with me to find a better solution for our projects together. One of the articles I sent her was an old one from Joel Spolsky written in 2007. Re-reading the article I again drawn to his discussion of using Monte Carlo simulations to help come up with estimates about project duration. While he argues it helps increase accuracy, I mostly think it helps emphasis their lack of accuracy.

And since I’m a developer I wrote a simple tool to create project estimates that simulates how long a list of tasks might take (code on GitHub and pull requests are welcome). It’s nothing fancy, just a simple JavaScript tool that allows you to enter some tasks and estimates (or upload a CSV file) and run the simulation as many number of times you’d like.

Currently the purpose of it is more to encourage people to understand risk levels and ranges than to provide a figure to hang your hat on. Since estimates are bad, the tool is inherently garbage in garbage out. But I’m finding helpful in explaining to PMs about the fuzziness of the estimates. By showing a range of outcomes – including some that are very high (it assumes some your high-end estimate could be as much as ⅓ the total time needed on a task) – and providing a simple visualization of the data, it helps make it clear that estimates can be wrong, and added up error can blow a budget.

Histogram of time estimates.
This is the output from a recent set of estimates I was asked for, hopefully it’ll be good news

Please take some time to play around the tool and let me know what you think. It’s extremely rough at the moment, but if people find it useful I could polish some edges and add features.

Writing Good Directions

A last fall I wrote about the importance of writing good documentation, and part of writing good documentation includes writing good directions. I have a pet peeve when it comes to poorly written instructions of any kind, but unfortunately I’m still learning to do it well myself.

Writing directions can be thankless: you know you provided good directions when people use them and never complain about them. If you write bad directions everyone who gets stuck complains about your work – and usually not nicely because you left them frustrated.

A greyhound wearing a vest labeled donations
No one ever asks where to put money when Leo wears his donations vest.
Good directions, like good recipes, cover all the steps you need to follow, are easy to read at a glance, and provide a extra details to help you stay on track. If I’d written up my Drupal Cake recipe as a large block of text without formatting no one would even recognize it as a recipe let alone be able to follow the steps.

Sign with arrow pointing left label Cake and one pointing right labeled No Cake
You don’t have to ask to know where to get the cake.

Over the last few months at work we’ve been updating our development workflow. It started with a large project to migrate our code repositories to Bitbucket and move all support clients onto new testing infrastructure. With a large number of support clients, we had lots of updates to do, so we shared among all the developers. I did the first few conversions and then wrote up a set of directions for other developers to use. The first few times other people walked through them I got corrections, complaints, and updates, and then after a few edits there was silence.  Every couple of days I noticed another batch of clients got migrated without anyone asking me questions. The directions got to be good because no one struggled with them after the first few corrections. But I didn’t get, or expect, compliments on them, but they achieved their purpose.

Switch for a microwave labeled No fish, no curry.
This is from a hotel, but every office should probably have one on their microwave. I doubt the person who created those labels hears about them much unless someone broke the rule and microwaved fish in their room.

It’s easy to complain about directions, but it’s hard to do them right. There is another set of directions at work that I know are bad: because everyone complained about them and then gave up on the process they explain. I need to try again, but frankly it’s hard to get up the motivation to replace the current silence with either new silence (if I succeed) or complaints (if I fail).

Usually when I’m writing up directions the outcome doesn’t matter much. If your Drupal Cake isn’t the shade of blue you were hoping for, or my colleagues have to ask a couple extra questions while migrating site configuration, the world will not end. But there are people who have to write important directions that can save or cost lives.

Even if your directions aren’t signs that helpfully save lives, it is worth trying to do them right. I’ve already admitted I’m still working on getting this right but here are a few things that help me.

  1. Write down the steps as you do the task. Include pictures or screenshots when they are helpful.
  2. Do the task again following your directions to the letter.
  3. As you edit them (cause you will find mistakes) add tips about what happened when you made mistakes during your previous attempt to help people know they are off course and how to recover.
  4. Repeat 2 and 3 until you are sure you have removed the largest errors.
  5. Watch someone else follow your directions and see where they get confused – if the task is complex they will get confused and that’s okay for now. Ideally this person should have a different experience level than you do.
  6. Edit again based on the problems that person ran into.
  7. Repeat 5 and 6 until you run out of colleagues willing to help you or you stop finding major errors.
  8. Release generally, and wait for the complaints.

This of course is an ideal.  It’s what I did for the migration instructions, but not what I do most of the time. Rarely do we have the time to really work a process like that and edit more than once or twice. You can shortcut this process some by limiting the number of edits, but if you don’t edit at all you should expect people to complain.

One last thing. I’ve often been told the first part of writing good instructions is mastering the process. I disagree with that advice pretty strongly. Most of the time I find the beginners write better instructions since they are playing attention to more details. Once I master a topic I think passed steps because they are obvious to me, but not to people who need the instructions. That’s why for step five you want someone of a different experience level, someone more junior to help make sure you didn’t forgot to include the obvious and someone more senior to point out that you made mistakes.

T-Shirts Revisited

A few weeks ago I wrote about not taking free t-shirts from vendors at DrupalCon (or other tech conferences). Well DrupalCon North America 2017 has come and gone so I thought I’d report back on this year’s t-shirts.

My free shirts from DrupalCon 2017

I ended up with seven new free shirts all from places that also offered them in women’s sizes. In addition to the official conference t-shirt I picked up shirts from Lingotek, Linode, Pantheon, Optasy, Chef.io, and Kanopi Studios. There were a couple companies that appeared to be giving out shirts I didn’t talk to so there may be a couple worthy of complementing that I missed.  The big prize for the year goes to Linode whose job ad was a postcard in the shape of a (men’s) t-shirt and read:

Want a career in the cloud hosting industry? We’ve got a shirt in YOUR size.

Pantheon, as usual, had the most popular t-shirts with their custom printing shirts in a wide variety of sizes. That continues to be an amazing way to get people to watch their demo and collect contact information (although to be fair the demo itself is pretty amazing).

There were also a few companies that tried to convince me that bringing “unisex” shirts was the same as if they had brought women’s sizes.

Unisex shirts are, of course, just men’s shirts with a different label. And there are, of course, women who prefer the fit of that cut to shirts sold as women’s. But suggesting they work for everyone is just finding a new language for cheeping out. Arguably its worse than just forgetting that people come in different shapes since it shows someone thought about women looking for shirts but couldn’t be bothered to realize that most people want clothes that take into account their body shape. Ever met a guy who says he’s prefers how a woman’s cut shirt fits his body?

At least I didn’t hear anyone recommending using them as pajamas.

Cached JSON responses in Drupal 8

This week I was working on a Drupal 8 project that includes a page that uses Drupal as a simple proxy to convert a weak XML API into a simple JSON response the browser is willing to accept.

When I first built the site I hadn’t yet gotten my head around Drupal 8 caching, and so the JSON responses weren’t cached and therefore the page was slow. After some issues with the site caused me to have to look at this part of the project again I decided it was time to try to do something about this.

Drupal 8’s use of symfony means we have great access to tools for things like providing JSON responses.  Originally in the controller all I had to do was provide the JSONResponse class an array of data and it would handle the rest:

That’s all well and good if you don’t want your response to ever be cached, but Drupal provides a CacheableJsonResponse class the links up to the rest of the Drupal 8 caching engine to provide much better performance. But it turns out the docs kinda suck for explaining how to use it. After a great deal of digging I found this Question on StackExchange which gave me what I needed.

Early Thoughts on Drupal Governance Change

One of the things that the Drupal community has learned in the last few weeks is that our current governance structures aren’t working in several ways. Having spent a lot of time at DrupalCon talking about these issues I figured I share a few initial thoughts for those working on our new processes.

This isn’t the first time I’ve been part of a community that was changing how it organizes itself. In my religious life I am a Quaker, and for a long time I was a member of Philadelphia Yearly Meeting which is the regional organizing body for Quakers in the greater Philadelphia area. And I served for a time on some of their leadership committees. I’ve seen that 300+ year old group pass through at least three different governance structures, and while many of the fundamentals are the same, the details that matter a lot to people also change a lot.

My great aunt put it into perspective during one of the long discussions about change. When my wife asked her for her opinion of then pending proposal she just responded that it didn’t matter much to her as long as it worked for those willing to take leadership roles at the moment.

So as the Drupal community grows through a process to change our leadership structure here are the things I think it is important for all of us to remember.

  1. It will not be perfect.  We’re human, we will make mistakes, that’s okay.
  2. It will change again. I don’t know when or why, but whatever we do will serve us for a time, and then we’ll replace it again.
  3. Most of the community wont care most of the time. Most of the time, most of us don’t notice what Dries, the Drupal Association, Community Workgroup, and all the other groups that provide vision and leadership are doing.

I think we can all agree my first point is a given. I mention it mostly because some of us will find fault in anything done going forward. We should remember the people doing this work are doing the best they can and give them support to do it well.

On the plus side, whatever mistakes we make will be temporary because Drupal and its community will outlive whatever we create this time. We’ll outgrow it, get annoyed with the flaws, or just plain decide the change it again. Whatever we build needs to be built to be changed, improved, and replaced in the future.  Think about it like the clauses in the constitution designed to amend the constitution.

Finally, we should remember that community and project governance is insider baseball. Understanding how and why we have the leadership we do is like watching a pitching duel in a rainy day, most baseball fans don’t enjoy those kinds of games.  Most of the our community wants to use Drupal and they don’t want to have to think about how DrupalCon, Drupal.org, and other other spaces and events are managed. That will not prevent them from complaining next time there are problems, it is a fact of life those who do care should acknowledge.

Our community is stronger than we have been giving it credit for in the last few weeks. We need to be patient and kind with each other, but we’ll get through this and the divisions that will come in the future.

DrupalCon Baltimore Notes

I’m using this post as a place to store and share “notes” from DrupalCon Baltimore.  The part of conference notes I tend to find most useful are links and stray ideas I get talking with people.  I don’t tend to take detailed notes anymore since I rarely if ever go back to those, although on rare occasions I do re-watch a session if I found it particularly useful.

Basically this is a dump of links, pictures from various things, and a few stray thoughts. I’ll edit as the week progresses and probably add more thoughts and ideas.

Prenote: https://events.drupal.org/baltimore2017/balti-more-prenote-balti-most-fun-drupalcon (unmitigated silliness)

DriesNote: https://events.drupal.org/baltimore2017/driesnote

Import things to call out:

  • Claims we’re launching 15,000 D8 sites per month!
  • Field Layout module (experimental in Drupal 8.3 core) appears to be DS in core: https://www.drupal.org/node/2795833
  • BigPipe is ready for production.
  • Quick edit can do drag and drop image upload.

Greg Anderson’s PHP OSS Workflow tools: https://events.drupal.org/baltimore2017/sessions/development-workflow-tools-open-source-php-libraries

  • Some time is more important than others, like outages.
  • To find Drupal plugins on Packages: https://packagist.org/search/?type=drupal-drush
  • poser.pugx.org provides badges on packagist pages.
  • https://scrutinizer-ci.com/ “Sometimes any static analysis tools will give you answers you don’t like so just ignore it.”
  • https://www.versioneye.com/ uses the licenses from composer.json to check for both out of date and for compatible licenses. Not terribly useful internally, but user for open projects since you can link a badge to the result. Alternative `composer licenses` which is actually smarter.
  • Sami: A symfony component that does a JavaDoc like project for API documents. https://github.com/FriendsOfPHP/Sami

Baby Steps, Lessons Learned & Big plans for Drupal Diversity and Inclusion: https://events.drupal.org/baltimore2017/sessions/year-diversity-initiatives (Core conversations style 30 minute talk with 30 minutes questions).


Launching Online Stores with Commerce 2.x on Drupal 8 https://events.drupal.org/baltimore2017/sessions/launching-online-stores-commerce-2x-drupal-8

Drupal is Changing, Quickly: How and Why https://events.drupal.org/baltimore2017/sessions/drupal-changing-quickly-how-and-why

Composer Resources:


Project Estimates:

My free shirts from DrupalCon.

Technology and its workforce at ethics crossroad

https://events.drupal.org/baltimore2017/keynote-technology-and-its-workforce-ethics-crossroad

  • Humans don’t panic properly! We panic too late instead of when we can do something about it.
  • Programmers shouldn’t trust themselves since they don’t know what will happen with their work later. @zeynep keynote #drupalcon
  • Everything is multi-causal.
  • Toolmakers’ ideals don’t rule their tools.

  • Surveillance is Baked into Everything.
  • Dismantling structures of accountability
  • Labor Realities of New Economy

Raising the bar with guardr

https://events.drupal.org/baltimore2017/sessions/raising-security-bar-guardr

Watch later:

Additional Resources to checkout:

Fixing the Expert Beginner

I’ve been reading Erik Deitrich’s blog a bunch recently, particularly two pieces he wrote last fall on how developers learn. They are excellent. I recommend them to anyone who thinks they are an expert particularly if you are just starting out.

Failed Sticky bun
I am a good baker but this attempt at a giant sticky bun failed because I am not an expert.

In short he argues for a category of developer he calls the Expert Beginner.  These are people who rose to prominence in their company or community due more to a lack of local competition than raw skill.  Developers who think they are great because they are good but have no real benchmarks to compare themselves to and no one calling them out for doing things poorly.  These developers not only fail to do good work, but will hold back teams because they will discourage people from trying new paths they don’t understand.

I have one big problem with his argument: he treats Expert Beginning as a finished state. He doesn’t provide a path out of that condition for anyone who has realized they are an expert beginner or that they are working with someone who needs help getting back on track to being an actual expert.

That bothers me because I realized that at times I have been, or certainly been close to being, such expert beginner.  When I was first at AFSC, I was the only one doing web development and I lacked feedback from my colleagues about the technical quality of my work.  If I said something could be good, it was good because no one could measure it. If I said the code was secure, it was secure because no one knew how to attack it. Fortunately for me, even before we’d developed our slogan about making new mistakes, I had come to realize that I had no idea what I was doing. Attackers certainly could find the security weaknesses even if I couldn’t.

I was talking to a friend about this recently, and I realized part of how we avoided mediocrity at the time was that we were externally focused for our benchmarks.  The Iraq Peace Pledge gathered tens of thousands of names and email addresses: a huge number for us. But as we were sweating to build that list, MoveOn ran out and got a million. We weren’t playing on the right order of magnitude to keep pace, and it helped humble us.

I think expert beginnerism is a curable condition. It requires three things: mentoring, training, and pressure to get better.

Being an expert beginner is a mindset, and mindsets can be changed. Deitrich is right that it is a toxic mindset that can cause problems for the whole company but change is possible. If it’s you, a colleague, or a supervisee you have noticed being afflicted with expert beginnerism the good news is it is fixable.

Step 1: Make sure the expert beginner has a mentor.

Everyone needs a mentor, expert beginners need one more than everyone else. A good mentor challenges us to step out of the comfort zone of what we know and see how much there is we don’t understand. Good mentors have our backs when we make mistakes and help us learn to advocate for ourselves.

When I was first in the working world I had an excellent boss who provided me mentoring and guidance because he considered it a fundamental part of his job. AFSC’s former IT Director, Bob Goodman, was an excellent mentor who taught me a great deal (even if I didn’t always admit it at the time). Currently no one person in my life can serve as the central point of reference that he did, but I still need mentoring. So I maintain relationships with several people who have experiences they are willing to share with me. Some of these people own companies, some are developers at other shops, some are at Cyberwoven, and probably none think I look at them as mentors.

I also try to make myself available to my junior colleagues as a mentor whenever I can. I offer advice about programming, careers, and on any other topic they raise. Mentoring is a skill I’m still learning – likely always will be. At times I find it easy, at times it’s hard. But I consider it critical that my workplace has mentors for our junior developers so they continue progress toward excellence.

Step 2: Making sure everyone gets training.

Programming is too big a field for any of us to master all of it.  There are things for all of us to learn that someone else already knows. I try to set a standard of constant learning and training. If you are working with, or are, an expert beginner push hard to make sure everyone is getting ongoing training even if they don’t want it. It is critical to the success of any company that everyone be learning all the time. When we stop learning we start moving backward.

Also make sure there are structures for sharing that knowledge. That can take many different shapes: lunch and learns, internal trainings, informal interactions, and many others. Everyone should learn, and everyone should teach.

Step 3: Apply Pressure.

You get to be an expert beginner because you, and the people around you, allow it. To break that mindset you have to push them forward again. Dietrich is right that the toxicity of an expert beginner is the fact that they discourage other people from learning. The other side of that coin is that you can push people into learning by being the model student.

Sometimes this makes other people uncomfortable. It can look arrogant and pushy, but done well (something I’m still mastering) it shows people the advantages of breaking habits and moving forward. This goes best for me is when I find places that other colleagues, particularly expert beginners, can teach me. Expert beginners know things so show them you are willing to learn from what they have to offer as well. They may go out and learn something new just to be able to show off to you again.

Finally, remember this takes time.  You have to be patient with people and give them a chance to change mental gears.  Expert beginners are used to moving slow but it feels fast to them.  By forcing them into the a higher gear you are making them uncomfortable and it will take them time to adjust. Do not let them hold you back while they get up to speed, but don’t give up on them either.

Why I won’t wear your free t-shirt

With DrupalCon coming up I figured I want to talk about a question I will be asking vendors giving out t-shirts: do you have women’s shirts? I’ll than request a men’s large (since it’s the size that actually fits my body). Given the reminder this week about the problems in the Drupal community around misogynism – a series of events I’m not yet ready to comment on myself – this seems appropriate topic if not the most timely.

Close your eyes and picture a Drupal developer (go ahead I’ll wait). I can’t say who you saw, but too many sales managers for technology companies just pictured a man or group of men. They want those developers to think nicely of their company and to wear shirts with their logos. They will buy, and in a few weeks give away, t-shirts for the developers they just pictured. They will forget that our community is strong because we’re diverse, and gender is a critically important form of diversity for us.

Thinking about this through t-shirts isn’t a new or original idea. The first time I ran into a form of this discussion was this 2006 blog post from Kathy Sierra (which I probably read in 2007, so I’ve been thinking about this for 10 years). I was a big fan of her work at the time (and was until she was driven from tech circles shortly after), and the support she got from women on the topic was almost as influential on me as the attacks she received from men for daring to talk about her own body. And it’s not just tech: if you listened to the entire Planet Money t-shirt saga you hear the NPR staff complain about the same problem.

For me usually the conversation starts something like:

“Do you have t-shirts for women?”

“Yes, do you want one for your wife or girlfriend?”

“No, I’ll take a men’s large.”

[confused stare from salesperson followed by them giving me a t-shirt.]

Like many tech conferences, there are usually lots of chances to get free t-shirts. Usually from vendors giving them away free. For anyone who hasn’t thought about it, that t-shirt is meant to make you and I into walking billboards. It puts their brand in the minds of people in your office, neighborhood, and anyplace else you go. And it works. After I got home from New Orleans last year I wore shirts from several different hosting companies everyday for a week, and since we were talking about new hosting relationships at the time, I got questions about the company on my shirt each day – we do business with two of those companies now. So giving me a free t-shirt is a request for me to advertise on their behalf which could easily pay for itself.

A few years ago I was at DrupalCon with a female colleague who was attending for the first time. The all male dev team members had attended several times before that and she had always liked the interesting variety of t-shirts they came home with, and so was looking forward to finally getting something for herself. Only she didn’t.

Very few vendors had women’s shirts at all and none in her size. Even worse, DrupalCon itself didn’t have a t-shirt for her because the men who had checked in before she arrived had thought their female partners would like the design and had taken all the woman’s shirts.

I should have known this was a risk for her since it’s not like the topic was new, but I didn’t and felt while I felt bad about that doesn’t undo the insult.

Instead of making sure she got to fully participate in our ritual, we allowed her to be left out. Several years had passed since the Kathy Sierra triggered discussion and I wrongly assumed we’d made progress as a community. Oops.

As part of trying to apologize to my friend for my own cluelessness, and in part to try to do something to make our community better, I took up asking vendors with t-shirts if they have women’s sizes. Not because I want one for someone else in particular but because I want other people in general to have the same chances I have. And I am not willing to advertise for companies if they are making our community worse. Anything we do that makes women feel less welcome makes our community worse.

Over time I’ve had interesting conversations with people who have said both yes and no.

The people who say yes are sometimes interesting. Usually they are just confused because they never thought the issue through. Sometimes they cite Kathy Sierra, sometimes they cite a similar experience to my own. Usually we’ll exchange thank you’s and I’ll move on.

If they say no, the conversation goes a bit differently. I am always nice, but I don’t let them off the hook. I’ll ask “why not”.  With one exception the answers are unfulfilling.

The most common answer is “I don’t know.” While the salesperson is sure sure no offense was meant (as if they would tell me if one was), I generally offer to wait while they call their boss to figure out why they don’t want women to advertise for them (no one has taken me up on it yet).

The next most popular answer (usually offered right after saying “I don’t know” didn’t get me to go away)  “It’s too expensive to add those sizes.” Typically this is from a person who gives out hundreds or thousands of t-shirts a year. This just isn’t true at that scale. Most vendors are still going to order enough shirts to get over the same price breaks they would have with their current order, and every t-shirt they give a woman is one they didn’t give a man. The only way for this to really be true is if they end up giving away more total shirts because more people want them, which is the whole point of the exercise. The time a RackSpace employee gave me this answer I just stared at the woman, in a woman’s cut RackSpace t-shirt, and said “Really”?  The next year RackSpace had women’s t-shirts (this probably had nothing to do with me, but it’s nice to think it might have).

I’ll also sometimes get “We didn’t have room to pack them.” I usually get this answer from smaller vendors who may not have as many to give out as a company like RackSpace or Pantheon, and are therefore concerned about bringing shirts that won’t find a person to take them. But I’ve gotten it from big companies too who will admit shipping five or six boxes of shirts. Either way, sorry, but no, avoid insulting potential customers by splitting your packing space.

The final answer I hear is “Women don’t want them.” This is the go to excuse from men who don’t want to think about why women don’t participate in anything related to technology. I even got that response from a man planning a Drupal Camp when I pointed out that none of the women on the planning committee had shown any interest in having shirts at all – his daughter being one of them. When I commented that maybe they didn’t like not having shirts that don’t fit a wave of nodding followed: we had women’s shirts made.

If you are attending DrupalCon, or any other large event for that matter, please ask everyone giving out t-shirts about women’s sizes. If they say yes, take whatever you want, but if they say no I encourage you to think hard about if you want to advertise for them. And draw them into a discussion on the topic.

If you are bringing t-shirts to DrupalCon, or any other large event I attend, please bring t-shirts for as many different types and sizes of attendees as you can fit. The right ratio is a hard problem to solve, and I know you have limited space. Ask the conference for an estimate of attendee demographics and make your best guess. If you guess wrong that’s okay, apologize and try to do better next time.

Do I think refusing to take free t-shirts from tech companies will suddenly solve all our the gender issues? Of course not. But it does force people into conversations they aren’t used to having, and it makes at least some stop and think about ways we create unfriendly atmospheres for women in technology.