Custom Products Webpage Layout via the Etsy API

Anybody who is familiar with Etsy knows they provide an excellent service. Members can sign up to create their own Etsy shop and sell custom-made goods such as clothes, jewelry, posters, and tons of other neat stuff. It's almost like eBay except for custom (usually hand-made) goods.

In this tutorial, I want to jump into using the Etsy API developers to build a custom storefront page. We'll enter a simple search phrase and pull the most recent results published to the website. The API call takes a long time to fully complete, so we'll also setup a small cache file which is updated every hour. This will greatly reduce load times and also handle a smoother 3rd party connection into Etsy's developer API.

Custom Products Webpage Layout via the Etsy API


Custom Products Webpage Layout via the Etsy API

The Result

The Result

Register a New App

To get started let's visit the Etsy developer center and register a new API key. Whenever you're making calls to any 3rd party API you'll need to generate a new developer key. Note that you'll need an Etsy account before you can register a new application, so if you don't have one just signup real quick. It's free and shouldn't take more than a couple minutes.

After you're logged into the site head to the registration page and register a new application. The name and description don't really matter as long as you provide some relatable content. Also for the domain you can use whatever you like. But ideally it should be set to the TLD on which you'll be hosting the webapp.

Once that is finished you'll be presented with some new data about your application. We need to copy the Key String as our frontend API key. I will save this into a new string variable in PHP inside my index.php file. Let's hop over into the HTML and see how to setup the initial document.

Default Page Contents

Initially I'll only be using 2 specific documents - index.php and style.css. We eventually want to create another cache file down the road, but this can be generated dynamically through PHP. Below is the code I'm using in the document header:

<!doctype html>
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Etsy Products Search for 'Final Fantasy'</title>
  <meta name="author" content="Jake Rocheleau">
  <link rel="stylesheet" type="text/css" href="style.css">
  <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Galindo">
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<!--[if lt IE 9]>
  <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>

I've included a copy of the latest jQuery library along with a custom Google Web font stylesheet. We can use this external CSS document to work with typography across all platforms and web browsers. I'll wait until later in the tutorial to add the full body text until after we've created all the top dynamic PHP code.

So now before any heavy stuff let's simply open some PHP tags above the doctype way at the top of the page. I'm going to simply create a string variable which holds our new API key.

<?php
$apikey = "YOURAPIKEY";
$apiurl = "http://openapi.etsy.com/v2/listings/active?api_key=".$apikey."&limit=28&keywords=final%20fantasy";
?>

Logic for Building a Cache File

You'll notice the 2nd variable I've created is the direct URL to Etsy's listing API. We use this feature to pull all related listings based on criteria we set in the URL string. For this example we'll be pulling the most recent 28 product listings related to the keywords "final fantasy".

But now comes the part where we need to access that data and choose how to loop through everything. Etsy has a few different return types, but the default is JSON which works great for us! So here is the initial if/else statement call I've added below those variables.

$cachetime = @filemtime("cache.json");
$diff = time() - $cachetime;
if($diff <= 60*60) {
  // if the cache is less than 1hour we pull this data
  $results = json_decode(file_get_contents("cache.json"));
  $products = objectToArray($results);

} else {
  // generate new data from the API
}

The first variable $cachetime will check the last time we modified a local file named "cache.json". If the file doesn't exist or if the file is older than 1 hour(60x60) then we immediately go into creating a new API request.
The two functions file_get_contents() and json_decode() are built into the PHP library. First we're pulling the file contents into memory(if we have a cache file) then decoding the data from JSON into PHP objects.

function objectToArray($d) {
  if (is_object($d)) {
    // Gets the properties of the given object
    // with get_object_vars function
    $d = get_object_vars($d);
  }

  if (is_array($d)) {
    /*
     * Return array converted to object
     * Using __FUNCTION__ (Magic constant)
     * for recursive call
     */
     return array_map(__FUNCTION__, $d);
   }
   else {
     // Return array
     return $d;
   }
}

I'm using a quick custom function named objectToArray() which will parse through the response data and convert all JSON/PHP objects into arrays. It's not so important that you understand how this code works. But it is useful to quickly read our cache data so be sure to keep it with all the other PHP content.

Storing the PHP Response

The code inside our else { } clause will be called only if the cache file is missing or older than 1 hour. In this scenario we parse a new API call to Etsy and loop through the return data, then store it into the cache file. This way we only need to make 1 call to the remote server in order to pull down all new results.

  $products = array();
  $results = json_decode(file_get_contents($apiurl));
        
  $i = 0;

The first couple lines I'm setting up important variables before the loop. $products will hold all the 28 results which are returned from Etsy's server. The $results variable actually contains object data, and we need to convert that into a formatted array. We can do this using the $i variable as a counter which increases after every row.

foreach($results->results as $product){
  $products[$i]["pid"]      = $product->listing_id;
  $products[$i]["title"]    = $product->title;
  $products[$i]["url"]      = $product->url;
  $products[$i]["price"]    = $product->price;
  $products[$i]["quantity"] = $product->quantity;
  $products[$i]["endtime"]  = $product->ending_tsz;

  $imgs = json_decode(file_get_contents("http://openapi.etsy.com/v2/listings/".$product->listing_id."/images?api_key=".$apikey));

  $products[$i]["thumb"] = $imgs->results[0]->url_170x135;
  $products[$i]["image"] = $imgs->results[0]->url_570xN;

  $i++;
}

This may seem a bit daunting but don't fret! The PHP foreach() loop is fairly straightforward once you understand how to read the syntax. Basically this reads "for each API product result we'll use the variable $product". Then inside the loop $product contains the direct results from Etsy, and we're storing this data into our empty array.

We can use $products[$i] because that will define a new indexed array starting at 0. Note that $product(singular) refers to the API results while $products (plural) is our custom array. The first few values target the product name, price, and quantity. But then we need to make another API call to the images listing and store that data into the array as well. I'm only pulling thumbnails and the full 570px images, but there are often a couple more sizes you could use.

Pushing Content into JSON

The final piece of this else{} clause is passing our new array data into the cache file. The code is much simpler than our entire loop, but it's still important nonetheless.

  $jsonified = json_encode($products);
        
  $jsoncache = "cache.json";
  $fp = fopen($jsoncache, "w");
  fwrite($fp, $jsonified);
  fclose($fp);

If you remember from earlier the $products variable was an empty array we setup to hold all the new API data. So the variable $jsonified will convert this PHP array into JSON data. Then using PHP's fopen() function we check if the file cache.json exists and if we can read/write to it.

If not PHP will automatically create the file in your directory and write this new content. If the file already exists we wipe out the old content and truncate this new JSON response into the file. So every single time we pull data from the API we're also wiping the cache file completely empty and storing this new response data.

Display the Body Content

And now for the final piece to this puzzle! Down in the index.php file after our closing head tag we need to create a body area. Inside I'll use another foreach loop to pull down the$products array. You should notice we're using this naming convention for both the cache data and the live API data.

<body>
  <div id="w">
    <h1>Custom Final Fantasy Etsy Shop</h1>
                
    <div id="products" class="clearfix">
    <?php
                
    foreach($products as $product) {
      echo "<div class=\"product\">\n";
      echo "<h2><a href=\"".$product['url']."\" target=\"_blank\">".$product['title']."</a></h2>\n";
      echo "<center><a href=\"".$product['url']."\" target=\"_blank\"><img src=\"".$product['thumb']."\" alt=\"".$product['title']." featured image\" class=\"thumb\"></a></center>\n";
      echo "<p>Price: <span class=\"price\">$".$product['price']."</span></p>\n";
      echo "<p>Quantity: ".$product['quantity']."</p>\n";
      echo "</div>\n";
    }
    ?>        
    </div>
  </div>
</body>
</html>

The container div has an ID of #products which will contain many smaller div blocks. For each product inside the array we're creating a .product div to display the internal features. If you look at each individual echo statement you'll notice which variables I'm displaying on the page.

The most notable vars are the product's URL, title, price, quantity, and thumbnail image. With all this data we can create blocks linking to external Etsy products while also giving visitors a small preview right from the page. I know it can be very difficult to follow along exactly with this tutorial code, so feel free to check out our live demo below.

Conclusion

I hope this tutorial can be useful for other web developers interested in working with Etsy. I haven't used any type of OAuth authentication since this process does require a lot more programming work. But even to build a simple webapp like we have here doesn't require any type of user login process.

It may be difficult to follow all of the PHP code and scripting I've used. But if you can go over the code again and possibly build your own practice layouts, the process will become clearer. Feel free to download a copy of my source code from the link above. You can mess around with the code any way you like and even append this onto your own website projects.