├── Insert Random User.sketchplugin ├── README.md ├── Refresh Random Users.sketchplugin ├── preview.gif └── randomUserCommon.js /Insert Random User.sketchplugin: -------------------------------------------------------------------------------- 1 | #import 'randomUserCommon.js' 2 | 3 | // find the current artboard 4 | var layer; 5 | 6 | if ([selection count] != 0) 7 | { 8 | layer = [selection objectAtIndex:0]; 9 | } 10 | 11 | if (layer) 12 | { 13 | var currentArtboard; 14 | 15 | do { 16 | if (layer.class() === MSArtboardGroup) 17 | { 18 | currentArtboard = layer; 19 | break; 20 | } 21 | 22 | layer = [layer parentGroup]; 23 | 24 | } while (layer); 25 | 26 | } else { 27 | 28 | if ([[[doc currentPage] artboards] count] > 0) 29 | { 30 | currentArtboard = [[[doc currentPage] artboards] objectAtIndex:0]; 31 | } 32 | } 33 | 34 | if (!currentArtboard) 35 | { 36 | currentArtboard = [doc currentPage]; 37 | } 38 | 39 | // plugin defaults 40 | var fields = ["firstname", "lastname", "city, state", "email"]; 41 | 42 | var profilePictureHeight = 200; 43 | var height = 40; 44 | 45 | 46 | // create our layer group that we'll be inserting the text fields into 47 | 48 | var randomUserGroup = currentArtboard.addLayerOfType("group"); 49 | randomUserGroup.setName("randomUser"); 50 | 51 | [randomUserGroup frame].width = 400; 52 | [randomUserGroup frame].height = profilePictureHeight + (fields.length * height); 53 | 54 | [randomUserGroup frame].x = 20; 55 | [randomUserGroup frame].y = 200; 56 | 57 | // get our random user 58 | var user = getRandomUser(); 59 | 60 | var whiteColor = [[MSColor alloc] init]; 61 | [whiteColor setRed:0.8]; 62 | [whiteColor setGreen:0.8]; 63 | [whiteColor setBlue:0.8]; 64 | [whiteColor setAlpha:1]; 65 | 66 | for (i = 0; i < fields.length; i++) 67 | { 68 | var textLayer = randomUserGroup.addLayerOfType("text"); 69 | 70 | textLayer.textColor = whiteColor; 71 | textLayer.fontSize = 24; 72 | 73 | textLayer.setName("profile:" + fields[i]); 74 | 75 | var textLayerFrame = [textLayer frame]; 76 | [textLayerFrame setWidth: 400]; 77 | [textLayerFrame setHeight: 30]; 78 | 79 | [textLayerFrame setX: 0]; 80 | [textLayerFrame setY: profilePictureHeight + (height * i)]; 81 | 82 | [textLayer setStringValue:fields[i]]; 83 | 84 | insertRandomUser(textLayer, user); 85 | } 86 | 87 | // insert our picture layer 88 | insertProfilePicture(randomUserGroup, user); 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Random-User 2 | =========== 3 | 4 | A SketchApp plugin that inserts random user data into your Sketch documents. Random user data is pulled from the fantastic webservice at [http://randomuser.me/](http://randomuser.me/) 5 | 6 | 7 | Installation 8 | ============================= 9 | 10 | Download the zip for this project and extract it to a temporary folder. Copy the **Random User** folder your Sketch Plugin folder. You can get access to that folder by opening the Plugins menu, and choosing **Reveal Plugins Folder...**. 11 | 12 | Short Demo 13 | ============================= 14 | ![alt preview](preview.gif "Title") 15 | 16 | Usage 17 | ============================= 18 | 19 | Select any Artboard in your project, open the **Plugins** menu and choose **Random User > Insert Random User**. You can refresh the user with new data by opening the **Plugins** menu and choose **Random User > Refresh Random Users**. 20 | 21 | Watch this [short screencast](http://youtu.be/j456z5gFgjg) for full description of how the plugin can be customized. 22 | 23 | Text Configuration 24 | ============================= 25 | The insertion of data into the Sketch Text layers are determined by the name of the text layer. The layer must begin **profile:** and then be followed by any combination of the following keywords: 26 | 27 | * firstname 28 | * lastname 29 | * picture 30 | * street 31 | * city 32 | * state 33 | * zip 34 | * email 35 | * phone 36 | * cell 37 | * username 38 | 39 | ###Examples: 40 | 41 | * profile:firstname 42 | * profile:lastname, firstname 43 | * profile:city, state zip 44 | 45 | In future releases I will be adding support for: 46 | 47 | * Date of birth 48 | * Date registered 49 | -------------------------------------------------------------------------------- /Refresh Random Users.sketchplugin: -------------------------------------------------------------------------------- 1 | #import 'randomUserCommon.js' 2 | 3 | log ([doc fileUrl]); 4 | 5 | var randomUserLayers = []; 6 | var profileLayers = []; 7 | 8 | findRandomUserLayers([[doc currentPage] layers]); 9 | 10 | log (randomUserLayers.length); 11 | 12 | for (var i = 0; i < randomUserLayers.length; i++) 13 | { 14 | 15 | var randomUserLayer = randomUserLayers[i]; 16 | findProfileLayers(randomUserLayer); 17 | 18 | for (var j = 0; j < profileLayers.length; j++) 19 | { 20 | var user = getRandomUser(); 21 | var profileLayer = profileLayers[j]; 22 | insertRandomUser(profileLayer, user); 23 | } 24 | 25 | profileLayers = []; 26 | } 27 | 28 | function findRandomUserLayers(layers) 29 | { 30 | 31 | for (var i = 0; i < [layers count]; i++) 32 | { 33 | var layer = [layers objectAtIndex:i]; 34 | 35 | if ([layer isMemberOfClass:[MSArtboardGroup class]] || [layer isMemberOfClass:[MSLayerGroup class]] ) 36 | { 37 | if ([layer isMemberOfClass:[MSLayerGroup class]] && layer.name().indexOf("randomUser") == 0) 38 | { 39 | randomUserLayers.push(layer); 40 | } 41 | 42 | findRandomUserLayers([layer layers]); 43 | } 44 | } 45 | } 46 | 47 | function findProfileLayers(randomUserLayer) 48 | { 49 | var layers = [randomUserLayer layers]; 50 | 51 | for (var i = 0; i < [layers count]; i++) 52 | { 53 | var layer = [layers objectAtIndex:i]; 54 | 55 | if (layer.name().indexOf("profile:") == 0) 56 | { 57 | profileLayers.push(layer); 58 | } 59 | 60 | if (layer.class() === MSLayerGroup) 61 | { 62 | findProfileLayers(layer); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimrutherford/Random-User/7573e2dd27444e613a4bd3dde913c1aec8c755cf/preview.gif -------------------------------------------------------------------------------- /randomUserCommon.js: -------------------------------------------------------------------------------- 1 | function getRandomUser() 2 | { 3 | var theUrl = [NSURL URLWithString:"http://api.randomuser.me/?sketch=true"]; 4 | 5 | // define the request 6 | var theRequest = NSMutableURLRequest.requestWithURL_cachePolicy_timeoutInterval(theUrl, NSURLRequestReloadIgnoringLocalCacheData, 60); 7 | theRequest.setHTTPMethod_("GET"); 8 | 9 | // get response data 10 | var theResponse = null, theResponseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:nil]; 11 | 12 | if (theResponseData!=nil) { 13 | 14 | // convert data to text 15 | theText = [[NSString alloc] initWithData:theResponseData encoding:NSUTF8StringEncoding]; 16 | 17 | var parsed = JSON.parse(theText); 18 | user = parsed.results[0].user; 19 | } 20 | 21 | return user; 22 | } 23 | 24 | 25 | function insertRandomUser(profileLayer, user) 26 | { 27 | if (profileLayer.class() === MSTextLayer) 28 | { 29 | 30 | text = [profileLayer name]; 31 | 32 | // strip the prefix 33 | text = text.replace("profile:", ""); 34 | 35 | text = text.replace("firstname", toTitleCase(user.name.first)); 36 | text = text.replace("lastname", toTitleCase(user.name.last)); 37 | 38 | text = text.replace("street", toTitleCase(user.location.street)); 39 | text = text.replace("city", toTitleCase(user.location.city)); 40 | text = text.replace("state", toTitleCase(user.location.state)); 41 | text = text.replace("zip", toTitleCase(user.location.zip)); 42 | 43 | text = text.replace("email", user.email); 44 | text = text.replace("phone", user.phone); 45 | text = text.replace("cell", user.cell); 46 | text = text.replace("username", user.username); 47 | 48 | [profileLayer setStringValue:text]; 49 | } 50 | else if (profileLayer.class() === MSBitmapLayer) 51 | { 52 | insertProfilePicture(profileLayer, user); 53 | } 54 | } 55 | 56 | function insertProfilePicture(profileLayer, user) 57 | { 58 | var urlString = user.picture; 59 | var imageURL = [NSURL URLWithString:urlString]; 60 | 61 | var imageFromURL = [[NSImage alloc] initWithContentsOfURL:imageURL]; 62 | 63 | var imageLayer; 64 | var imageCollection; 65 | 66 | if (profileLayer.class() === MSBitmapLayer) 67 | { 68 | // updating an existing layer 69 | [profileLayer setIsVisible:false]; 70 | imageCollection = [[profileLayer documentData] images]; 71 | var image = [imageCollection addImage:imageFromURL name:"profilePicture" convertColourspace:false]; 72 | [profileLayer setPrimitiveImage:image]; 73 | [profileLayer setIsVisible:true]; 74 | } else { 75 | // creating a new profile picture 76 | imageCollection = [[MSImageCollection alloc] init]; 77 | var image = [imageCollection addImage:imageFromURL name:"profilePicture" convertColourspace:false]; 78 | imageLayer = [[MSBitmapLayer alloc] initWithImage:image parentFrame:[profileLayer frame] name:"profile:picture"]; 79 | 80 | if (imageLayer) 81 | { 82 | //log ("Got Image Data"); 83 | 84 | [profileLayer addLayer:imageLayer]; 85 | 86 | var layerFrame = [imageLayer frame]; 87 | 88 | [layerFrame setX:0]; 89 | [layerFrame setY:0]; 90 | 91 | [layerFrame setConstrainProportions: false]; 92 | [layerFrame setHeight: 200]; 93 | [layerFrame setWidth: 200]; 94 | [layerFrame setConstrainProportions: true]; 95 | 96 | } 97 | } 98 | } 99 | 100 | function toTitleCase(str) 101 | { 102 | return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}); 103 | } 104 | --------------------------------------------------------------------------------