What I learnt from my old boss that made me quit

I resigned from my job nearly two months ago. We had recently hired someone that could easily step up into the vacancy I was leaving, so I could handover and be out of there quickly. There were lots of reasons for resigning. The main one was that my wife needed more help raising our baby daughter. Spending all that time at work, while my wife was struggling alone just didn’t make sense.

After a couple of months of being home with my family and working on getting CS Workflow ready for people to check out, I have had time to reflect.

There are three key lessons I learnt from my ex-boss. All three lessons contributed to me quitting.

There is no tomorrow

My boss used this phrase to create a sense of urgency. To me it meant to do whatever we were discussing right away. To do something right away, or as quickly as possible, I had to strip the task down to the bare essentials, so that no time was wasted. This would result in a balancing act of meeting the time expectations and putting something to the market that I could be happy with.

More often that not, my professional pride for crafting things to a high standard and with best practices didn’t matter as much I thought, going by the results. Usually that professional pride comes from imagining my peers judging my work.

“There is no tomorrow” forced me to focus on what’s important. In a small business that’s the customer and making sales as soon as possible. Waiting until tomorrow means one more day that revenue isn’t coming in.

This led me to resign because one more day of my wife struggling at home alone was one too many.

Act now.

Have the end in mind

My boss used this phrase to remind me that everything needed a purpose. I am goal oriented anyway, but I like this phrasing.

It’s very easy to lose sight of the end when juggling lots of competing priorities with limited resources. The trap becomes doing whatever is necessary to check tasks off the list.

“Have the end in mind” links to the previous lesson, because it provides the context to be able to judge what is important.

This led me to resign because I knew as Marketing Director I could help achieve 10 times growth for his company. Achieving this would take at least two years of my life. The end would be everything I learnt along the way and the reputation of the achievement, which would make it easier for me to get my own company off the ground, which is my real goal.

However, why invest in his company when I can invest in my own company now. In two years the things I will have learnt on my own will be more relevant to my real goal. Starting a business now has big risks, but there is no guarantee that working with my boss would significantly increase my chances of success.

Know why.

Be brazen

This wasn’t a phrase used by my boss. It was how he acted and was clearly evident in the decisions he made.

For example, there’s a line in marketing that marks the edge of what’s considered acceptable by customers and prospects. Crossing that line can be damaging to a brand. My boss didn’t think about that line and pushed to go beyond it. Again, crossing that imaginary line never really mattered. In fact, the results were usually positive.

What I learnt was to be less fearful of taking risks and to not place arbitrary lines between possible and impossible.

This led to me resigning, because I stopped worrying about the perception and impact on my relationships at work. Instead, I let my actions be guided by my goals and decided to trust that my heart knew best.

Don’t be led by fear.

Be careful what you say about your competition

People don’t like it when someone is attacked, especially when the attack seems unjustified or there’s an underdog being attacked. This is a reasonably common human trait that still operates in the world of business.

So, if you are up against a competitor with a prospective customer you should tread carefully. I’d recommend that your proposal talks about only about the way you’ll solve their problem. Remember that part of the problem they have is in choosing a solution amongst different vendors. Build trust in your brand and solution.

Don’t go cross the line into slamming the competition. This erodes trust very quickly. You don’t know the relationships the prospect has or where that information will end up. You had better hope all the facts you used about the competition are totally squared away.

Be a company others want to do business with. And stop helping the competition.

Getting selected text with Rails and Turbolinks

I have to start by confessing that I don’t know what it is about Turbolinks that caused the issue I was having. I’m only edu-guessing that Turbolinks is the cause.

So…I needed to know the text that the user had selected with their cursor. This would be used to create context for the comment they wanted to make on the text. I started by using a popular method I found on Stack Overflow.

function getSelectionText() {
  if (window.getSelection) {
    return window.getSelection().toString();
  } else if (document.selection && document.selection.type != "Control") {
    return document.selection.createRange().text;
  }
}

This worked fine in a static proof of concept. It also initially worked in my Rails project. By initially I mean after a browser refresh. As soon as I navigated to other pages and retested the function fell through and returned nothing. The rest of my javascript is fine. I am displaying a positioned button after text is selected and once clicked, the button performs an action with the selected text. This all works as expected.

I don’t know enough about the DOM or getSelection method to figure it out on my own. I set Google on it, which turned up a different function from the rest.

function GetSelectedText() {
  var selectedText = (
    window.getSelection
    ?
      window.getSelection()
    :
      document.getSelection
      ?
        document.getSelection()
      :
        document.selection.createRange().text
  );
  if (!selectedText || selectedText=="") {
    if(document.activeElement.selectionStart) {
      selectedText = document.activeElement.value.substring(
        document.activeElement.selectionStart
        . document.activeElement.selectionEnd);
    }
  }
  return selectedText;
}

That is now working. Or at least it fixes my previous bug. It’s the nested if where selectedText is blank that solves it. I don’t like the if else in the selectedText initiation so I’m using the original function is start with.

My pillars of marketing strategy

I keep coming back to the same three pillars when developing marketing strategies. This is regardless of industry, company size, customer type, and channel. These pillars are awareness, engagement and innovation. There’s nothing complicated or ground-breaking here, just a simple structure I like to work with.

Awareness

Awareness covers all growth-focused activities, like attracting new customers and spreading the brand. Examples are SEO, paid search and press releases. Success metrics depend on the business model, but could include new registrations, total site traffic, search traffic, or social mentions. And yes, those are vanity metrics. Awareness on its own won’t lead to success.

Engagement

Engagement covers all conversion and satisfaction-focused activities. Engagement aims to move customers further along from having some initial interest to being paid customers and beyond. Examples are having a sales website, customer support, trial onboarding experience, and educational newsletters. Generally success metrics are paying customers, monthly/weekly active users and satisfaction scores, like net promoter score. Again this depends on the business model.

Innovation

Innovation is the positive reminder to solve my own problems. It’s very easy to copy what competitors are doing or what was in an article someone successful wrote. Common wisdom and current trends only go so far. Creativity and rigorous scientific execution are the next level shit.

 

All very straight-forward. It’s all about answering these questions:

  • How will new people find out about my company?
  • How will I convert them to customers and keep them happy?
  • What best suits my budget, customers and company?

Attaching PDFs to emails with Prawn and Rails

Yesterday I released a very simple tool to help copywriters get better briefs. I had a couple of days dev time up my sleeve while other parts of the main CS Workflow project are getting worked on.

What I ended up with was a simple signup for copywriters. This generates a token that, when part of a URL, associates the brief with the copywriter. The briefs are a tableless model and are only saved as an attached PDF that is sent to the copywriter. Simple.

I decided to use Prawn over the other options after watching the railscast (requires pro subscription) on the topic. It gave me the most control over the rendered PDF. For this project I used Rail 4.0.0.beta1.

To start I added Prawn to my Gemfile and ran bundle. The latest version was 0.12.0 at writing.

gem 'prawn', '~> 0.12.0'

I found out that through an error message that Rails 4 already has the PDF mimetype registered, so that part of the railscast can be skipped.

I rendered a test PDF in the browser so I could make sure it looked how I wanted before attaching it to an email. Refreshing the browser displayed the changes. To get this working I created a ‘test’ action in my briefs controller and added that as a route.

def test
  @brief = Brief.new(test_brief)
  @user = User.find_by_email("ben@csworkflow.com")
  respond_to do |format|
    format.pdf do
      pdf = BriefPdf.new(@brief, @user)
      send_data pdf.render, filename: "brief_#{@brief.name}",
                            type: "application/pdf",
                            disposition: "inline"
    end
  end
end

Following the same pattern as the railscast, I created a BriefsPdf class that inherited from Prawn::Document. This initializes, taking the arguments, which are my objects, then calls methods that render boxes and text. It’s a bit hacked together, but you get the picture. I kept the testing output, so that’s what the class renders.

The biggest “gotcha” I came across was with using bounding boxes and text boxes. The cursor, which moves down the page as it renders, behaves differently with those boxes. I ran into trouble with my two bounding boxes, because if the cursor is moved to the bottom of the right box. If the left box is higher I got overlap. With text boxes the cursor doesn’t move down at all. You have to move it manually with move_down. This is fine if you know the height of the box. With user input you don’t have control. That’s why I’m not using text boxes.

The mailer is the simplest part of the whole process.

def send_brief(brief, user)
  @brief = brief
  @user = user
  filename = "brief_#{@brief.name.parameterize(sep = '_')}_#{Time.now.strftime('%Y%m%d')}.pdf"
  attachments[filename] = BriefPdf.new(@brief, @user).render
  mail(to: @user.email,
       cc: @brief.email,
       subject: "New brief from #{@brief.name}")
end

I’m using a dynamic file name for the PDF, so the client and copywriter have a reference. The actual attachment is a single line.

There you have it. I’ll be using this same technique for creating invoices and subscription agreements.

Here’s the list of resources that guided me: