Treehouse

Using the GitHub API and PHP to Get Repository Information

By on  

GitHub is an awesome place to host your open source project code. MooTools, Prototype, and jQuery all use GitHub. As you probably know, the MooTools Forge requires your plugins be hosted on GitHub. The only problem with hosting all my MooTools plugins is that I lose traffic when I want people to see my code. Problem solved: use PHP, the GitHub API, and PHP Markdown to display files of my choice on my website.

Our goals with this code will be to:

  • Connect to GitHub via the API to retrieve repository information.
  • Retrieve the content of two files from the repository: a source file and the README.md Markdown file.
  • Cache the information for a given period of time to reduce the load on GitHub.
  • Use PHP Markdown to output a formatted README.md file.

I know that seems like a lot of work but you'll be amazed at how easy the process is.

PHP MarkDown

You may download PHP Markdown at Michel Fortin's website. It's simple and full of features.

The PHP

The first step is to build a PHP function that will connect to GitHub using cURL:

/* gets url */
function get_content_from_github($url) {
	$ch = curl_init();
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); 
	curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,1);
	$content = curl_exec($ch);
	curl_close($ch);
	return $content;
}

Next we need to define a few settings:

/* static settings */
$plugin = 'Overlay';
$cache_path = $_SERVER['DOCUMENT_ROOT'].'/plugin-cache/';
$cache_file = $plugin.'-github.txt';
$github_json = get_repo_json($cache_path.$cache_file,$plugin);

The next step is to create another PHP function that grabs the repository information (JSON-encoded, because I love JSON) -- either fresh from GitHub (by first grabbing the most recent commit hash, then grabbing the contents of the two files) or our local cached information:

/* gets the contents of a file if it exists, otherwise grabs and caches */
function get_repo_json($file,$plugin) {
	//vars
	$current_time = time(); $expire_time = 24 * 60 * 60; $file_time = filemtime($file);
	//decisions, decisions
	if(file_exists($file) && ($current_time - $expire_time < $file_time)) {
		//echo 'returning from cached file';
		return json_decode(file_get_contents($file));
	}
	else {
		$json = array();
		$json['repo'] = json_decode(get_content_from_github('http://github.com/api/v2/json/repos/show/darkwing/'.$plugin),true);
		$json['commit'] = json_decode(get_content_from_github('http://github.com/api/v2/json/commits/list/darkwing/'.$plugin.'/master'),true);
		$json['readme'] = json_decode(get_content_from_github('http://github.com/api/v2/json/blob/show/darkwing/'.$plugin.'/'.$json['commit']['commits'][0]['parents'][0]['id'].'/Docs/'.$plugin.'.md'),true);
		$json['js'] = json_decode(get_content_from_github('http://github.com/api/v2/json/blob/show/darkwing/'.$plugin.'/'.$json['commit']['commits'][0]['parents'][0]['id'].'/Source/'.$plugin.'.js'),true);
		file_put_contents($file,json_encode($json));
		return $content;
	}
}

Once we've acquired the appropriate information, we output the information to screen:

/* build json */
if($github_json) {
	
	//get markdown
	include($_SERVER['DOCUMENT_ROOT'].'/wp-content/themes/walshbook3/PHP-Markdown-Extra-1.2.4/markdown.php');
	
	//build content
	$content = '

'.$github_json['repo']['repository']['description'].'

'; $content.= '

MooTools JavaScript Class

'.$github_json['js']['blob']['data'].'

'; $content.= trim(str_replace(array('',''),'',Markdown($github_json['readme']['blob']['data']))); }

That's all! Now I get the benefit of hosting my code on GitHub but displaying it on my own website. I've created a special WordPress template page to do so and recommend you do too!

Demo?

Visit my Projects page and click on the "Docs" link for any project. All of the information that comes up on individual project pages comes from GitHub. No more manual page creation!

ydkjs-6.png

Recent Features

  • 5 HTML5 APIs You Didn&#8217;t Know&nbsp;Existed

    When you say or read "HTML5", you half expect exotic dancers and unicorns to walk into the room to the tune of "I'm Sexy and I Know It."  Can you blame us though?  We watched the fundamental APIs stagnate for...

  • Create Namespaced Classes with&nbsp;MooTools

    MooTools has always gotten a bit of grief for not inherently using and standardizing namespaced-based JavaScript classes like the Dojo Toolkit does.  Many developers create their classes as globals which is generally frowned up.  I mostly disagree with that stance, but each...

  • Create a CSS Flipping&nbsp;Animation

    You've all asked for it and now I've added it: Internet Explorer support! Annoyingly enough, the change involves rotate the front and back elements instead of just the container. Skip to this section if you'd like the...

Incredible Demos

  • Hot Effect: MooTools Drag&nbsp;Opacity

    As you should already know, the best visual features of a website are usually held within the most subtle of details. One simple trick that usually makes a big different is the use of opacity and fading....

  • CSS&nbsp;Tooltips

    We all know that you can make shapes with CSS and a single HTML element, as I've covered in my CSS Triangles and CSS Circles posts.  Triangles and circles are fairly simply though, so as CSS advances,...

  • CSS Fixed Position Background&nbsp;Image

    Backgrounds have become an integral part of creating a web 2.0-esque website since gradients have become all the rage. If you think gradient backgrounds are too cliche, maybe a fixed position background would work for you? It does...

Discussion

  1. Roy Sutton

    Very nice, exactly what I was looking for. I did notice that the last line of get_repo_json() should be return $json instead of return $content.

  2. Hi, nice article.
    I would love to try it, but your demo seems to fail.

  3. […] Github API has a method to render Markdown (PHP example), and DocumentUp can automatically generate  documentation pages/sites from Markdown, so some of […]

  4. […] Using the GitHub API and PHP to Get Repository Information […]

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Use Code Editor