Wardley Maps for product development

Wardley Mapping is most commonly associated with higher level business strategy. When I’ve talked to people familiar with Wardley Mapping, they’ve been quick to dismiss it as a tool for the C-level suite, not for mere mortals developing products. I disagree. The following will attempt to explain why I find Wardley Maps not only relevant but vital to product development. If you’re unfamiliar with Wardley Maps, I recommend watching Simon Wardley’s 2017 Google Next talk for a good overview. If you want to take a deeper dive, I suggest Simon’s free online book.

Digital Beanie Baby: Husky
Welcome to the future. Digital Beanie Babies. Trade them on your favorite exchange!

Imagine. We’re transported to a time where it seems like anything with the label “beanie” is drawing attention, mostly because a new form of Digital Beanie Babies (DBB) has been skyrocketing in value for over 12 months. An entire ecosystem has sprouted up around the digital critters. In the midst of this beanie bonanza are exchanges launching to enable trading DBB, much like other exchanges exist for trading stocks, fiat currency (e.g. USD), etc. Each new DBB exchange has its strengths and weaknesses.

A few entrepreneurs identify an opportunity to create a new exchange that fills the gaps left by even the most successful DBB exchanges, while also adding a couple innovative features. They’re focused on meeting existing customer needs in a burgeoning market, not building a larger technical “platform” that has aspirations beyond being a very successful DBB exchange. The founders form their startup, get some technical people on board, build a proof of concept, raise funding, and continue building on the vision of providing a better DBB exchange for traders big and small.

But how does the startup know that they should build this product from the ground up?

Product development for this new exchange is focused on continuing the path the proof of concept set – build a secure, fast, trustworthy, and feature rich DBB exchange from the ground up. In such a new market space this seems reasonable. Put together a small, agile/lean development team and continue to build a product that meets the needs of its traders, validating the product as it is built. Lean startup style.

But how does the startup know that they should build this product from the ground up? Are there pieces they should buy? Higher level functional open source components they should adopt? The assumption is made that because DBB trading is a fairly new market it requires building a brand new product from scratch. Besides, many of the most successful DBB startups built their exchange from the ground up. They blazed a trail, this new startup is simply following in the path that’s cleared for them.

Enter Wardley Maps, a way to visualize the evolution of the underlying landscape anchored to the needs of users. When we map out the Digital Beanie Baby trading landscape, including high level components/requirements of a DBB exchange, we start to see that a number of core components of the exchange are available for purchase, leasing, and/or open source. After all, exchanges have been around quite a while in various forms.

Based on the product development approach the Beanie exchange startup is taking, we’d expect to see most of the exchange components and requirements in the “Custom-Built” or “Genesis/Novel” lane, but instead a majority of the core exchange features in development (highlighted in blue) fall into the “Product/Rental” lane or very close to it. What does this tell our startup? It’s telling them that the bulk of what they’re currently developing is something that has (probably) been built before and is available to buy, lease, or simply use (open source).

A common objection I hear at this point is: OK, but what if you’re wrong about the position of various items on the map? That’s quite possible. The potentially incorrect map positioning can drive meaningful discussions as well as further research to either validate or invalidate the position. The beauty with the map is that we’re: A) having the product/business strategy discussion based upon a shared visual aid and context B) able to identify our assumptions. In the case of our startup example, the biggest areas likely up for debate are core components (that they’re creating themselves) like the matching engine, order book, API, web app, etc. Maybe with some further digging the discovery is made that commercial offerings exist, but they’re immature, or expensive, or rigid, or any number of other issues that may make them less viable as options. Maybe we find that certain components are available as products, but are only really suitable for more traditional exchanges, not for those aimed at trading digital beanies. It’s also possible that we discover there are numerous existing components and products that fit our needs and validate the position of those items on the map.

The Wardley Map provides a higher level view that can help drive lower level product development decisions.

Another objection I’ve heard is that what I’m crediting to Wardley Maps is really just another path to market research that any business should already be doing. Possibly, but the map provides a shared context that market research does not commonly provide, as market research tends to end up buried in docs and slide decks. A group of people can look at a Wardley Map together and start to quickly identify areas of alignment, disagreement, opportunity, etc. Those with more industry expertise can be brought in to look at the assumptions on the map and determine if those assumptions are on track or need adjusted.

In our startup’s case, the map identified some potential blindspots in the product development approach. Should the exchange startup be building something from the ground up that is already available for purchase, rent, and/or adoption? Unless the devil is hiding in the details of those components mapped in the product lane, then it’s unlikely the startup should pour further (fairly limited) development resources into those items. 

It makes more sense for the startup to consider focusing its development time and talent on building items in the novel or custom lanes. Or, possibly focus the engineering team on implementing the items in the product lane, become experts on operating those in production (much sooner than the homegrown equivalent would be available), and then discover through real customer feedback what should be introduced on the exchange next. The possibilities the map opens up are much greater than what development teams tend to consider when they’re building a product, such as, should we: Scale back feature X, Y, Z? Reprioritize the backlog? “Pivot” to target only one subset of customer initially? Change our approach to development in order to increase velocity and lower time to market? Reset some or even all of our goals for the MVP? Those are all legitimate options to consider in product development, but they may be too nearsighted and ultimately limiting. A startup is particularly sensitive to this form of myopia, as the business and product the startup is building are so tightly coupled, it can be hard to determine where one ends and the other begins. The Wardley Map provides a higher level view that can help drive lower level product development decisions.

Adding Wardley Maps to a product development team’s toolbox is a valuable asset, even if at a first glance it’s hard to understand how. Mapping is not a silver bullet or even a tool that is immediately easy to grasp, but it’s worth learning. This example only begins to touch on all the nuances of Wardley Maps. There are many other nuggets of strategy gold to be found for those who take the time to learn how to create and collaborate with these maps.

Not about school

Consider this a parable of sorts for those building products. I’ll leave it up to the reader to determine its meaning.

Carl is a senior in high school and has a D in Algebra II heading into the last semester. He wants to bring his grade up to a B so that he can qualify for college scholarships. Quizzes and tests make up 80% of a student’s grade. The other 20% consists of completing homework (15%) and classroom work (5%). Carl’s Algebra II teacher, Mr. Smith, insists that Carl catch up on all his missing classroom work first, even though most of that work will not help on upcoming quizzes and tests. Mr. Smith works with his student to create a rather large yet well-defined backlog of all the classroom work Carl needs to catch up on so they can track his progress together. Carl diligently works on burning down that backlog. He finally catches up on the classroom work near the end of the school year. Mr. Smith pats him on the back. Carl’s final Algebra II grade is a D+.

A remote retrospective

It’s been a while since I last facilitated an all remote retrospective. Below is an email I sent out to the team I’m currently working with to help us prepare for our first “retro” together. We’ve since held the retro and it went well overall, so I thought this prep and guidance might be useful for others to iterate on.


Hi All,

On Tuesday we’re going to have a Project Retrospective (aka “retro”). In my experience, retros are hugely beneficial opportunities for teams to learn and grow.

Please take the time to read the rest of this email. It outlines how the retro will run. In order to make the most of our time, it’s best to come prepared. 🙂

Retro Goals

  • Learning jointly – From each other’s different perspectives, feelings, and current thoughts about where the team is at since launching the project.
  • Taking action Based on learning together, we identify where we can most benefit from improvement and take action.
  • Strengthening the team – We’re in this together. By listening, learning, and taking action on what we’ve learned, we develop a stronger bond that is bigger than “just the work”.

Ground Rules

Regardless of what we discover, we understand and truly believe that everyone did the best job he or she could, given what was known at the time, his or her skills and abilities, the resources available, and the situation at hand.

  1. Be respectful
  2. Be present (no phones, no “side chats/conversations”, no browsing, etc.)
  3. Everyone gets a turn to speak
  4. No interrupting
  5. No judgement on feedback (use “I statements“)

Before The Retro (between now and when we meet)

Please take time between now and when we meet to think about the following in relation to your experience and/or what you observed during your time with the TGE project:

  • What you want us to continue doing
  • What you’d like us to start doing
  • What you’d like us to stop doing

You can add your items to this doc, which we’ll use as part of the retro: Google Doc

The Start

Check-in: We’ll go around the call and have everyone provide one word for how they’re feeling in the moment. Have trouble coming up with a word for how you’re feeling? I know I do sometimes! Try this to help identify a word: https://verbaliststravel.files.wordpress.com/2016/01/the-language-and-vocabulary-wheel-for-feelings-verbalists.jpg

The Middle

Part 1) We’ll use the “Before the Retro” section above to guide the initial discussion. What we want to: continue, start, and stop doing. If you haven’t added your items to each area, we’ll have a short time for everyone to add to each list.

Part 2) We’ll go through each item and open it up for questions/clarification. I will do my best to encourage open, focused discussion that honors our time.

Part 3) Everyone gets 3 votes per area to put against the items they think we should take action on now, not later. You can apply more than 1 vote to an item if you feel that strongly about it.

Part 4) Identify the top item in each area and determine next steps (which can be as simple as identifying an owner to drive the action post-retro). …But what about the other items – aren’t they important too? Yes! But focus is key. Just because an item isn’t made “top priority” doesn’t mean it won’t see progress in the future.

I’m accountable for ensuring the 3 items we identified to take action on make progress. Don’t expect miracles. Some things require a a fair amount of determination over a period of time to show results. My commitment is to continue to provide visibility to the items and help move them forward. Expect this to be part of our weekly meetings, even if it’s just a quick update.

The End

Check-out: Everyone on the call gets a brief (30 seconds or less) opportunity to express closing thoughts/feelings now that the retro is at a close.

Looking forward to learning and improving with you all!


Deploying a Python Flask web app on AWS Lambda

The best server is no server?

OK, servers are still involved with “serverless computing“, but not ones that you and I need to worry about maintaining and scaling. While serverless platforms like Amazon’s AWS Lambda, Google’s Cloud Functions, IBM’s OpenWhisk, Microsoft’s Azure Functions, and others aren’t the right fit for every need, I’m beginning to think they’re applicable to more apps and services than not.

I’ve been playing around with AWS Lambda for a little while now. After getting a number of functions up and running, I started to think about how this platform might be applicable for web apps. While I’ve built a Slack app using Node.js, I have to admit I missed the elegance of Python.

I settled on getting a little web app based on a Python web framework up and running on Lambda. I wanted the deployment to be as painless as possible (i.e. easily repeatable once configured). For this exercise I didn’t care about integrating with outside services. I was fine with running against a local SQLite database, knowing I could switch over to RDS or another database at another time. Here is what I ended up selecting for this task:

I chose Flask because it’s well regarded and simple to get running. I chose the Serverless framework (versus something like Zappa) because Serverless provides the ability to deploy Python and non-Python based projects quickly while also allowing you to deploy to other cloud providers like Google, Microsoft, etc. I chose the Flaskr app because it’s simple but not too simple.

Before we get started

There’s quite a bit that needs to be setup and running before my howto below will work for you. Here is what I expect to be running:

Also, my instructions assume you’re on Linux or Mac. If you’re on Windows, you’ll need to adjust the commands for your environment.

How to get it all running

  1. Setup Serverless and the Flaskr app locally
  2. Modify SQLite code to run in Lambda (and locally)
  3. Configure the Serverless deployment
  4. Deploy to AWS
  5. Remove from AWS
1. Setup Serverless and the Flaskr app locally

In a terminal session run the following:

# Install Serverless globally
npm install -g serverless

# Create a flaskr in our home directory and clone the flaskr project
mkdir ~/flaskr
cd ~/flaskr
git init
git remote add -f origin https://github.com/pallets/flask.git
git config core.sparseCheckout true
echo "examples/flaskr/" >> .git/info/sparse-checkout
git pull origin 0.12-maintenance

# Move the flaskr project out of the examples dir & get rid of the examples dir
mv examples/flaskr .
rm -r examples
cd flaskr

# Install the Serverless WSGI plugin locally
npm install --save serverless-wsgi

# Create the Serverless AWS Python template
serverless create --template aws-python

# Add Flask 0.12.2 as a requirement
echo "Flask==0.12.2" >> requirements.txt

# Make flaskr runnable
export FLASK_APP=flaskr
sudo -H pip install --editable .

# Initialize the database
flask initdb

These commands install the Serverless framework, downloads the Flaskr app from Github, sets up the app to run with Flask, and initializes a local SQLite database with the necessary table. If all goes well, you should be able to start up Flaskr locally:

flask run

In this case I can access in my browser and see something like this:

2. Modify SQLite code to run in Lambda (and locally)

We need to modify the flaskr/flaskr.py file in order to get SQLite to work in Lambda. In case it wasn’t already obvious, this setup is not meant for production. With that out of the way…

Modify the replace the app.config.update section with the following to configure the SQLite database file to be created in /tmp:


    SECRET_KEY='development key',

Then look further down in the file and modify the @app.route(‘/’) section with the following:

def show_entries():
    db = get_db()
    entries = {}
        cur = db.execute('select title, text from entries order by id desc')
        entries = cur.fetchall()
        entries = {}
        return render_template('show_entries.html', entries=entries)

The above change tries to query the database and if there’s an exception, will attempt to call our init_db() function to create the SQLite database and set an empty entries variable.

3. Configure the Serverless deployment

Now we need to setup our Serverless deployment by setting the serverless.yml file to:


service: test

  name: aws
  runtime: python2.7

    - node_modules/**

  - serverless-wsgi

    handler: wsgi.handler
      - http: ANY {proxy+}
      - http: ANY /

    app: flaskr.app

These settings tell AWS we have a Python based function to run, we’ll use the serverless-wsgi plugin, all http requests are to be handled by the WSGI handler to run our flaskr.app. Note we need to explicitly set events to respond for “/” even though we have the catch all entry of {proxy+} set. If we don’t, AWS API Gateway will return an error of Missing Authentication Token.

Let’s test this locally one last time before we deploy to AWS:

sls wsgi serve

You should get a message telling you where the Flask app is running (e.g. http://localhost:5000) to the one above, complete with a locally running instance of the flaskr app.

4. Deploy to AWS

Now we’re ready to deploy to AWS:

sis deploy -v

This can take a little bit to run, as this single command takes care of all the AWS setup for us to access our flaskr app via Lambda. When successful, you should see output towards the bottom similar to the following:

Stack Outputs
FlaskrLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:770800358818:function:test-dev-flaskr:31
ServiceEndpoint: https://zwe667htwd.execute-api.us-east-1.amazonaws.com/dev
ServerlessDeploymentBucketName: test-dev-serverlessdeploymentbucket-s03hsyt0f0oz

Copy the URL from the ServiceEndpoint and access it in your web browser. You should see something familiar:

If you don’t get a response or see an error of some sort, it’s time to look at the logs on AWS:

sls logs -f flaskr -t

If you want to make changes to the app (e.g. change templates, modify routes in flaskr/flaskr.py, etc.) and don’t need to make changes to your serverless.yml file, you can do a much quicker re-deploy of the code (i.e. no AWS configuration):

sls deploy function --function flaskr
5. Remove from AWS

Once you’re done with these steps, it’s a good idea to remove your function so that you don’t get unexpectedly charged for anything related to this deployment. Don’t fret, it’s only one line to get it all running again. 🙂

sls remove

Where to from here?

I may get this example working with a proper database. If I do, I’ll be sure to add a new post explaining how I did that.

Silver bullets


In folklore, a bullet cast from silver is often the only weapon that is effective against a werewolf, witch, or other monsters.


I’m not sure how many of us in tech are hunting werewolves, witches, or monsters, but there are A LOT of us looking for silver bullets. Take one look around at the world of software development and operations today and it’s baffling. A perfect example of what I’m talking about can be found in this CircleCI blog post, which sounds like nonsense but actually sums up the current state of software development and operations quite nicely. Maybe we’re not looking for silver bullets. Maybe we’re looking for the gold bullet, then the platinum bullet, then we move onto missiles, bombs, etc. It never ends.

I’m not talking about the evolution of technology as a whole. We have a desire to always learn and progress. What we have in software development and operations today is a hyper spin cycle of the next shiny object. Very little of it gets mature enough before it’s thrown out in favor of the new-new silver bullet. Unlike the last silver bullet, this one will kill werewolves AND witches. If you’re a software engineer caught up in this never ending hype you can find yourself using all the latest and hottest tech with so much complexity it will melt the minds of mere mortals. This happens rather easily because the hottest tech often comes from companies like Google, Facebook, Netflix, etc. who are solving extremely large and complex problems. They are generously (and often strategically) open sourcing a lot of that work, which turns into the hottest tech of the month club. But most of us are not solving problems at that scale. When we take their tech and apply it to our problem we can easily find ourselves with a lot of moving parts when only a few would likely suffice for our problems. Multiply this problem by the output of the firehose of “innovation” happening. I put innovation in quotes because what comes to us in the guise of innovation is often a company’s hope to ever so slightly improve upon a good enough solution and take away market share in the process. Even when there is legit innovation, the benefits of adopting a brand new stack or even layer in the stack are questionable when weighed against building upon a solid foundation.

Again, to get the best grasp of what I’m referring to, read the CircleCI blog post. It’s short, funny, and maddening all at once. We need to stop the never ending pursuit of the silver bullet and figure out a more sustainable way to build great services people find value in. Otherwise, I’m afraid we’re spending too much of our time porting or, worse, figuring out how to port existing stuff that works well onto something that is now deemed “better”.

Cloning VirtualBox images (or how I save hours a day when testing software)

First things first. If you’re testing software and you’re not using some sort of virtualization solution, stop reading this and go install one. My product of choice is VirtualBox. It’s free (as in no cost and most of it is open source), user friendly, runs on an Ubuntu host computer and I’m familiar with it.

Lately I’ve been doing a lot of testing of the Ubuntu One desktop software and I need to be able to quickly get various versions of Ubuntu up and running. Below I outline how I do that on an Ubuntu host computer. My steps assume that you’re familiar with VirtualBox enough that you know how to setup a virtual machine (VM) already.

Create a master image

The master image is the one we’ll use to clone test images off of. By doing this we can worry about keeping our master image up-to-date and configured the way we need it and then simply clone that image when we have to test.

  1. Create a new VM in VirtualBox and install the OS  (see Lifehacker’s guide if you’re not sure how to do this)
  2. After restarting the VM when the install is done, install all the latest updates on the master image and restart
  3. Install the VirtualBox Guest Additions (allows nice integration with the host computer)
  4. Shutdown the master image

Periodically you’ll want to make sure your master image has all the latest updates, so just boot it up, install the updates and then shut it down.

Clone the master image

Now we’re ready to start testing some software. Instead of using the master image we created above, we’re going to clone that image. This should take less than 5 minutes start to finish.

  1. In a terminal session do the following:
    cd ~/.VirtualBox/HardDisks
    VBoxManage clonehd master_image.vdi test_image.vdi --format VDI
  2. In VirtualBox, create a new VM by clicking the New button
  3. Go through each screen selecting the appropriate values and clicking the Next button until you get to the Virtual Hard Disk part
  4. Select the Use existing hard disk radio button
    VirtualBox Hard Disk Setup screenshot
  5. Click on the folder icon next to the pull down menu listing existing VDI files
  6. Click the Add button
    Add VirtualBox VDI screenshot
  7. Select the image you created (should be in ~/.VirtualBox/HardDisks) to add it to the list of available hard disks
  8. Click on the image you just added and then click the Select button
  9. Click the Next button
  10. Click the Finish button

You now have a brand new VM to use for testing. Once you test with this image and decide its usefulness is over you can delete the virtual disk image (VDI) file in ~/.VirtualBox/HardDisks, repeat step 1 above to create a new cloned image, and then edit your cloned VM in VirtualBox to use the new clone image. In other words, you don’t have to setup a new VM (steps 2-10) every time you want to use another VDI if you don’t want to.

Review The Tests, Then The Code


Last week I was talking with one of the developers at work and he was telling me about improvements his team was making in regards to (informal/desk check) code reviews. I told him that was great and then followed that up with a recommendation on how to improve even more.  Next time there is a code review, start with the tests. This will do two things: 1) Stress the importance of having tests 2) Make the review go quicker, as the tests will either be there and make the intent of the code clear or they won’t be there and the review is postponed until tests are in place.

I know I’m not the first to make this suggestion, but I felt it was worth repeating. Code reviews do have value, even when you pair program. At least, I think they do. Pair programming provides two sets of eyes on the code at the time of creation, but it’s surprising what someone who hasn’t seen the code before will find during a review.

Oh, and if reviewing the tests during a code review doesn’t make the intent of the code any clearer, then I suggest the team investigate behavior driven development (BDD). I’m becoming quite partial to the Cucumber framework for BDD, as I like it’s emphasis on user stories with acceptance tests/examples written in plain text and backed by executable steps.

The Customers Disappear Right Before Our Eyes

Tonight I was foolish enough to think my family and I could waltz into a restaurant on Valentine’s and get a table without much trouble. We were trying a restaurant we hadn’t been to before and I realized as soon as we pulled into the parking lot this probably wasn’t the best night to experiment. We went inside anyway to see how long the wait was. Much to my surprise, the hostess told us it was only about a 15-20 minute wait. I looked around the restaurant and, while it was full, there wasn’t a large number of people waiting on tables. We got on the waiting list and then proceeded to wait.

What I saw during the wait was kind of surprising. I noticed that the staff were diligently doing their jobs, quickly moving from one spot to another. I had to be careful not to step too far away from the waiting area or I was sure to bump into one of the busy bee workers. And while the staff was incredibly focused on the operations of the restaurant, I couldn’t help but notice they were almost oblivious to their customers, whether those customers be waiting for a table, eating their meal, or somewhere in between. I looked around the restaurant of about 40 tables and noticed that at any given moment there were numerous people looking to get the attention of their waitress. Customers coming in through the door were rarely greeted in a timely manner. Those of us waiting for a table were ignored completely, even as our original wait time came and went.

It dawned on me that this situation is not unlike what happens with some software development projects. We get in the groove of producing the software and never take time to make sure we’re satisfying the customer. Yes, those of us practicing agile have the advantage of delivering in short iterations which, at worst, won’t allow a project to go too long before the customer is back in the mix. But, even on agile projects, I’ve seen teams go through an entire iteration without giving much thought to the customer’s needs beyond the initial planning meeting. We think we understand exactly what the customer wants, can’t or simply don’t get continuous feedback from the customer during the iteration, and we develop the functionality. We become like the restaurant’s staff, who are so busy running the restaurant that they forget about the very people who really keep the restaurant running, the customers. Sure, the orders are taken, the food is getting out to people, drinks are refilled, new people are put on the waiting list, etc., but the customers aren’t satisfied, let alone happy. The software gets designed, written, documented, tested, etc. but the customers aren’t satisfied, let alone happy. Sound familiar?

Tonight was a good reminder that technical and operational excellence is critical to delivering a good customer experience, but if we lose sight of the customer in that process then we will fail miserably. We need to be diligent about keeping constant contact with the customer and focusing on the value we’re delivering. We don’t want our customers to walk away from us like my family and others did on the restaurant we attempted to eat dinner at tonight.

One Smart Cucumber

I was messing around with some Ruby stuff tonight and was reading up on the Cucumber project. Cucumber is a behavior driven development (BDD) testing tool.

Anyone who talks to me about user stories knows I’m kind of a stickler on the value statement.  I think I’ve found a kindred soul in Aslak Hellesoy, the creator of Cucumber. The following comes from the Cucumber documentation.

You should discuss the “In order to” part of the feature and pop the why stack max 5 times (ask why recursively) until you end up with one of the following business values:

  • Protect revenue
  • Increase revenue
  • Manage cost

If you’re about to implement a feature that doesn’t support one of those values, chances are you’re about to implement a non-valuable feature. Consider tossing it altogether or pushing it down in your backlog. Focus on implementing the MMFs (Minimum Marketable Features) that will yield the most value.

Here is an example taken from an IRC chat session in #cucumber:

[5:08pm] Luis_Byclosure: I'm having problems applying the "5 Why" rule, to the feature
                         "login" (imagine an application like youtube)
[5:08pm] Luis_Byclosure: how do you explain the business value of the feature "login"?
[5:09pm] Luis_Byclosure: In order to be recognized among other people, I want to login
                         in the application (?)
[5:09pm] Luis_Byclosure: why do I want to be recognized among other people?
[5:11pm] aslakhellesoy:  Why do people have to log in?
[5:12pm] Luis_Byclosure: I dunno... why?
[5:12pm] aslakhellesoy:  I'm asking you
[5:13pm] aslakhellesoy:  Why have you decided login is needed?
[5:13pm] Luis_Byclosure: identify users
[5:14pm] aslakhellesoy:  Why do you have to identify users?
[5:14pm] Luis_Byclosure: maybe because people like to know who is
                         publishing what
[5:15pm] aslakhellesoy:  Why would anyone want to know who's publishing what?
[5:17pm] Luis_Byclosure: because if people feel that that content belongs
                         to someone, then the content is trustworthy
[5:17pm] aslakhellesoy:  Why does content have to appear trustworthy?
[5:20pm] Luis_Byclosure: Trustworthy makes people interested in the content and
                         consequently in the website
[5:20pm] Luis_Byclosure: Why do I want to get people interested in the website?
[5:20pm] aslakhellesoy:  :-)
[5:21pm] aslakhellesoy:  Are you selling something there? Or is it just for fun?
[5:21pm] Luis_Byclosure: Because more traffic means more money in ads
[5:21pm] aslakhellesoy:  There you go!
[5:22pm] Luis_Byclosure: Why do I want to get more money in ads? Because I want to increase
                         de revenues.
[5:22pm] Luis_Byclosure: And this is the end, right?
[5:23pm] aslakhellesoy:  In order to drive more people to the website and earn more admoney,
                         authors should have to login,
                         so that the content can be displayed with the author and appear
                         more trustworthy.
[5:23pm] aslakhellesoy:  Does that make any sense?
[5:25pm] Luis_Byclosure: Yes, I think so
[5:26pm] aslakhellesoy:  It's easier when you have someone clueless (like me) to ask the
                         stupid why questions
[5:26pm] aslakhellesoy:  Now I know why you want login
[5:26pm] Luis_Byclosure: but it is difficult to find the reason for everything
[5:26pm] aslakhellesoy:  And if I was the customer I am in better shape to prioritise this
                         feature among others
[5:29pm] Luis_Byclosure: true!

I was impressed to find that section in the documentation. Not only do the docs detail basic usage but they go into the deeper discussion of how to apply agile principles using Cucumber. The balancing act of teaching principles and practices at the same time is no small feat. To find that in software documentation is pretty amazing.

P.S. One of my worst titles ever, I know. I think I was subconsciously inspired by the Hallmark Movie my wife had on a couple nights ago. I now realize I missed my calling as a greeting card writer.

Apache Shindig PHP Setup Problem Solved

First things first. Shindig is an Apache incubator project that serves as an OpenSocial Container and…I’m already falling asleep. Too boring. I’m way behind the curve on all things “social networking” but I have an idea for an app that may scratch an itch I have, and it just happens that some of this social networking stuff might be a good way to jump start the idea. So that means catching up on a couple of years (or more) of stuff that’s been going in the world of web 2.0, which includes OpenSocial. I wanted a local OpenSocial test sandbox and found Shindig to fit that bill.

Now, onto the problem I was running into and the solution. Unless you want the long boring details, I can save you the trouble and tell you to make sure you have mod_rewrite enabled in Apache.

If you haven’t dozed off by now then it probably means you’re running into issues with the Shindig PHP setup and would like some more details. I followed the directions on setting up the PHP Shindig server on my laptop running Kubuntu 08.04 here at home and kept getting a 404 error. I thought that was strange since I could hit other files with my browser that I put in that directory manually for testing but not the Shindig index.php page. Turns out the Shindig index.php page tries to be more “controller/servlet” like by sniffing the URI and passing it along to the appropriate handler. If it can’t find a match, then it gives a custom 404 error. I noticed the test URI (http://shindig/gadgets/ifr?url=http://www.labpixies.com/campaigns/todo/todo.xml) didn’t have any reference to index.php. Ah yes, the wonders of Apache mod_rewrite! And guess what I didn’t have enabled? Yep, Apache mod_rewrite. So, below is what I did to get things running on an Ubuntu setup from scratch (meaning no Apache 2, PHP 5 was installed or configured):

sudo apt-get install apache2 apache2-common apache2-mpm-prefork apache2-utils ssl-cert libapache2-mod-php5 php5-cli php5-common php5-curl php5-mcrypt

svn co http://svn.apache.org/repos/asf/incubator/shindig/trunk/ /home/jhoover/dev/shindig

sudo mv /etc/apache2/mods-available/rewrite.load  /etc/apache2/mods-enabled/

sudo cp /etc/apache2/sites-enabled/000-default /etc/apache2/sites-enabled/shindig

sudo pico /etc/apache2/sites-enabled/shindig

Stop laughing, I use the Pico text editor. I’m, as my son would say, “weak sauce”. I know. Anyway, here’s what I have in that virtual host file:

NameVirtualHost *
  ServerAdmin [email protected]
  ServerName shindig

  DocumentRoot /home/jhoover/dev/shindig/php
  DirectoryIndex index.html index.php
  <Directory />
    Options FollowSymLinks
    AllowOverride All

  ErrorLog /var/log/apache2/error.log
  LogLevel warn

  CustomLog /var/log/apache2/access.log combined
  ServerSignature On

Once we have that in place, we need to edit our host file:

sudo pico /etc/hosts

Append the following to the hosts file and save:       shindig

Time to restart Apache:

sudo /etc/init.d/apache2 restart

Now you should be able to go to your web browser of choice and run the demo/test app:


If all went well you should see something a little like this: