Portfolio Work – Interweaving the Personal API

myportfolio

I know. The title is pure click-bait. That’s part of why this blog is so wildly popular.1

I’ve been building a new portfolio site2 and I think some of this is kind of interesting even if it sounds boring. There are a few different goals in play. One challenge is to create a site that stays up to date with minimal work on my end. It’s a parallel of the small-pieces-loosely-joined mentality. I want tiny-actions-over-time (from the aforementioned small pieces) rather than widely-spaced-herculean efforts. I’m also trying to make sure that it fits in well with my current workflow and that I’m capturing the work I do elsewhere in ways that make sense.

Another focus is to keep any work highly portable. I’ve had to re-enter data a number of times as I’ve migrated and I don’t want to do that any more. That’s going to be made possible mainly through some new API options and by working on my API/JSON, JavaScript skills. I’ll probably have to do chunks of it over anyway but I like to pretend I wont.

I’ve got a ways to go but I’ve made some decent progress. The basic template/visuals are handled by Bootstrap. I’ve also got some simple Angular views, Timeline JS, JSON from Google sheets, WordPress WP Rest API v2, and Pinboard’s API. So that’s kind of fun (I think).

The Front Page

portfolio details

The following is the code for the jQuery JSON parser. It displays the JSON created by the WordPress API. I opted to cache the data rather than call it live for two reasons- it seemed much faster performance-wise and I’m also hosting this on GitHub which brings up http/https issues until I turn on https for my personal site. I just use PHP to grab it and stick it in a folder every 24 hrs via a cron task.

$(document).ready(function(){ 
          console.log("ready"); //just to check in the firebug console.
          
        $.ajax({
          url:'json/blogs.json', //gets json
          jsonp:"cb",
          dataType:'json',
          success: function(data) {
//builds the html and does a default img if there isn't one
            $.each(data, function(index, item){
                if (item.better_featured_image != null){ var photo ='<div class="pinimg"><img src="'+ item.better_featured_image.media_details.sizes.thumbnail.source_url +'" width="40px" height="40px"></div>' } else {var photo ='<div class="pinimg"><img src="imgs/default.png" width="40px" height="40px"></div>';};              
                $('#blog').append('<a href="' + item.link + '"><div class="pinboard">' + photo + '<div class="pindetails"> ' +item.title.rendered + ' <br/> published on ' + item.date.substring(0,10) +' </div> </div></a>');              
              if (index == 10) return false; //only display 10 items
              }); //each
            } //success
          }); //ajax
          
        });//ready

For Pinboard, I did something similar.

$(document).ready(function(){ 
          console.log("ready"); 
          
        $.ajax({
          url:'https://feeds.pinboard.in/json/u:twwoodward/', //from the pinboard API
          jsonp:"cb",
          dataType:'jsonp',
          success: function(data) {
            $.each(data, function(index, item){
                $('#pinboard').append('<div class="pinboard"><a href="' + item.u + '">' + item.d
        + '</a>  -  ' + item.dt.substring(0,10) +' </div>');
              if (index == 10) return false; //only display 10 items
              }); //each
            } //success
          }); //ajax
          
        });//ready

I tried to parallel the visual elements for the blog posts and the Pinboard posts with the Twitter widget visuals since I couldn’t really change the way that looked. I should have called the class something more generic than pinboard since I used it on things that aren’t pinboard as well.


.pinboard {
  font: normal normal 12px/1.2 Helvetica,Roboto,"Segoe UI",Calibri,sans-serif;
  padding-top: 12px;
  padding-bottom: 12px;
  border-bottom: 2px solid #efefef; 
  line-height: 18px;

}

.pinboard:hover{
  background-color: #f1f7fa;
}

.pinboard a {
  color: #3498db;
  padding: 2px;

}

Screen Shot 2016-07-10 at 5.14.22 PM

This is kind of amusing. The following chunk of code uses Flickr’s API to get the total number of photos I’ve uploaded. It seems to take more code than I feel like it should but it works.

 $(document).ready(function() {

    $.ajax({
        url: 'https://api.flickr.com/services/rest/?method=flickr.people.getInfo&api_key=276580779b3354f9d6820e102e5775f0&user_id=29096601%40N00&format=json&jsoncallback=?',
        dataType: 'jsonp',
        success: function(data) {
                console.log(data); //dumps the data to the console to check if the callback is made successfully.
                $.each(data, function(index, item) {
                    $('#flickrcount').prepend('<div class="bignumber">' + numberWithCommas(item.photos.count._content) + '</div>');
                    $('#details').append(timeConverter(item.photos.firstdate._content));
                }); //each
            } 
    }); 
}); 

function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
//from a stackoverflow answer to format the date nicely
function timeConverter(UNIX_timestamp) {
    var a = new Date(UNIX_timestamp * 1000);
    var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
    var year = a.getFullYear();
    var month = months[a.getMonth()];
    var date = a.getDate();
    var hour = a.getHours();
    var min = a.getMinutes();
    var sec = a.getSeconds();
    var time = date + ' ' + month + ' ' + year;
    return time;
}

The rest of the page is my more typical Angular construction pattern with Bootstrap. It feels much simpler than the jQuery version to me. It’s using the WordPress JSON in a cached manner.

var app = angular.module('myApp', ['ngSanitize']);
			//
app.controller('SuperCtrl', function($scope, $http) {
$http.get("./json/weeklyPhotos.json")
.success(function(response) {$scope.entries = response;});
});
			
<div class="col-md-10 col-md-offset-1 col-xsm-12">
	<a href="{{ entry.link }}">		 
		<div ng-repeat="entry in entries | filter: search| orderBy:'-id' : reverse" class="col-lg-2 col-md-3 col-xs-12 artist" style="background-image: url({{ entry.better_featured_image.media_details.sizes.medium.source_url }}); background-repeat: no-repeat; background-position: center; background-size: cover ">	
		<div class="artist_title"><h4 ng-bind-html="entry.title.rendered"></h4>
		</a>	
	</div>		      
</div>	

Screen Shot 2016-07-10 at 5.14.41 PM
The Presentations page is fairly similar. It uses Angular and Bootstrap for display and the JSON from a Google Sheets. I link to most of the evidence. I may rethink that a bit given some of the new options I have to automate things via Google Scripts and the tendency for things on the Internet to wander off.

var app = angular.module('myApp', ['ngSanitize','angular.filter']);
$gid = "1xG1ClBl5A0kuNca6TYJliKL-5oHSEx6OerAzAJO9f6o"
//$gid = $_GET['id'];
$gURL = "https://spreadsheets.google.com/feeds/list/" + $gid + "/1/public/values?alt=json";
app.controller('SuperCtrl', function($scope, $http) {
    $http.get($gURL)
    .success(function(response) {$scope.entries = response.feed.entry;});
});

There’s still a lot of stuff I don’t feel like I’m capturing well or efficiently. I need to think about it more and do some more work. It does bring up some larger issues that I need to think about career-wise. In the last few years, after resisting for quite some time, I have become a person who can program. I still have so very, very much to learn but I’ve learned a huge amount in the last few years- server stuff, php, WordPress, javascript, various APIs, a bit of Angular, lots of Google Script lately . . . I wonder about focusing. I know it’d help in some ways. I also realize that programming isn’t likely to be where I bring real value in terms of jobs that are likely to pay me. There are lots of younger people who can do more than I can technically. I do have a decent ability to think through things with people and to think about doing things from a variety of angles. I like to solve problems and make life better for the humans.


1 My most popular posts involve either scraping Instagram or a mouse drug game that I linked to several years ago.

2 The evisceration of one’s department will encourage a bit of attention there.

Comments on this post

  1. John Johnston said on July 11, 2016 at 6:43 am

    this is really lovely, elegant.

    I guess you using a Wp Api plugin to provide the json?

    I tried the same sort of thing on my ds106 blog, but in a much more horrible way:
    http://johnjohnston.info/106/ds106-activity-dashboard/

    • Tom Woodward said on July 11, 2016 at 7:09 am

      Thanks John. I’ve become something of a JSON fan.

      I am using the v2 plugin.

  2. carpetbomberz said on July 11, 2016 at 7:57 am

    Noting footnote #2 (ie evisceration etc.) I feel your pain. Our EdTech unit (started ’99-ended ’12) at rochester.edu got shutdown due to money and politics. I escaped to a desktop support job for 1 year, then they re-advertised my original job 1 year later. I applied for that position and I’m right back doing what I had been, with slight changes. EdTech will never go away, EdTech Lives.

    • Tom Woodward said on July 11, 2016 at 8:17 am

      I should clarify that no one at my level has been fired but we’ve had two open positions for nearly a year. We have since lost four more people as they’ve left for a variety of reasons. I’m hoping we’ll get it all straightened out but failing to prepare . . . and all that.

Leave a Reply

Trackbacks and Pingbacks on this post

No trackbacks.

TrackBack URL