browser side rendering of json resume https://github.com/jsonresume
template: https://github.com/jsonresume/jsonresume-theme-boilerplate
based on example from: https://github.com/cultofmetatron/jquery-autobars
browser side rendering of json resume https://github.com/jsonresume
template: https://github.com/jsonresume/jsonresume-theme-boilerplate
based on example from: https://github.com/cultofmetatron/jquery-autobars
| body { | |
| background: #fff; | |
| font: 15px Arial, Helvetica, sans-serif; | |
| line-height: 1.4; | |
| margin: 50px 0; | |
| margin-bottom: 100px; | |
| } | |
| em { | |
| color: #999; | |
| } | |
| p { | |
| line-height: 1.4; | |
| } | |
| ul { | |
| margin-bottom: 0; | |
| } | |
| section { | |
| margin-bottom: 2em; | |
| } | |
| blockquote { | |
| margin: 0; | |
| margin-bottom: 1em; | |
| } | |
| .item { | |
| margin-bottom: 1em; | |
| } | |
| #resume { | |
| margin: 0 auto; | |
| max-width: 480px; | |
| padding: 0 20px; | |
| } | |
| #basics { | |
| margin-bottom: -10px; | |
| } | |
| #basics h3 { | |
| margin-top: 1.5em; | |
| } | |
| #basics .contact strong, | |
| #location strong { | |
| clear: both; | |
| float: left; | |
| line-height: 1.3; | |
| width: 120px; | |
| } | |
| #profiles, | |
| #skills { | |
| overflow: hidden; | |
| } | |
| #profiles .item, | |
| #skills .item { | |
| float: left; | |
| width: 50%; | |
| } |
| <!DOCTYPE HTML> | |
| <head> | |
| <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> | |
| <title>Rafal Piekarski CV example</title> | |
| <link rel="stylesheet" href="boilerplate.css"> | |
| <script src="https://code.jquery.com/jquery-2.1.1.min.js" type="text/javascript"></script> | |
| <script src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.min.js" type="text/javascript" charset="utf-8"></script> | |
| <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> | |
| <script src="jquery-autobars.js" type="text/javascript"></script> | |
| <script src="boilerplate.hbs" type="text/x-handlebars-template"></script> | |
| <script type="text/javascript"> | |
| $(document).ready(function() { | |
| $(document).autoBars(function() { | |
| $.getJSON("resume.json", function(json) { | |
| var data = { "resume" : json}; | |
| var $html = $.handlebarTemplates['boilerplate'](data); | |
| $('body').append($html); | |
| }) | |
| .fail(function(jqxhr, textStatus, error) { | |
| var err = textStatus + ", " + error; | |
| console.log( "Request Failed: " + err ); | |
| }); | |
| }); | |
| }) | |
| </script> | |
| </head> | |
| <body> | |
| </body> | |
| /*global Handlebars */ | |
| /*global jQuery */ | |
| /* | |
| * this file is a basic helper utility for people | |
| * using handlebars.js. it allowes you to store several | |
| * handlebars templates seperated with | |
| * | |
| * <!--#?templateid--> | |
| * | |
| * | |
| * <!--#?end--> | |
| * | |
| * Created by Peter de Croos (Cultofmetatron) | |
| * blog.peterdecroos.com | |
| */ | |
| (function($) { | |
| 'use strict'; | |
| var methods; | |
| methods = { | |
| initialize: function () {}, | |
| parseName: function (url) { | |
| var splitName, splitUrl, name; | |
| splitUrl = url.split('/'); | |
| //get everything past the last slash | |
| name = splitUrl[splitUrl.length - 1]; | |
| //strip querystring | |
| name = name.split('?')[0]; | |
| splitName = name.split('.'); | |
| if (splitName.length > 1) { | |
| //strip extension | |
| splitName = splitName.slice(0, -1); | |
| } | |
| return splitName.join('.'); | |
| }, | |
| parsePartials: function (data) { | |
| var endToken, separatorToken, END_TOKEN_SIZE, | |
| templates; | |
| //first we seperate the strings with a regular expression | |
| separatorToken = /<!--#\?[a-zA-Z]+-->/; //matches the headers | |
| endToken = /<!--#\?end-->/; | |
| END_TOKEN_SIZE = 12; | |
| templates = {}; | |
| // now we get the names of the partials | |
| // first remove all white space characters that are in groups > 2 | |
| data = data.split('\n').join('').split(/\s{2,}/).join(''); | |
| // now that we have a whitespace stripped version, | |
| // we loop through chunking them. | |
| // get the first token and extract the key | |
| while (data.match(separatorToken)) { | |
| var token = data.match(separatorToken)[0]; //gets the first token | |
| var name = token.match(/[a-zA-Z]+/)[0];//the name we get token | |
| data = data.slice(token.length); | |
| // feed in characters till you get to the end tag. | |
| var endIndex = data.search(endToken); | |
| var source = data.slice(0, endIndex); | |
| // increment to the next size; | |
| data = data.slice(endIndex + END_TOKEN_SIZE); | |
| templates[name] = Handlebars.compile(source); | |
| } | |
| // register partials for use within Handlebars templates | |
| // for usage, see https://github.com/wycats/handlebars.js/#partials | |
| for (var key in templates) { | |
| if (Object.prototype.hasOwnProperty.call(templates, key)) { | |
| methods.registerPartial(key, templates[key]); | |
| } | |
| } | |
| }, | |
| registerPartial: function (key, partial) { | |
| Handlebars.registerPartial(key, partial); | |
| }, | |
| mainTemplates: function (context) { | |
| var pipe = [];//promise objects | |
| context.find('[type="text/x-handlebars-template"]') | |
| .each(function (index, element) { | |
| var loadUrl = $(element).attr('src'); | |
| //var name = loadUrl.match(/([^\/]+)(?=\.\w+$)/)[0]; | |
| var name = methods.parseName(loadUrl); | |
| //here we gather all our promises | |
| pipe.push( | |
| $.ajax({ | |
| url: loadUrl, | |
| dataType: 'text' | |
| }).done(function (data) { | |
| jQuery.handlebarTemplates[name] = Handlebars.compile(data); | |
| }) | |
| ); | |
| }); | |
| return pipe; | |
| }, | |
| partials: function (context) { | |
| //we take the nodes and pull out partials | |
| var pipe = [];//promise objects | |
| context.find('[type="text/x-handlebars-partial"]') | |
| .each(function (index, element) { | |
| //handlebarTemplates = Handlebars.compile($(element).html()); | |
| var loadUrl = $(element).attr('src'); | |
| //gather the promises | |
| pipe.push( | |
| $.ajax({ | |
| url: loadUrl, | |
| dataType: 'text' | |
| }).done(function (data) { | |
| //each pageload is performed asynchronously and so the data exists only in this | |
| //context. here we scrub the input and use it; | |
| methods.parsePartials(data); | |
| }) | |
| ); | |
| }); | |
| return pipe; | |
| } | |
| }; | |
| $.fn.autoBars = function(options, callback) { | |
| var args = Array.prototype.slice.call(arguments, 0); | |
| if (args.length === 1 && typeof(args[0]) === 'function') { | |
| //checks if there's only one argument and sets the | |
| // callback to be the first | |
| callback = options; | |
| options = {}; | |
| } | |
| //so we don't overwrite it | |
| jQuery.handlebarTemplates = jQuery.handlebarTemplates || {}; | |
| jQuery.handlebarTemplates.partials = | |
| jQuery.handlebarTemplates.partials || {}; | |
| var settings = $.extend({ | |
| loadHandlebars : false, | |
| }, options); | |
| // gather all the promises from the multiple async calls | |
| var partialPromises = methods.partials(this); | |
| var templatesPromises = methods.mainTemplates(this); | |
| var promises = partialPromises.concat(templatesPromises); | |
| // we delay execution of the callback until all | |
| // the promises are fulfilled!! | |
| if (typeof(callback) === 'function') { | |
| $.when.apply(this, promises).done(callback); | |
| } | |
| // return the original jquery object | |
| return this; | |
| }; | |
| })(jQuery); | |
| { | |
| "basics": { | |
| "name": "Rafał Piekrski", | |
| "label": "Senior full-stack developer", | |
| "picture": "https://rebased.pl/images/team/ravbaker.jpg", | |
| "website": "https://github.com/ravbaker", | |
| "location": { | |
| "city": "Warsaw", | |
| "countryCode": "PL" | |
| }, | |
| "profiles": [ | |
| { | |
| "network": "LinkedIn", | |
| "username": "ravbaker", | |
| "url": "https://linkedin.com/in/ravbaker" | |
| }, | |
| { | |
| "network": "Twitter", | |
| "username": "RaVbaker", | |
| "url": "https://twitter.com/ravbaker" | |
| }, | |
| { | |
| "network": "StackOverflow", | |
| "username": "ravbaker", | |
| "url": "https://stackoverflow.com/users/285848/ravbaker" | |
| } | |
| ] | |
| }, | |
| "work": [ | |
| { | |
| "company": "Rebased", | |
| "position": "Senior full-stack developer", | |
| "website": "https://rebased.pl", | |
| "startDate": "2014-11-01", | |
| "endDate": "now", | |
| "summary": "I have worked mostly on legacy projects, migrated infrastructure from self-hosted to AWS and backend (Ruby) applications.", | |
| "highlights": [ | |
| "Multi-tenant e-commerce platform", | |
| "API and internal tools for company providing private transportation service all over the world. A monolith project in process of being rewritten to around twenty micro services. My team is responsible for maintaining the legacy app and handling pricing, payments, billing & fraud preventing. Technologies used: Ruby on Rails 3/4/5, MySQL, PostgreSQL, AWS SQS, SNS, various 3rd-party APIs.", | |
| "Ruby, Sinatra, Ruby on Rails, MySQL, PostgreSQL, Redis, AWS, Golang" | |
| ] | |
| }, | |
| { | |
| "company": "Ragnarson", | |
| "position": "Ruby developer", | |
| "website": "https://ragnarson.com", | |
| "startDate": "2012-07-01", | |
| "endDate": "2014-10-30", | |
| "highlights": [ | |
| "Working with clients all over Europe and developers around world", | |
| "Maintaining app that deals with Global Distibution Systems (GDS) while being available 24/7", | |
| "Dealing with big amounts of data about advertisements and e-commerce offers that should be processed on time in multi-thread applications.", | |
| "Implementing UI in AngularJS for Mobile & Desktop", | |
| "Designing and implemneting architecture for a green field project from start till dealing with first tens of thousads customers", | |
| "Ruby, Rails, Sinatra, JavaScript, BackboneJS, AngularJS, PostgreSQL, Redis, Docker, ElasticSearch" | |
| ] | |
| }, | |
| { | |
| "company": "Nokaut.pl", | |
| "position": "Team coordinator & lead developer", | |
| "website": "http://nokaut.pl", | |
| "startDate": "2008-02-01", | |
| "endDate": "2012-12-31", | |
| "summary": "Working on one of biggest polish e-commerce site (millions of users every month)", | |
| "highlights": [ | |
| "Designing, optimizing and implementing solutions in a scrum team", | |
| "Building and tweaking search engine solution based on Solr technology", | |
| "Actively managing team of 10+ people", | |
| "PHP, JavaScript, MySQL, Java, Apache Solr" | |
| ] | |
| }, | |
| { | |
| "company": "DeSmart", | |
| "position": "PHP Developer", | |
| "website": "http://desmart.com", | |
| "startDate": "2007-06-01", | |
| "endDate": "2008-01-31", | |
| "highlights": [ | |
| "Working in small software agency with various clients", | |
| "Developing fast and responsive solutions for a lot frontend problems" | |
| ] | |
| } | |
| ], | |
| "education": [ | |
| { | |
| "institution": "Stanford University", | |
| "area": "Computer Science", | |
| "studyType": "Coursera Specialization", | |
| "startDate": "2016-04-13", | |
| "endDate": "", | |
| "courses": [ | |
| "Machine Learning (certificate http://bit.ly/coursera-cert)" | |
| ], | |
| "gpa": "100%" | |
| }, | |
| { | |
| "institution": "Polish-Japanese Academy of Information Technology", | |
| "area": "Computer Science", | |
| "studyType": "Engineer's degree", | |
| "startDate": "2009-03-01", | |
| "endDate": "2011-06-30", | |
| "courses": [], | |
| "gpa": "5.0" | |
| }, | |
| { | |
| "institution": "Gdansk University of Technology", | |
| "area": "Computer Science", | |
| "studyType": "Engineer's degree, 2 years completed", | |
| "startDate": "2007-10-01", | |
| "endDate": "2009-02-28" | |
| } | |
| ], | |
| "skills": [ | |
| { | |
| "name": "Languages", | |
| "keywords": [ | |
| "Ruby", | |
| "Go", | |
| "PHP", | |
| "JavaScript", | |
| "Python", | |
| "Java" | |
| ] | |
| }, | |
| { | |
| "name": "Frameworks", | |
| "keywords": [ | |
| "Ruby on Rails", | |
| "Sinatra", | |
| "Backbone.js", | |
| "React.js", | |
| "AngularJS" | |
| ] | |
| }, | |
| { | |
| "name": "Databases", | |
| "keywords": [ | |
| "PostgreSQL", | |
| "MySQL", | |
| "MongoDB", | |
| "Redis", | |
| "Elastic Search", | |
| "Apache Solr" | |
| ] | |
| }, | |
| { | |
| "name": "Web", | |
| "keywords": [ | |
| "HTML", | |
| "HAML", | |
| "SLIM", | |
| "CSS", | |
| "SASS", | |
| "CoffeeScript", | |
| "EcmaScript", | |
| "jQuery" | |
| ] | |
| }, | |
| { | |
| "name": "Servers", | |
| "keywords": [ | |
| "Nginx", | |
| "Unicorn", | |
| "Puma", | |
| "AWS Lambda", | |
| "Chef", | |
| "Ansible" | |
| ] | |
| }, | |
| { | |
| "name": "Testing", | |
| "keywords": [ | |
| "RSpec", | |
| "Minitest", | |
| "TDD", | |
| "BDD" | |
| ] | |
| }, | |
| { | |
| "name": "Source Code Management", | |
| "keywords": [ | |
| "GIT", | |
| "SVN" | |
| ] | |
| }, | |
| { | |
| "name": "External services", | |
| "keywords": [ | |
| "Amazon AWS", | |
| "Facebook API", | |
| "Flickr API", | |
| "Youtube API", | |
| "Stripe", | |
| "Braintree", | |
| "Heroku" | |
| ] | |
| } | |
| ], | |
| "volunteer": [ | |
| { | |
| "organization": "Chemin Neuf Community", | |
| "position": "Volunteer", | |
| "website": "http://chemin-neuf.org", | |
| "startDate": "2011-09-01", | |
| "endDate": "2012-06-30", | |
| "summary": "During my sabbatical I service at student residence in Lodz (Poland) and help community in managing their website and migrating from Joomla to new Zope/Plone installation." | |
| } | |
| ], | |
| "languages": [ | |
| { | |
| "language": "Polish", | |
| "fluency": "Native speaker" | |
| }, | |
| { | |
| "language": "English", | |
| "fluency": "Fluent" | |
| }, | |
| { | |
| "language": "French", | |
| "fluency": "Conversational" | |
| } | |
| ] | |
| } |