Here's a cool feature of CodePen that allows you to easily and dynamically create a new pen with any code you want as the starting point. Sound cool?

Here's Chris Coyier's pen that showcases this feature in action

http://codepen.io/chriscoyier/pen/FKxjB/

http://blog.codepen.io/2014/12/03/two-useful-css-apps-beautifully-export-codepen/

http://blog.codepen.io/documentation/api/prefill/

This is really cool. Take a look at how Clippy leverages this.

http://bennettfeely.com/clippy/

Notice the CodePen button at the bottom?

At any point, it becomes incredibly easy for the user to try out code.

The best part? It's very easy to do. The API is very intuitive with simple implementation.


  1. Form that submits Data to CodePen URL
  2. Set CodePen Data Object Configuration (code, preprocessors, libraries, more)
  3. Convert the Data Object to a string with safe quotes replacement (html entities)
  4. Add String as value to form to be submitted.
  5. Submit Form. Yup. That's it.

Pretty sweet eh? Okay, let's get into it.


1. Forms

If you're not familiar with form submissions or working with API's have no fear, this will be a great introduction.

  <!-- Form To Submit To Codepen To Create New Pen -->
<form action="http://codepen.io/pen/define" method="POST" target="_blank">

  <!-- We'll populate the value with the data to post to codepen here. -->
  <input type="hidden" name="data" value="">

  <!-- Fancy Pants CodePen Submit Button. -->
  <input type="image" src="http://s.cdpn.io/3/cp-arrow-right.svg" width="40" height="40" value="Create Pen" class="codepen-mover-button">

</form>

The action and method of a form control how the form handles the values inside.

The action is the location the data should go.

The method determines if the data is sent to another location, or if the data comes from another location like a URL parameter.

Think google search. We could always process information from a url - that would be a GET request.

                                                                            // My Search (what is a url parameter)
https://www.google.ca/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=what%20is%20a%20url%20parameter


CodePen expects data to be POSTed to it.

[ Form (Data) ] --POST-- > [ CodePen ] "Thanks, I'll create a new pen with this data"

The location(action) we send this data to is http://codepen.io/pen/define

CodePen has created this page to process information we send it into a new pen.


2. Setting up the Pen Data

Okay great, so what data does CodePen expect to receive then?

  var data = {
        title : "New Pen Title",
        description  : "New Pen Description",
        html  : "",  // My Starting HTML
        html_pre_processor : "",
        css : "",  // My Starting CSS
        css_pre_processor : "",  // Maybe start it with scss?
        css_starter : "",
        css_prefix :  "",
        js : "",  // My Starting JS
        js_pre_processor : "",
        js_modernizr :  "",
        js_library :  "",
        html_classes  :  "",
        css_external : "", // External CSS File - http://brandonbrule.com/css/style.css
        js_external : ""  // External Link to JS File - Whatever library you want really.
};

This, this is an API. An API allows us to use parts of code that make up an application.

CodePen has opened up parts of their code to allow us the ability to interact with the inner workings that make up the site we all love.

The CodePen team has made it easy for us to create new pens with a lot of options.

We send them this, and boom - new pen.


3. Convert it to a string

By design, forms only allow plain text strings. This prevents and protects sites and their users from malicous code.

This means, that the data object we send to CodePen must be turned into a string before being sent over.

To turn the CodePen data object, and all of the code inside that object into a string we use JSON by Mr. Dougless Crawford.

JSON is built into JavaScript and is easy to use.

  // CodePen data Object
// Codepen Object
var data = {
  title              : "",
  description        : "",
  html               : "",
  html_pre_processor : "",
  css                : "",
  css_pre_processor  : "",
  css_starter        : "",
  css_prefix         : "",
  js                 : "",
  js_pre_processor   : "",
  js_modernizr       : "",
  js_library         : "",
  html_classes       : "",
  css_external       : "",
  js_external        : ""
};

// Convert data object to string
// dataString is now a string representation of the CodePen data Object
var dataString = JSON.stringify(data);

dataString is now a string of the entire CodePen data object.

JSON.stringify(obj) turns objects, into strings.

For Reference,

JSON.parse(str); turns strings into objects (if they are correctly formatted)

  // Convert dataString back to JavaScript Object
var backToObject = JSON.parse(dataString);


3. It's Working... It's Working!

So at this very moment, if we set the dataString to the hidden input value and submit the form, we will create a new CodePen.

Super Sweet.


4. Setting up pre defined code

Well out of the box everything works great.

No problemo over here. Thank you very much CodePen.


Extending Functionality

There are a couple really cool tricks (badum chee) in Chris' pen .

First, I'm not sure if it was just me, but I didn't know you could have target="_blank" on a form.

  <form action="http://codepen.io/pen/define" method="POST" target="_blank">

THERE I SAID IT.. I didn't know.


To retain formatting he uses a code tag inside a pre tag.

  <pre class="codepen-able" data-type="html"><code>&lt;div>
  &lt;p>I'm example HTML&lt;/p>
&lt;div></code></pre>

White space matters with pre tags as does the brackets that create html elements. Any indentation or spacing of the code will affect the indentation of the text inside the pre tag and for visual rendering we need to display the first < as it's html entity.

Now, when we set the value of the html, css, or js properties in the CodePen data object, we can grab the code tag's innerHTML and the formating and spacing of the code will be the same for our newly created pen.

One thing though. We've got to replace all the quotes with their html entity equivalent. We can do this with .replace().

Here's a function that'll do just that.

  // Replace Quotes and Set Object as String Function
var setDataString = function (data){
  var string = JSON.stringify(data);
  string = string.replace(/"/g, "&quot;");
  string = string.replace(/'/g, "&apos;");
  return string;
};

This is for security reasons, without sanatizing inputs, there comes a risk of the inputs executing code which could damage or expose database information. CodePen has precautions in place that will return safe characters (like html entity text) without this formating.

This is what happends when quotes are not parsed.

So we need to replace those quotes, and then we can append that string to the hidden value that's submitted to CodePen.

Here's an example of an html code snippet after the quotes have been changed.


All Three Code Boxes

We could also loop through all of the pre tags, look for a data-attribute, or any identifier, and append all three html, css, and js properties to the data object to be sent.

Like this.


Groups of Pens

We could also wrap each of the sets of pre tags inside their own container so we can have multiple CodePen builders for something like a step by step article.

Here's what I have currently. I'm still messing around with this, so if it's broken for a bit, just try again, I save often, but go ahead and take it away from here.

http://codepen.io/brandonbrule/pen/MYaGPa


Next Steps

Well as Chris said it.

You can consider it an open API, so any approach to POSTing to that URL with data is fine


CodePen Button Builder

Playing with the API some more, here's a little something that will build a try it on CodePen button with prefilled settings and code. Copy and paste the form html on your site and it should be good to go.


2,989 6 29