My last post gave a simplified overview of the developer process behind this approach. I showed how the dev teams would create a set of helper functions to generate these dictionaries server-side. These functions would then be called whenever a new interaction is “packaged” up. The resulting
interaction dictionary is then passed off as a whole to Google Tag Manager for the next stage in the process.
But now it’s time to go back to the start, the actual process for fleshing out and managing these dictionaries before any code is written.
Warning: Seriously unconventional analytics work ahead (done for ecommerce but concepts apply to other business models). From here onwards it can get pretty geeky at times. I’m using this series of posts as a way document the process for myself.
1. Identify interactions and associated business entities
Remember the anatomy of an interaction
Every interaction follows (more or less) this structure:
subject + verb + object + context +
Document ALL interactions fully then prioritise them
Use wireframes or dev/live website walkthroughs to document all interactions of interest. Must seek to document the interaction fully and that involves identifying all of the things that are directly or indirectly part of it or affected by it. Write it down in plain English, being as precise and comprehensive as possible. Don’t forget to document trigger elements (for client-side events). Prioritise them (I use MoSCoW tags for this).
- user clicks on carousel image in
- user clicks on thumbnail image for
productin snippet on
Go through the interactions and make a list of all the nouns. Identify nouns that keep coming up or are somehow alike. Some are obvious (like
product), others not so much (carousel image and thumbnail image are alike — they’re both
calls to action).
First, identify business entities
Of the nouns found, which ones are fundamental to the business model? These are the first-class entities we’ll be building dictionaries for. Which nouns are important but not critical? If in doubt, ask yourself, will you ever need to compare one instance against another to answer a question? Does the noun support a first-class entity? If answer is yes, then that noun is also an entity (but a second class one).
- First class entities:
checkout, etc — (these are critical).
- Second class entities:
search result collectionetc — (these not as much OR they support 1st class business entities).
Then, identify other reoccuring nouns
All of the other nouns that keep coming up act as simple interaction objects or they form the interaction context. We’ll build dictionaries for these too (even though we aknowledge that they’re not business entities). They’re most likely related somehow to the business entities we care about the most.
call to action,
form field, etc — These might be part of the context, they might be the interaction trigger OR might even act as generic “base” objects that entities are built upon (e.g. a
promo is also a
call to action whilst being so much more than that).
Identify entity – interaction associations
Go over interactions again and see which ones are actually about a business entity (regardless of the interaction object). Explicitly document the entity in a separate column.
Summarise the interaction and its elements
Summary should include: interaction name (choose wisely, this needs to be unique and will show up in reports; needs to be self-explanatory yet brief), interaction category (a roll-up term for multiple related interactions; will be used in reports), subject, object, business entity it directly relates to, and last but not least, context objects and entities.
This interaction is unambigously directly related to a
checkout stage. But I’d argue that at a business level, what we really care about is the
checkout that the
checkout stage belongs to.
Generate the interaction dictionaries
The script automatically uses the elements of the interaction to produce the JSON spec developers will be working from
It takes several passes to boil richly described interactions down into components. There will be undiscovered entities and objects with every pass, interactions that involve some repetition or interactions where the business entity it directly relates to isn’t clear. The design becomes clearer with every pass.
2. Flesh out dictionaries for entities
interaction dictionaries will need to be tightly integrated with Google Tag Manager (my TMS of choice) and its building block is of course, JSON.
I therefore needed something like this:
- User-friendly way for analysts to develop these dictionaries collaboratively, make additions and changes without getting lost in code.
- Automatically convert them into precise JSON specifications to hand over to developers.
- Commit-style version control, highlighting changes (similar to GitHub) and email notification on changes.
- Act as the single source of truth for the data layer instrumentation. Can’t stress how critical that is for this kind of unconventional analytics setup.
Enter Google Sheets with Google Apps Scripts, the familiar environment of a spreadsheet turbocharged by the amazing functionality of Google Apps Scripts.
entity dictionary workhorse
product dictionary worksheet
product collection dictionary worksheet
checkout option dictionary worksheet
What are we looking at?
This is where all the bulk of the work happens. Attributes are added in following discussions with developers and business stakeholders and grouped logically.
We then assign priority tags and decide which attributes will make it into the current work package. We can add also jot down candidates for future cycles as well as think ahead to analysis time and write down metrics and dimensions which will prove relevant. We also mark each attribute with client-side or server-side tags, depending on where the push to GTM will come from.
The dictionary is a tree
Highlighted in red is a branch. Related or similar attributes are grouped together under the same tree branch. The last cell on the row (green cell) is the value of the attribute. The branch nodes leading up to it are for classification only (inspired by mind-mapping software and JSON structure). We’ll grab these values (the green cells) from the backend whereever possible.
Flat or nested?
Some will disagree saying that a flat tree (and therefore JSON) structure is preferable (e.g.
Lists of children objects
Some entities (like
product collection) are composed of children objects. In this case, products. The
:listindicates that from there onwards, the contents of that branch will be a list of
productnodes. For each product, its dictionary is simply “slotted” in.
Lists, NOT arrays
Debated this a while and opted against arrays when children are business entities. Will revisit why in a future post but sufice to say for now that lists of JSON nodes allow you to access a specific node (and dictionary within) directly via dot notation like so
product_collection.products.product_345rather than looping an array. We’ll use this for fast lookups. Neat, huh?
Related business entity
Explicitly document if an object or entity is in reality related to another, more important business entity. It is often enough to document its
id(can substitute id for
Informational tags for management
Each tree node has a bracket with some text. These tidbits of text are the management language of the dictionary. They pack a lot of information and are used to manage the work/requirements (more on that below). The script uses “clues” in this language to automatically produce different summaries and specifications.
Priority tags (MoSCoW)
First single letter after opening bracket — (M, …) __ indicates priority status according to MoSCoW method. By default, only attributes marked M (Must have) make it into the spec passed to developers. This allows the analyst and business stakeholders to continue working on the dictionary without affecting the current work package.
“Moment of use” tags
Following MoSCoW flag is a tidbit of text that tells us whether that attribute will need to be passed to the data layer server-side (SS), client-side (CS) or not passed at all but inferred later (Analysis). This allows the analyst the explore requirements along the entire analytics continuum, from data collection to analysis, all from within a single repository.
Each worksheet is named after its entity (e.g.
product_dict). Entity name is also is the first cell — makes it clear what dictionary I’m editing.
No blank spaces in tree node names
The text for each tree node (until the opening bracket) will be used as a JSON key. Avoid blank spaces. Underscore vs camelCase is merely a question of personal preference.
Tree nodes are colour coded according to priority. Make highest priority ones to stand out whilst avoiding visual noise from the lowest priority ones.
Every element in this dictionary is carefully thought through so that relevant documentation can be generated with as little manual work (which increases risk of human error) as possible.
- Add done tags for completed nodes and produce summary for completed parts of the dictionary.
3. Automatically generate entity dictionary documentation
I’ve written some code in Google Apps Scripts to use the individual dictionary worksheets to automatically generate a summary sheet with the following:
A list of attributes added / removed from dictionary compared to previous version (GitHub style). These are documented using dot notation as this is easier to read. Only attributes marked M — relevant to current work package — are included.
It can get tiresome to try and read JSONs. I decided to strip out the noise and leave a barebones version that I can actually read. Hierarchical structure is preserved.
Precise JSON specification
The spec developers will work from to generate dictionaries server-side with helpful commentary as to what each attribute represents.
HTML5 markup requirements
For client-side interaction tracking additional markup requirements become inevitable. The script screens all attributes and those marked with CS data-* (and only them) get converted into HTML5 dataset markup.
Current version number and last updated
Basic elements of version control are: entity name, current version number and last modified date.
- Add commit-control. Prompt for commit comment when changes have been made.
- Add email notification to relevant parties when changes are made.
A static document would not work for this. Simo Ahava recently wrote in his Data Layer blog post:
“it’s extremely important to treat the Data Layer as a living, agile model, not a stagnated, monolithic, singular entity.””
I fully agree. This kind of tool (and the rest of the lego-inspired design model) allows you to start with the shortest, leanest dictionaries you need and then expand them over time as and when requirements demand it.
Thoughts? Please let me know in the comments.