Editor's note: “Pushing content to unexpected places” is our series of articles where we connect different devices, platforms and programs to Contentful, and share our experiences during the process. This is the first article, where Stefan Judis discusses his experience creating a plugin that connects Sketch to Contentful. Enjoy!
Building great digital products involves several teams that focus on different things. Teams can range from product design over content strategy to UX design, and at some point, the vision of the new shiny product ideas reaches the development team, which then has the honor to build the dream product everybody has in mind.
Personally, I’ve been involved in the startup industry building awesome products for seven years now, and I truly believe in the fact that well-defined structures play a significant role in successful product development. The first thing coming to my mind is always content structure. It doesn’t matter what the product you’re building is about, a well-defined content structure and a proper content model will most likely help all people being involved understanding what they’re dealing with.
Defined terms will build the base for conversations which contributes to avoid misunderstandings. And not to forget the most important part – structured data comes in a reusable format and may be even available via a public API. That’s a huge win!
Unfortunately, it’s usually only developers that will make use of this structured data. And this got me thinking. What if we could connect more people to this data?
Front-end developers know these situations, which happen once in awhile when collaborating with design teams: content far from realistic built the base for product designs and screens. Not everybody is aware of people that don’t have a beautiful, short name like “Jane Doe”, and this unawareness can lead to this one moment when a design just can’t work with production data. What follows then is another design iteration, which then costs time and money. I’ve been there – I’ve done that!
But what if we could give the design teams a way to deal with real data?
My personal website is built using Contentful, and I’ve got a designer friend who creates screens for me when my nerd design skills are not able to produce something decent-looking. So what has to be done to make it possible for Sketch to deal with data coming from a JSON API?
It should be possible to fetch data for particular layers of a Sketch document from a given space in Contentful. To achieve this, Sketch needs to make HTTP requests against the Content Delivery API. Therefore, storing an API access token and a space ID to identify the data on a per document basis becomes necessary.
This can’t be too hard, can it?
I quickly discovered the first hurdle, which is the setup of a development environment. Sketch provides a custom script editor which works fine for simple scripts and plugins, but it is surely not the environment I prefer to write complex code in.
To install a Sketch plugin, you can either double-click a
.sketchplugin file (which is actually a folder), or you place a new folder inside of Sketch’s plugin directory that is deeply buried in the
~/Library/Application Support folder. The
Library folder is a place I don’t like to work in, so the first thing I did was to set a symbolic link to a directory where I usually store all my code related projects.
A Sketch plugin has to follow a particular folder structure so that Sketch knows how to deal with it.
The most important file in a Sketch plugin is the
manifest.json file. It is the general configuration file for the plugin. It defines the version, author and which commands should be available. After symlinking the project and providing a valid
manifest.json my new plugin appeared already in the plugins dialog of Sketch. First mission accomplished!
There was only one problem at this stage. Sketch didn’t seem to take file changes into account immediately. To test my changes I always had to restart Sketch to run the latest code. Later I found out that this can be solved by enabling a “refresh” mode. The explanation how to do this is, unfortunately, a bit hidden in the Sketch documentation under Scripting Preferences.
After setting the symbolic link and enabling the refresh mode, I was ready to get my hands dirty on writing some code.
To debug the scripts I used the
log function provided by Sketch, which writes to my system logs. I found myself using a mixture of a
tail command running in my terminal and a the Console.app app provided by OSX.
For the needs of my Contentful plugin, I decided to implement two different commands, the configuration of which is pretty straightforward. I simply added new settings objects to the
commands property in the
manifest.json file, and I was ready to go.
Each command has to define a file and a particular function that should be executed whenever the user triggers the command. For example, to display the settings dialog, the function
openSettings in the file
lib/settings.js will be executed. The falsy
isRoot property leads to the commands being displayed inside of the plugin menu and not at the plugin menu root level, which is fine for me as they’re grouped together under the Contentful label.
The defined command handlers will be executed with a current context object. This object holds references to other useful objects like the current document or the current command, which will come in handy for later usage.
Showing a settings window including two input fields to give the possibility to store data was way harder than I expected. Displaying a typical OSX dialog from a Sketch plugin means entering the “Cocoa world”, and as my Cocoa experience is limited, this became tricky. I didn’t find any examples in the Sketch docs on how to achieve something like this and digged the AppKit documentation and scanned several other Sketch plugins on GitHub.
I ended up copying and modifying the code of a plugin called Sketch-Constraints and made my way through it with the good old trial and error approach. In case you’re interested in the implementation just have a look at the
createSettingsFunction of the Contentful Sketch plugin.
Thanks to the power of open source I succeeded! ❤️
The next step was to store the configuration data I received from the settings dialog. To achieve this there are the functions
valueForKey_onDocument_forPluginIdentifier defined in the
context.command object. I found these on sketchplugin.com and am still looking for some actual documentation around these. Sketchplugin.com seems to be very active, so I think it’s a good place to ask for help.
So at this point I was able to store settings – the next step was to analyze the document and to find out which layers should be connected with data that is stored in Contentful. I decided to follow a layer name convention to connect the Sketch document with the data in Contentful.
An SVG group should represent a content entry and define the entry id. Inside of this group text layers would be able to connect to a given data property.
I didn’t hit any problems analyzing the document, and the implementation of this went relatively well.
I have to say that writing a simple Sketch plugin that fetches some JSON data took me way longer than I thought. The current plugin implementation works fine for the simple use case of a string replacement. Dealing with relations and images is an entirely different story.
While writing this plugin I discovered (once more) that developer experience is really important when offering a software product for developers. Surely plugins are not Sketch’s primary business, but they’re part of its ecosystem. Good documentation, getting-started guides and tons of useful examples matter a lot.
And I don’t want to blame Sketch here – I only want to point out that writing good docs is hard, and keeping them up to date is even harder. Providing a good developer experience is not something that one can do on the side.
I prepared a short video where I actually show the plugin in action. As you can see the configuration is pretty straightforward, and overall it's easy to use.
Nevertheless, I think the idea of bringing real data into the design space has a lot of value. For me, this plugin was just a proof of concept, but I’ll try to keep track of it and maybe push it a bit further. What I’d like to see are people that have ideas and wishes on how to connect content management with Sketch. And if you’re a developer and want to help to improve this idea I’d really happy to collaborate on that, so open an issue or submit a PR to the project on Github!