Engineer the web, together.

Symbiote news

Keep in touch with what we're up to.

RSS available too if that's your thing!

More prominent workflow

Posted 29 Sep 2017

Making workflow... work.

The Advanced Workflow module is a pretty nifty piece of process management once you get your head around it; editors can create and change things, but can't publish until a prescribed sequence of events have happened. Generally allowing a few cycles of feedback to occur. One of the common complaints with it though is that the "Workflow Actions" (ie the things people need to do...) are hidden and not obvious for content authors to find. Here's a snippet that makes use of the Right Sidebar module to help with that a little...

Assuming you have advancedworklfow installed already, add the rightsidebar module with composer:

composer require micschk/silverstripe-rightsidebar

Create an extension in your project like

class WorkflowSidebarExtension extends Extension

    public function updateWorkflowEditForm(Form $form)
        $tab = $form->Fields()->findOrMakeTab('Root.WorkflowActions');
        if (!$tab) {

        $sb = RightSidebar::create('WorkflowActions');

        foreach ($tab->Fields() as $f) {


        $form->Fields()->insertBefore($sb, 'Root');

And lastly, bind that to the CMS editing controllers

    - WorkflowSidebarExtension
    - WorkflowSidebarExtension

Enjoy having the workflow actions appearing alongside authors' work!

You need to compile JavaScript now?

Posted 12 Sep 2017

A JavaScript build cycle

For years jQuery has been the dominant JavaScript framework on the web. Serve up an HTML page, load in your JS and add functionality after the fact. Times change, and after much experimentation, we're choosing to standardise on React. 

Part of the reason is wanting to try new things, but some key considerations have been

  • Comparatively rigid structure to follow with how components are built, leading to more consistent development in the team
  • More familiar class based layout (helps getting backend developers up to speed) 
  • Strict(er) typing with the use of TypeScript providing a predictable codebase amongst multiple developers

All that aside - one of the biggest hurdles to getting started with these technologies has been "what is a webpack and why does my allegedly current version of node / npm / yarn / babel / brunch / ohwat not work with it?". (Yes, there's a good reason why some of those won't work together...). Rather than deal with all the different quirks each operating system has, and to ensure the same versions of tools, we looked to use Docker to create a define-once-run-everywhere image. 

After much experimentation, we've settled on a JavaScript build set of ES2016, TypeScript, React, jQuery and Bootstrap - depending on need - all managed using Yarn for package management, with Brunch binding everything together. To maintain consistency across the development team, we're using the following Docker file, which gives us a consistent execution environment across the board;

FROM ubuntu:14.04

# allows the use of the 'source' command. 
RUN rm /bin/sh && ln -s /bin/bash /bin/sh

RUN apt-get update && apt-get install -y \
    software-properties-common \
    apt-transport-https \
    build-essential \
    ca-certificates \
    vim \
    git \
    curl \ 
    wget \
 && rm -rf /var/lib/apt/lists/*

ENV NVM_DIR /usr/local/nvm

ADD /tmp/

RUN bash /tmp/ \
    && source $NVM_DIR/ \
    && nvm install $NODE_VERSION \
    && nvm alias default $NODE_VERSION \
    && nvm use default \
    && npm install -g grunt-cli \
    && npm install -g yarn \
    && npm install -g brunch 

ENV NODE_PATH $NVM_DIR/versions/node/v$NODE_VERSION/lib/node_modules
ENV PATH      $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH


CMD ["/bin/bash"]

This can be run directly from the CLI, or with a simple wrapper; so a might look like


docker run -i -v $(pwd):/tmp/work -p 9485:9485 -w /tmp/work --name jsbuildtools --rm symbiote/jsbuild bash -c "yarn \"$@\""

which is then usable just like a locally installed yarn binary start

Simple but effective; we're conscious of the impact learning new technologies has on our teams, so we're doing as much as possible to bypass the frustrating (okay, infuriating) process of getting a working JS build environment in place. 

The repo for the above Dockerfile is available at

Yes, even Firefox gets it wrong

Posted 16 Aug 2017

Not so pixel perfect in Firefox

Imagine for a second, that you're trudging through the inconsistent waters of frontend development and you've incredibly close to finishing off a piece of work. You test in Internet Explorer 9+ and pray. The gods smile on you as you haven't hit an browser-specific bug. You then move onto Safari for Mac and iOS. The skies are clear and you're so close to being done when suddenly... tragedy strikes.

You test in Firefox and see that various parts of your layout are off by a couple of pixels for seemingly no reason. "Why Firefox? Why has thou forsaken me? I thought you weren't like Internet Explorer!" you scream, perhaps also throwing a few profanities around for good measure. After you let the frustration wash over you and calm down you'll probably end up adding a fixed-height on all offending elements so that the off-by-one bugs are "fixed".

But what the heck happened? This problem is not at all new, in fact, with this bug now passing 11 years of life. The issue lies with rounding up the calculated height of text, rather than down when using ems / rems on the line-height property. The only way to not hit this bug is to use fixed pixel sizes with the line-height property, which isn't really feasible if you want to support zooming in Internet Explorer 9.

You can run the following JSFiddle to get the calculated height of a div containing text with the offending line-height styles:

As you can see, every browser that isn't Internet Explorer 6 or 7 will consistently render the div and have a height of 146px. That includes Firefox on the iOS 6S Plus.

Tested browsers with 146px height (rounded down):

  • Windows 7
    • Internet Explorer 8 (changed REM to EM for test purposes)
    • Internet Explorer 9
    • Internet Explorer 10 (Full Version: 10.0.9200.17229)
  • Windows 10
    • Chrome 59
    • Internet Explorer 11 (Full Version: 11.1358.14393.0)
    • Edge 38 (Full Version: 38.14393.1066.0)
  • iOS 5S
    • Safari
    • Chrome
  • iOS 6S Plus
    • Chrome
    • Safari
    • Firefox
  • Nexus 5X (Android 4.2)
    • Chrome
  • Mac OS Sierra
    • Safari 10.1
    • Chrome 59
    • Opera 46
    • Yandex 14.12
  • Mac OSX Lion
    • Safari 6
    • Chrome 49

Tested browsers with 147px height (rounded up):

  • Windows
    • Firefox 54 (32-bit)
  • Nexus 5X (Android 7)
    • Firefox
  • Mac OS Sierra
    • Firefox 54
  • Mac OSX Lion
    • Firefox 44

Old Internet Explorer shoutouts:

  • Internet Explorer 6 has 154px height.
  • Internet Explorer 7 has 148px height.