Video icon 64
Want to be a web designer? Skill up fast with video courses from Tuts+. Start your free trial.
Advertisement

How to Use the Behance API to Build a Custom Portfolio Web Page

by
This post is part of a series called Build Your Own Behance-Powered Portfolio.
Styling Our Behance Portfolio Website Using LESS

Behance is great hub for creatives to share and show off their work and ongoing projects. Unlike Dribbble or Forrst which — as I personally see them — are predominantly populated by illustrators and UI designers, Behance encompasses a wider range of creative fields including Architecture, Motion Graphics, Automotive Design and Fashion. In addition to this, Behance also provides a set of APIs to get access to the content.

During this short series, we are going to use the Behance API to build a personal portfolio website. We'll effectively pull content from Behance and display it on our own external web page. But before proceeding any further with building the website, we first need to investigate how Behance manages its content and see how the API works.

Exploring Behance and the API

Behance splits its content into modules; namely image, embed, video, audio, and text. Data retrieved from the API will not only comprise image URLs but could also be video, audio URLs as well as plain text. Displaying all these types of content in our website, however, would complicate things. Therefore, in this tutorial, we will focus on images and exclude the rest to keep our code simpler.

Note: This tutorials assumes that you have an Adobe account and a Behance portfolio to work with. For the purposes of our demonstration, we'll be using the stunning portfolio of Mike "Creativemints", who's kindly agreed to let us use his work in this case.

Behance project editing screen.

When working on your own projects, after uploading your content, Behance will show you a dialog window to upload the cover image. This is like setting up a featured image in WordPress. The image that we upload here will be displayed as a preview of the entire project. In our website we will use the cover image likewise.

The dialog window to upload cover image in Behance.

Once we have set the cover image, we will be presented with options to assign several attributes such as creative fields, tags, and a description of the content. We won't overwhelm our website with too many of these attributes. In this tutorial, aside from the cover image and the title, we will only show the creative field attributes.

Creative fields selection in Behance.

Behance API Key

We need a unique API key/Client ID to get access to the Behance API. To get one, go to Behance Dev, register your app, fill out the Application Name, Website, and Description. the Redirect URI (for OAuth) field is optional, unless you are going to create an app that will require user authentication.

Behance API key.

Once we have the API key, go to Behance API Endpoints where you'll find listed all the ways to get access to the API. An API Endpoint is the address for a web service, usually just a simple HTTP URL string.

In this tutorial, we will need to get access to User information, the User's Projects. Here are the API endpoints to request this information:

Get a user's information

http://www.behance.net/v2/users/{user_id}?api_key={the_api_key}

The user information includes the user ID number, name, user's location, user avatar URL, and a bunch of other data.

Get a user's projects

http://www.behance.net/v2/users/{user_id}/projects?api_key={the_api_key}

We will get the list of published project of the given user_id. The list can be limited with per_page parameter.

Get the content of a project

http://www.behance.net/v2/projects/{project_id}?api_key={the_api_key}

The API returns the project information including modules of the given project_id.

Since the Behance API can be accessed over HTTP, we can see the data immediately in the browser. If you are using Chrome or Firefox, I would suggest you install a browser plugin called JSONview to see the JSON data in a more readable format.

JSON data viewed with JSONview

API Limit

Please be aware that Behance limits the API by 150 requests per hour. If there are too many requests, we will end up with empty responses and we will get nothing. Here is how the limit is described in the documentation:

Requests are limited to 150 per hour and are measured against the public facing IP of the server or device making the request. If you make too many requests, you will receive an empty response with a 429 (Too Many Requests) status code.

So, in this tutorial, we will utilize HTML5 Offline Storage to store the data offline to minimize the requests. Instead of calling the API every time we load the page, we can retrieve it from the storage. Please refer to the following articles for more about HTML5 Offline Storage:

The Website Blueprint

Before we build our website structure, let's take a look at the website blueprint.

The Website Blueprint

As you can see above, our website has three sections: Header, Content, and Footer. The Header contains the user's image avatar, name, their creative fields, and their location. The Content section shows user's portfolio with the name and the creative fields. In the Footer, we will show the Behance logo, illustrating that the website is powered by the Behance API.

Building up the Website Content and Structure

Let's start our project by creating a directory named personal-portfolio and an index.html with basic HTML5 markup. In the index.html, we will link to the following libraries:

jQuery

In this tutorial, we will use jQuery primarily for two things: DOM manipulation and calling the Behance API through its $.getJSON() API.

Today, jQuery is split into two versions, 1.x and 2.x. Version 1.x aims to support older browsers namely Internet Explorer 8 and below, while version 2.x only caters to more modern browsers. We will assume that we now live in the world where everyone is using modern browsers (I'm feeling risky). So, in this tutorial, we can safely use jQuery 2.x.

Handlebars.js

Handlebars is a great JavaScript-based templating engine. In this tutorial, we will use Handlebars to build the template that will display the data retrieved from the Behance API. Tuts+ has two free screencasts which can help you get started with Handlebars:

If you have not worked with Handlebars before, we would suggest you to take your time finishing these screencasts or reading some basic tutorials before stepping any further.

In this tutorial, we will not include the JavaScript and CSS libraries in our project directory for the sake of achieving smaller file size of our project. Instead we will link them from a CDN source by CDNJS.com. Let's open our index.html in a code editor and add the following libraries inside the head tag.

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.3.0/handlebars.min.js"></script>

Please note that if you serve index.html through a local server, you need to add http:// in each of the links pointing to CDNJS.com.

Dividing Website Sections in HTML

The HTML markup which defines our website sections — Header, Content, and Footer — is quite simple. We use the HTML5 header element for the Header, a div to wrap the Content, and the HTML5 footer element for the Footer. Each of these elements are assigned with a unique ID and a class for styling and scripting purposes. Here is our HTML markup within the body tag at this stage.

<header id="header" class="portfolio-header clearfix">
</header>
<div id="content" class="content-area clearfix">
</div>
<footer id="footer" class="portfolio-footer clearfix">
</footer>

Creating Handlebars Templates

In this section, we are going to build the Handlebars templates to display the content of our website sections. And we will start with the template for the Header, which will be populated with the users data from this API endpoint www.behance.net/v2/users/{user_id}.

A Handlebars template is wrapped with a script tag with a special type text/x-handlebars-template and preferably with a unique ID for easier selecting the template, like so.

<script id="profile-template" type="text/x-handlebars-template">
</script>

Within the script tag we will lay out the markup for the Header's content along with the classes for styling purposes. We also include the class from Foundation Icon Fonts 3, which is initialized with fi-, to show the icons. Lastly, the content placeholder in the form of a Handlebars expression.

<figure class="profile-avatar"><img src="{{user.images.[138]}}" alt=""></figure>
		<h1 class="profile-name">{{user.display_name}}</h1>
		<div class="profile-fields">
			<ul class="field-list">
				{{#each user.fields}}
					<li class="field-item">{{this}}</li>
				{{/each}}
			</ul>
		</div>
<div class="profile-location fi-marker">{{user.city}}, {{user.country}}</div>

Each of these placeholders corresponds to the JSON keys retrieved from the API. The {{user.display_name}}, for instance, will show the user display name. The display_name is the actual key that holds the value of the name. But since it is nested under the user object, we refer have to it as user.display_name. The same applies for the other placeholders in this template as well as the templates that follow.

User display name in JSON

Next, we will build the template to display portfolio, and this is the last Handlebars' template we will create for our website. To begin, we create a new div with an ID portfolio within the Content section. We create this div to wrap the portfolio, just in case we need to add more content within in the future. Then we add the script tag that will contain the template. At this point the HTML structure of our portfolio content should appear as follows:

<div id="portfolio" class="portfolio-area clearfix">		
	<script id="portfolio-template" type="text/x-handlebars-template">
	</script>
</div>

Here you can see that the data retrieved from www.behance.net/v2/users/{user_id}/projects returns an array containing the user's portfolio. To display an array, we will have to loop through each item in the array using Handlebars' {{each}} to display it in the template.

An array of project retrieved from Behance API

We will lay out the portfolio in an unordered list. So let's add a ul element and wrap each  li element with {{#each}}...{{/each}}, as follows:

<div id="portfolio" class="portfolio-area clearfix">		
	<script id="portfolio-template" type="text/x-handlebars-template">
	<ul class="portfolio-list clearfix">
		{{#each projects}}
		<li class="portfolio-item"></li>
		{{/each}}
	</ul>
	</script>
</div>

Then, we will lay out the content of each item. As we mentioned earlier, we will show the image cover, the name, and the creative fields. We will contain them inside the li with a new div with the class, portfolio-content.

...
<div class="portfolio-content">
	<figure class="portfolio-cover" title="{{this.name}}">
		{{#if this.covers.[404]}}
		<img class="portfolio-image" src="{{this.covers.[404]}}" alt="">
		{{else}}
			{{#if this.covers.[230]}}
			<img class="portfolio-image" src="{{this.covers.[230]}}" alt="">
			{{else}}
			<img class="portfolio-image" src="{{this.covers.[202]}}" alt="">
			{{/if}}
		{{/if}}
	</figure>
	<h2 class="portfolio-title">{{this.name}}</h2>
	<div class="portfolio-fields">
		<ul class="field-list">
		{{#each this.fields}}
			<li class="field-item">{{this}}</li>
		{{/each}}
		</ul>
	</div>
</div> 
...

Notice that there are a few of Handlebars' conditional helpers, like {{#if this.covers.[404]}}, in this template. We use the conditional helper to help us refer to the right cover image size. The image may not always be at 404px (which is the highest size set for the cover image), it may only be available in lower size. Here you can see that Behance cropped the image into these sizes: 404px, 230px, 202px, and 115px.

Cover image sizes

The HTML markup in the Footer is really simple. We will add two paragraph tags: one will contain "Powered by", and the last one will contain a link pointing to Behance. We add fi-social-behance class in the a tag to show the Behance logo from Foundation Icon Fonts.

... 
<div id="power" class="power-by">
	<p>Powered by</p>
	<p><a class="power-logo fi-social-behance" href="http://www.behance.net/" title="Behance" target="_blank">Behance</a></p>
</div>

At this stage, we have completed building the HTML structures which lay out our website's content. However, when we open it in the browser we will see nothing appear yet! This is because we need to make a request to the API and then compile the data along with the Handlebars template.

Calling Behance API and Compiling the Template

Let's create a script tag to contain our JavaScript. We will also create two variables to contain the Behance API Key and the User ID. As mentioned earlier, we'll be using the portfolio of "Creativemints".

var apiKey  = 'ZLBxK9rEfHwJf9K0rmseNr2fS2gS2HJW';
var userID  = 'creativemints';

Below these two variables, we add the following function. This function will call the Behance User API and compile the Handlebars template for the Header.

(function() {
	var behanceUserAPI = 'http://www.behance.net/v2/users/'+ userID +'?callback=?&api_key='+ apiKey;
	function setUserTemplate() {
		var userData    = JSON.parse(sessionStorage.getItem('behanceUser')),
		getTemplate = $('#profile-template').html(),
		template    = Handlebars.compile(getTemplate),
		result      = template(userData);
    	$('#header').html(result);
	};
	if(sessionStorage.getItem('behanceUser')) {
		setUserTemplate();
	} else {
		$.getJSON(behanceUserAPI, function(user) {
			var data = JSON.stringify(user);
			sessionStorage.setItem('behanceUser', data);
			setUserTemplate();
		});
	};
})();

Let's examine this code in more detail. First, we stored the Behance User API in a behanceUserAPI variable. Notice that we have inserted the callback= parameter within it. This addition avoids the Not Allowed Access error caused by the Same-Origin Policy.

A Word on sessionStorage

Earlier in this tutorial we mentioned that the Behance API is limited to 150 requests per hour, and thus we decided to use HTML5 Offline Storage to store the data. In this function, we've used sessionStorage. The reason behind the use of sessionStorage for storing the user profile data is that the user might change his/her profile anytime, yet we cannot predict it when. So instead of using localStorage that will store the data persistently, we use sessionStorage that will remove the data once we've quit the tab or the browser. That way, once we open the browser and access the website again, it will pull fresh data from the Behance API.

The sessionStorage, however, can only contain string or plain text. So, as you can see from the above function, we've used JSON.stringify(); to turn JSON into a string before we store it in sessionStorage. Then we will pull the data with JSON.parse() to format it back to JSON.

We've also created a function called setUserTemplate() to compile the Handlebars template and append the content using jQuery .html(). We run this function under this condition: if the data in sessionStorage is available, we immediately execute the function, otherwise we will have to call the API using $.getJSON() first and subsequently execute it.

In addition, you can see sessionStorage under the Resource tab in Chrome DevTools and Webkit-based browser.

sessionStorage in Chrome DevTools

 Compiling the Content

We then add the function below to compile the portfolio template into the Content. This function is very much alike with the above function for the Header, except for the perPage variable and per_page= parameter which we will use to limit the number of content items retrieved from the API.

(function() {
	var perPage = 12;
	var behanceProjectAPI = 'http://www.behance.net/v2/users/'+ userID +'/projects?callback=?&api_key=' + apiKey + '&per_page=' + perPage;

	function setPortfolioTemplate() {
		var projectData = JSON.parse(sessionStorage.getItem('behanceProject')),
			getTemplate = $('#portfolio-template').html(),
			template    = Handlebars.compile(getTemplate),
			result      = template(projectData);
		$('#portfolio').html(result);
	};

	if(sessionStorage.getItem('behanceProject')) {
		setPortfolioTemplate();
	} else {
		$.getJSON(behanceProjectAPI, function(project) {
			var data = JSON.stringify(project);
			sessionStorage.setItem('behanceProject', data);
			setPortfolioTemplate();
		});
	};
})();

Now when we see the browser, we should already see the user profile as well as the portfolio. But they are not yet styled.

Next Time..

In the following part of this series, we will style our portfolio content, giving us a dynamic and responsive portfolio page. See you then!

Advertisement