Do more with Data: Building a Data Supplier plugin for Sketch
Bringing real Data into Sketch is the best way to really test out your designs. And by building a data plugin, you can take things a step further.
In Sketch 52, we introduced an exciting new feature — Data. If you still haven’t read about it, be sure to check our release blog post, or take a look at this great intro video by Peter Nowell, which is part of his new UX Design in Sketch course:
This new feature makes it really easy to bring data into your designs, and solves the most common use case—“just give me something random”— as painlessly as possible.
But what if you have slightly more complex needs? What if don’t want your data to be random, but totally predictable? What if you need your data to be smarter?
Enter Data Supplier plugins
When we designed the Data feature, we wanted it to be as simple as possible for most customers, but leave the door open for more advanced users to expand its functionality. And to do that, we built it on top of our, already powerful, plugin backend, adding a new API— DataSupplier.
Using this, you can build a Sketch plugin that adds a Data source to the app, making it trivial for customers to use it, while still taking advantage of all the cool things you can do with plugins. But, before we get started with building a Data Supplier plugin, it’s worth knowing how the Data feature works under the hood.
Sketch supports two types of Data for layers: images and plain text. A single plugin can provide multiple data types, so if you need to provide text and images at the same time, you can do so with just one plugin. When a layer is selected in the app, or an override’s Data icon is clicked in the Inspector, Sketch enables the relevant sources for each layer type. We’ll learn how to register a plugin for each Data type later on.
When a user requests some Data in Sketch, it passes that request to the relevant plugin, along with some important info needed to fulfil the request (in context.data
). Your plugin will then do some magic to generate, gather or download the data, and send it back to Sketch so that it places the data on the relevant layers. You can do this in a single step–by sending Sketch an array of data— or return the data one by one (which is useful if you’re getting data from a network that may take a second or two to download).
Enough talk, show me the code! A Data Supplier plugin example
In this post, we’ll go over a simple example that shows you how to build a Data Supplier plugin (don’t worry, we have more complex examples at the end, if you want to some inspiration). It assumes some familiarity with our plugin platform, but you can probably follow along if you know a bit of JavaScript.
We’ll be using our command line tool to create, develop and publish Sketch plugin, skpm. If it’s not already installed in your system, open Terminal.app, and run this:
npm install --global skpm
Please note that skpm
requires Node.js to be installed, but that’s beyond the scope of this tutorial. Go check their docs if you need help installing it.
One of the nicest features in skpm is the ability to use templates to create a plugin, and we’ve created a template specifically for Data: https://github.com/skpm/with-datasupplier.
To use it, let’s create a new plugin with it:
skpm create datademo --template=skpm/with-datasupplier
This will create a datademo
folder, add some files to it, install all the required dependencies, and give you some instructions on how to proceed from here. We’ll
cd datademo
and then
npm run build
That will build our Data plugin, and make it available in Sketch. You can see your plugin in the Plugins section in Preferences:
And also in the new Data section, along with other Data sources:
If you now add a bunch of Text Layers to a new document, and select Data › datademo, you’ll see what our sample plugin is doing: generating random numbers and filing the text layers with them.
Now let’s take a look at the code to understand what’s going on here. In your code editor, open the datademo
folder we created, and open src/my-command.js
. Ignore the onStartup
and onShutdown
functions for now, and go straight to onSupplyData
. This is the method that’s called by Sketch when it asks the plugin for data, and it does four things:
- Gets the data key from the context, so it can return the data later
- Iterates over the layers affected by the action
- Generates a random number for each one, and
- Sends the data back to Sketch
Step 1 is getting the key
attribute from the context.data
object. Here’s a list of the attributes in it:
- a
key
attribute, which is a UUID that your plugin will use to return the data to the right request - an
items
attribute, which is anNSArray
containing the list of layers or overrides that Sketch needs data for
let dataKey = context.data.key
Step 2 is achieved using a basic forEach
operation on the collection of layers that Sketch needs data for. That collection lives at context.data.items
. Depending on how the feature is triggered by the user, those items can be either layers or overrides.
const items = util.toArray(context.data.items).map(sketch.fromNative)
items.forEach((item, index) => {
// do stuff here…
})
Step 3 is just generating the random number:
let data = Math.random().toString()
Don’t let this basic example fool you: you can do anything you need here. Getting dynamic weather data from an online API? Translating the layer’s text to Indonesian? Downloading real data from your production database to set a product’s picture? Let your imagination fly…
Finally, step 4 is simply forwarding the data we’ve generated to the DataSupplier object, so that it sends it back to Sketch.
DataSupplier.supplyDataAtIndex(dataKey, data, index)
Where dataKey
is a key we were passed in the context (in context.data.key
). In this case, we’re sending the data one by one using the supplyDataAtIndex
method, but we could have stored the data in an Array object, and then pass all the data at once using the supplyData
method:
let count = context.data.items.count()
let dataKey = context.data.key
let data = Array.from(Array(count)).map(i => Math.random().toString())
DataSupplier.supplyData(dataKey, data)
Working with images is exactly the same, only you’ll need to supply a path to an image file on disk. If you want to use images from an online service, you’ll need to download them to a temporary location. Take a look at our own Unsplash Plugin for an example of how to do that.
Another funny example is this Random Translator plugin, where we use the Yandex API to translate text layers in Sketch into random languages (because nothing breaks your design like unexpected word lengths, and funky characters!)
Registering our plugin with Sketch
Now that we have some amazing code generating random numbers, we need to tell Sketch about it. To do that, we need to add an attribute to our manifest.json
(this is already set for us in the skpm template):
"suppliesData": true
We also need to tell Sketch which data types our plugin supplies, and which function to call to get the Data from our plugin. This is done using the actions
section in the manifest file, where we’ll add handlers for Startup / Shutdown (to register / unregister our plugin), and one for the event that is triggered when the plugin is called (you can use any name you want for your event, SupplyData
is just the one we use in our example):
{
"actions": {
"Startup": "onStartup",
"Shutdown": "onShutdown",
"SupplyData": "onSupplyData"
}
}
Then, in my-command.js
, we register the plugin in the onStartup
method:
export function onStartup() {
DataSupplier.registerDataSupplier('public.text', 'datademo', 'SupplyData')
}
That tells Sketch to register a Text Data Supplier, named datademo
, for the SupplyData
event. If you want your plugin to supply images, you need to use public.image
as the first argument.
Further Reading
If you want to know more about the DataSupplier feature, here are some links you’ll want to check:
- Our API documentation
- Our sample plugins: Data Supplier, Random Translation, Unsplash
- The skpm template for Data plugins: https://github.com/skpm/with-datasupplier
Wrapping up
That’s all for today! We’ve gone over quite a lot of material, and we’re sure this will keep you busy until we meet again in part two of this series, where we’ll learn how to work with Data and Symbol Overrides.
Until then, have fun! And don’t forget to share your creations with us, we love to see what you’re building.