No more duplicated themes

This commit is contained in:
Arnaud Ysmal 2018-05-09 23:30:40 +02:00
parent 5d82dbf58b
commit 6bfd12756d
15 changed files with 286 additions and 2223 deletions

View File

@ -34,9 +34,7 @@ import (
"jsonresume/model" "jsonresume/model"
"jsonresume/themes" "jsonresume/themes"
_ "jsonresume/themes/kendall" _ "jsonresume/themes/kendall"
_ "jsonresume/themes/kendallfr"
_ "jsonresume/themes/stackoverflow" _ "jsonresume/themes/stackoverflow"
_ "jsonresume/themes/stackoverflowfr"
) )
func main() { func main() {
@ -45,6 +43,7 @@ func main() {
var theme string var theme string
var err error var err error
var outf string var outf string
var lang string
var f *os.File var f *os.File
flag.StringVar(&resume, "resume", "resume.json", "JSON of resume") flag.StringVar(&resume, "resume", "resume.json", "JSON of resume")
@ -53,6 +52,8 @@ func main() {
flag.StringVar(&theme, "t", "", "Theme of resume") flag.StringVar(&theme, "t", "", "Theme of resume")
flag.StringVar(&outf, "out", "-", "Output file") flag.StringVar(&outf, "out", "-", "Output file")
flag.StringVar(&outf, "o", "-", "Output file") flag.StringVar(&outf, "o", "-", "Output file")
flag.StringVar(&lang, "lang", "", "Force lang")
flag.StringVar(&lang, "l", "", "Force lang")
flag.Parse() flag.Parse()
if outf == "-" { if outf == "-" {
@ -65,6 +66,9 @@ func main() {
if r, err = model.Parse(resume); err != nil { if r, err = model.Parse(resume); err != nil {
log.Fatal(err) log.Fatal(err)
} }
if lang != "" {
r.Language = lang
}
if t, exists := themes.Themes[theme]; exists { if t, exists := themes.Themes[theme]; exists {
if err = t.Render(r, f); err != nil { if err = t.Render(r, f); err != nil {

View File

@ -51,6 +51,7 @@ func (ct *ResumeDate) UnmarshalJSON(b []byte) (err error) {
// Resume represent Curriculum Vitae // Resume represent Curriculum Vitae
type Resume struct { type Resume struct {
Title string `json:"title"` Title string `json:"title"`
Language string `json:"lang"`
Basic Basic `json:"basics"` Basic Basic `json:"basics"`
Work []Work `json:"work"` Work []Work `json:"work"`
Volunteer []Volunteer `json:"volunteer"` Volunteer []Volunteer `json:"volunteer"`
@ -66,19 +67,19 @@ type Resume struct {
// Basic is the basic information for a resume // Basic is the basic information for a resume
type Basic struct { type Basic struct {
Name string `json:"name"` Name string `json:"name"`
Label string `json:"label"` Label string `json:"label"`
Image string `json:"image"` Image string `json:"image"`
Email string `json:"email"` Email string `json:"email"`
Phone string `json:"phone"` Phone string `json:"phone"`
URL string `json:"url"` URL string `json:"url"`
Summary string `json:"summary"` Summary string `json:"summary"`
ResumeLocation Location `json:"location"` Location UserLocation `json:"location"`
Profiles []SocialProfile `json:"profiles"` Profiles []SocialProfile `json:"profiles"`
} }
// Location is the location details of a resume owner. // Location is the location details of a resume owner.
type Location struct { type UserLocation struct {
Address string `json:"address"` Address string `json:"address"`
PostalCode string `json:"postalCode"` PostalCode string `json:"postalCode"`
City string `json:"city"` City string `json:"city"`
@ -93,35 +94,35 @@ type SocialProfile struct {
URL string `json:"url"` URL string `json:"url"`
} }
type JobHighlight struct { type Highlight struct {
Title string `json:"title"` Title string `json:"title"`
Items []string `json:"items"` Items []string `json:"items"`
} }
// Work is the work details of the resume owner. // Work is the work details of the resume owner.
type Work struct { type Work struct {
Name string `json:"name"` Name string `json:"name"`
WorkLocation string `json:"location"` Location string `json:"location"`
Description string `json:"description"` Description string `json:"description"`
Position string `json:"position"` Position string `json:"position"`
URL string `json:"url"` URL string `json:"url"`
StartDate ResumeDate `json:"startDate"` StartDate ResumeDate `json:"startDate"`
EndDate ResumeDate `json:"endDate"` EndDate ResumeDate `json:"endDate"`
Summary string `json:"summary"` Summary string `json:"summary"`
Highlights []JobHighlight `json:"highlights"` Highlights []Highlight `json:"highlights"`
Keywords []string `json:"keywords"` Keywords []string `json:"keywords"`
} }
// Volunteer is the volunteer details of the resume owner. // Volunteer is the volunteer details of the resume owner.
type Volunteer struct { type Volunteer struct {
Organization string `json:"organization"` Organization string `json:"organization"`
Position string `json:"position"` Position string `json:"position"`
URL string `json:"url"` URL string `json:"url"`
StartDate ResumeDate `json:"startDate"` StartDate ResumeDate `json:"startDate"`
EndDate ResumeDate `json:"endDate"` EndDate ResumeDate `json:"endDate"`
Summary string `json:"summary"` Summary string `json:"summary"`
Highlights []string `json:"highlights"` Highlights []Highlight `json:"highlights"`
Keywords []string `json:"keywords"` Keywords []string `json:"keywords"`
} }
// Education is the education details of the resume owner. // Education is the education details of the resume owner.
@ -179,16 +180,16 @@ type Reference struct {
// Volunteer is the volunteer details of the resume owner. // Volunteer is the volunteer details of the resume owner.
type Project struct { type Project struct {
Name string `json:"name"` Name string `json:"name"`
Description string `json:"description"` Description string `json:"description"`
Highlights []string `json:"highlights"` Highlights []Highlight `json:"highlights"`
Keywords []string `json:"keywords"` Keywords []string `json:"keywords"`
StartDate ResumeDate `json:"startDate"` StartDate ResumeDate `json:"startDate"`
EndDate ResumeDate `json:"endDate"` EndDate ResumeDate `json:"endDate"`
URL string `json:"url"` URL string `json:"url"`
Roles []string `json:"roles"` Roles []string `json:"roles"`
Entity string `json:"entity"` Entity string `json:"entity"`
Type string `json:"type"` Type string `json:"type"`
} }
func Parse(f string) (*Resume, error) { func Parse(f string) (*Resume, error) {

View File

@ -26,7 +26,6 @@
package kendall package kendall
import ( import (
"io/ioutil"
"jsonresume/themes" "jsonresume/themes"
"path" "path"
"text/template" "text/template"
@ -43,25 +42,23 @@ var Theme = themes.Theme{
Name: "kendall", Name: "kendall",
Directory: packageDirectory, Directory: packageDirectory,
Functions: template.FuncMap{ Functions: template.FuncMap{
"iconClass": themes.IconClass, "css": getCSS,
"formatDateWork": themes.FormatDateWork, "printcss": getPrintCSS,
"formatDateEdu": themes.FormatDateEdu,
"formatDatePub": themes.FormatDatePub,
"css": getCSS,
"printcss": getPrintCSS,
}, },
Template: fileTemplate,
} }
func init() { func init() {
t, _ := Asset(path.Join(packageDirectory, fileTemplate))
Theme.Template = string(t)
(&Theme).Register() (&Theme).Register()
} }
func getCSS() string { func getCSS() string {
r, _ := ioutil.ReadFile(path.Join(packageDirectory, fileCSS)) r, _ := Asset(path.Join(packageDirectory, fileCSS))
return string(r) return string(r)
} }
func getPrintCSS() string { func getPrintCSS() string {
r, _ := ioutil.ReadFile(path.Join(packageDirectory, fileCSSPrint)) r, _ := Asset(path.Join(packageDirectory, fileCSSPrint))
return string(r) return string(r)
} }

View File

@ -1,10 +1,10 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="{{.Language}}">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Resume of {{.Basic.Name}}</title> <title>{{.Lang.TitlePrefix}} {{.Basic.Name}}</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<style>{{css}}</style> <style>{{css}}</style>
@ -32,14 +32,14 @@
{{if .Basic.Summary -}} {{if .Basic.Summary -}}
<!-- ABOUT ME --> <!-- ABOUT ME -->
<div class="box"> <div class="box">
<h2><i class="fa fa-user ico"></i> About</h2> <h2><i class="fa fa-user ico"></i> {{.Lang.About}}</h2>
<p>{{.Basic.Summary}}</p> <p>{{.Basic.Summary}}</p>
</div> </div>
{{- end}} {{- end}}
{{if .Work -}} {{if .Work -}}
<!-- WORK EXPERIENCE --> <!-- WORK EXPERIENCE -->
<div class="box"> <div class="box">
<h2><i class= "fa fa-suitcase ico"></i> Work Experience</h2> <h2><i class= "fa fa-suitcase ico"></i> {{.Lang.WorkExperience}}</h2>
{{range .Work -}} {{range .Work -}}
<div class="job clearfix"> <div class="job clearfix">
<div class="row"> <div class="row">
@ -50,7 +50,7 @@
<a href="{{.URL}}" target= "_blank"><i class="fa fa-globe ico"></i> {{.URL}}</a> <a href="{{.URL}}" target= "_blank"><i class="fa fa-globe ico"></i> {{.URL}}</a>
</div> </div>
{{- end}} {{- end}}
<div class="year">{{formatDateWork .StartDate}} {{formatDateWork .EndDate}}</div> <div class="year">{{formatDateMY .StartDate}} {{formatDateMY .EndDate}}</div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@ -83,11 +83,11 @@
{{if .Awards -}} {{if .Awards -}}
<!-- AWARDS --> <!-- AWARDS -->
<div class="box"> <div class="box">
<h2><i class="fa fa-certificate ico"></i> Awards</h2> <h2><i class="fa fa-certificate ico"></i> {{.Lang.Awards}}</h2>
<ul id="awards" class="clearfix"> <ul id="awards" class="clearfix">
{{range .Awards -}} {{range .Awards -}}
<li> <li>
<div class="year pull-left">{{formatDatePub .Date}}</div> <div class="year pull-left">{{formatDateDMY .Date}}</div>
<div class="description pull-right"> <div class="description pull-right">
<h3>{{.Awarder}}</h3> <h3>{{.Awarder}}</h3>
<p><i class="fa fa-trophy ico"></i> {{.Title}}</p> <p><i class="fa fa-trophy ico"></i> {{.Title}}</p>
@ -101,7 +101,7 @@
{{if .Volunteer -}} {{if .Volunteer -}}
<!-- VOLUNTEER --> <!-- VOLUNTEER -->
<div class="box"> <div class="box">
<h2><i class= "fa fa-group ico"></i> Volunteer</h2> <h2><i class= "fa fa-group ico"></i> {{.Lang.Volunteer}}</h2>
{{range .Volunteer -}} {{range .Volunteer -}}
<div class="job clearfix"> <div class="job clearfix">
<div class="row"> <div class="row">
@ -112,7 +112,7 @@
<a href="{{.URL}}" target= "_blank"><i class="fa fa-globe ico"></i> {{.URL}}</a> <a href="{{.URL}}" target= "_blank"><i class="fa fa-globe ico"></i> {{.URL}}</a>
</div> </div>
{{- end}} {{- end}}
<div class="year">{{formatDateWork .StartDate}} {{formatDateWork .EndDate}}</div> <div class="year">{{formatDateMY .StartDate}} {{formatDateMY .EndDate}}</div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@ -124,7 +124,14 @@
<div class="highlights"></div> <div class="highlights"></div>
<ul class="list-group"> <ul class="list-group">
{{range .Highlights -}} {{range .Highlights -}}
<li class="list-group-item">{{.}}</li> <li class="list-group-item">
{{.Title}}
{{if .Items -}}
<ul>
{{range .Items}}<li>{{.}}</li>{{end}}
</ul>
{{- end}}
</li>
{{- end}} {{- end}}
</ul> </ul>
{{- end}} {{- end}}
@ -139,12 +146,12 @@
<div class="col-xs-12 col-sm-5"> <div class="col-xs-12 col-sm-5">
<!-- CONTACT --> <!-- CONTACT -->
<div class="box clearfix"> <div class="box clearfix">
<h2><i class="fa fa-bullseye ico"></i> Contact</h2> <h2><i class="fa fa-bullseye ico"></i> {{.Lang.Contact}}</h2>
{{if .Basic.ResumeLocation.City -}} {{if .Basic.Location.City -}}
<div class="contact-item"> <div class="contact-item">
<div class="icon pull-left text-center"><span class="fa fa-map-marker fa-fw"></span></div> <div class="icon pull-left text-center"><span class="fa fa-map-marker fa-fw"></span></div>
{{if .Basic.ResumeLocation.Address}}<div class="title pull-right">{{.Basic.ResumeLocation.Address}}</div>{{- end}} {{if .Basic.Location.Address}}<div class="title pull-right">{{.Basic.Location.Address}}</div>{{- end}}
<div class="title {{if not .Basic.ResumeLocation.Address}}only {{- end}} pull-right">{{.Basic.ResumeLocation.City}}{{if .Basic.ResumeLocation.Region}}, {{.Basic.ResumeLocation.Region}}{{- end}}{{if .Basic.ResumeLocation.PostalCode}} {{.Basic.ResumeLocation.PostalCode}}{{- end}}{{if .Basic.ResumeLocation.CountryCode}} {{.Basic.ResumeLocation.CountryCode}}{{- end}}</div> <div class="title {{if not .Basic.Location.Address}}only {{- end}} pull-right">{{.Basic.Location.City}}{{if .Basic.Location.Region}}, {{.Basic.Location.Region}}{{- end}}{{if .Basic.Location.PostalCode}} {{.Basic.Location.PostalCode}}{{- end}}{{if .Basic.Location.CountryCode}} {{.Basic.Location.CountryCode}}{{- end}}</div>
</div> </div>
{{- end}} {{- end}}
{{if .Basic.Phone -}} {{if .Basic.Phone -}}
@ -176,11 +183,11 @@
{{if .Education -}} {{if .Education -}}
<!-- EDUCATION --> <!-- EDUCATION -->
<div class="box"> <div class="box">
<h2><i class="fa fa-university ico"></i> Education</h2> <h2><i class="fa fa-university ico"></i> {{.Lang.Education}}</h2>
<ul id="education" class="clearfix"> <ul id="education" class="clearfix">
{{range .Education -}} {{range .Education -}}
<li> <li>
<div class="year pull-left">{{formatDateEdu .StartDate}} {{formatDateEdu .EndDate}}</div> <div class="year pull-left">{{formatDateY .StartDate}} {{formatDateY .EndDate}}</div>
<div class="description pull-right"> <div class="description pull-right">
<h3>{{.Institution}}</h3> <h3>{{.Institution}}</h3>
{{if .StudyType}}<p><i class= "fa fa-graduation-cap ico"></i> {{.StudyType}}</p>{{end}} {{if .StudyType}}<p><i class= "fa fa-graduation-cap ico"></i> {{.StudyType}}</p>{{end}}
@ -207,7 +214,7 @@
{{if .Skills -}} {{if .Skills -}}
<!-- SKILLS --> <!-- SKILLS -->
<div class="box"> <div class="box">
<h2><i class="fa fa-tasks ico"></i> Skills</h2> <h2><i class="fa fa-tasks ico"></i> {{.Lang.Skills}}</h2>
{{range .Skills -}} {{range .Skills -}}
<div class="skills clearfix"> <div class="skills clearfix">
<div class="item-skills"> <div class="item-skills">
@ -226,7 +233,7 @@
{{if .Publications -}} {{if .Publications -}}
<!-- PUBLICATIONS --> <!-- PUBLICATIONS -->
<div class="box"> <div class="box">
<h2><i class="fa fa-book ico"></i> Publications</h2> <h2><i class="fa fa-book ico"></i> {{.Lang.Publications}}</h2>
{{range .Publications -}} {{range .Publications -}}
<div class="publication panel panel-default"> <div class="publication panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
@ -236,7 +243,7 @@
{{if .Publisher -}} {{if .Publisher -}}
<div class="publisher"><i class= "fa fa-bookmark ico"></i> {{.Publisher}}</div> <div class="publisher"><i class= "fa fa-bookmark ico"></i> {{.Publisher}}</div>
{{- end}} {{- end}}
<div class="year">{{formatDatePub .ReleaseDate}}</div> <div class="year">{{formatDateDMY .ReleaseDate}}</div>
{{if .URL -}} {{if .URL -}}
<div class="address"> <div class="address">
<a href="{{.URL}}" target= "_blank"><i class="fa fa-globe ico"></i> {{.URL}}</a> <a href="{{.URL}}" target= "_blank"><i class="fa fa-globe ico"></i> {{.URL}}</a>
@ -253,7 +260,7 @@
{{if .Languages -}} {{if .Languages -}}
<!-- LANGUAGES --> <!-- LANGUAGES -->
<div class="box"> <div class="box">
<h2><i class="fa fa-language ico"></i> Languages</h2> <h2><i class="fa fa-language ico"></i> {{.Lang.Languages}}</h2>
<ul class="list-group"> <ul class="list-group">
{{range .Languages -}} {{range .Languages -}}
<li class=" list-group-item">{{.Language}}<span class="skill badge pull-right">{{.Fluency}}</span></li> <li class=" list-group-item">{{.Language}}<span class="skill badge pull-right">{{.Fluency}}</span></li>
@ -264,7 +271,7 @@
{{if .Interests -}} {{if .Interests -}}
<!-- HOBBIES --> <!-- HOBBIES -->
<div class="box"> <div class="box">
<h2><i class="fa fa-heart ico"></i> Interests</h2> <h2><i class="fa fa-heart ico"></i> {{.Lang.Interests}}</h2>
{{range .Interests -}} {{range .Interests -}}
<div class="interests clearfix"> <div class="interests clearfix">
<div class="item-interests"> <div class="item-interests">
@ -281,7 +288,7 @@
{{- end}} {{- end}}
{{if .References -}} {{if .References -}}
<div class="box"> <div class="box">
<h2><i class= "fa fa-check-square ico"></i> References</h2> <h2><i class= "fa fa-check-square ico"></i> {{.Lang.References}}</h2>
{{range .References -}} {{range .References -}}
<blockquote> <blockquote>
<div>{{.Reference}}</div> <div>{{.Reference}}</div>

View File

@ -1,68 +0,0 @@
/*
* Copyright (c) 2018 Arnaud Ysmal. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
package kendallfr
import (
"io/ioutil"
"jsonresume/themes"
"path"
"text/template"
)
const (
packageDirectory = "themes/kendallfr"
fileCSS = "style.css"
fileCSSPrint = "print.css"
fileTemplate = "resume.template"
)
var Theme = themes.Theme{
Name: "kendallfr",
Directory: packageDirectory,
Functions: template.FuncMap{
"iconClass": themes.IconClass,
"formatDateWork": themes.FormatDateWorkFR,
"formatDateEdu": themes.FormatDateEduFR,
"formatDatePub": themes.FormatDatePubFR,
"css": getCSS,
"printcss": getPrintCSS,
},
Template: fileTemplate,
}
func getCSS() string {
r, _ := ioutil.ReadFile(path.Join(packageDirectory, fileCSS))
return string(r)
}
func getPrintCSS() string {
r, _ := ioutil.ReadFile(path.Join(packageDirectory, fileCSSPrint))
return string(r)
}
func init() {
(&Theme).Register()
}

View File

@ -1,91 +0,0 @@
body {
font-size: .95em;
-webkit-print-color-adjust: exact;
}
a[href]:after {
content: none !important;
}
#photo{
display: none;
}
.box {
margin-bottom: -10px;
}
blockquote,
#education,
#awards,
.contact-item,
.publication,
.skills,
.interests {
page-break-inside: avoid;
}
.col-sm-5{
width: 40%;
padding: 0 15px;
}
.col-sm-7{
width: 60%;
padding: 0 15px;
}
.skills .col-sm-offset-1,
.interests .col-sm-offset-1{
margin-top: -10px;
margin-bottom: 5px;
}
#education {
margin: 0;
margin-bottom: -20px;
}
#awards:before,
#education:before {
background: none;
}
#awards .description,
#education .description,
.job .details {
border: 1px solid #eee;
}
.publication,
.publication .panel-heading,
.publication .name{
margin: 0;
padding: 0 5px;
border: none;
}
.publication .panel-body {
padding: 0 10px;
margin: 0;
}
.badge {
margin: 0;
}
.list-group-item{
border: none;
margin: 0;
padding: 5px 15px;
}
.list-group-item:after{
content: '';
position: absolute;
top: 8px;
right: 0;
left: -1px;
height: 0;
width: 0;
border: solid transparent;
border-right-color: #999;
border-width: 4px;
pointer-events: none;
}

View File

@ -1,299 +0,0 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CV de {{.Basic.Name}}</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<style type="text/css">{{css}}</style>
<style type="text/css" media="print">{{printcss}}</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-12">
<div id="photo-header" class="text-center">
<!-- PHOTO (AVATAR) -->
{{if .Basic.Image -}}
<div id="photo">
<img src="{{.Basic.Image}}" alt="avatar">
</div>
{{- end}}
<div id="text-header" {{if not .Basic.Image}}style="margin-top: 90px;"{{- end}}>
<h1>{{.Basic.Name}}<br>{{if .Basic.Label}}<span>{{.Basic.Label}}</span>{{- end}}</h1>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-7">
{{if .Basic.Summary -}}
<!-- ABOUT ME -->
<div class="box">
<h2><i class="fa fa-user ico"></i> À propos</h2>
<p>{{.Basic.Summary}}</p>
</div>
{{- end}}
{{if .Work -}}
<!-- WORK EXPERIENCE -->
<div class="box">
<h2><i class= "fa fa-suitcase ico"></i> Expérience Professionnelle</h2>
{{range .Work -}}
<div class="job clearfix">
<div class="row">
<div class="details">
<div class="where">{{.Name}}</div>
{{if .URL -}}
<div class="address">
<a href="{{.URL}}" target= "_blank"><i class="fa fa-globe ico"></i> {{.URL}}</a>
</div>
{{- end}}
<div class="year">{{formatDateWork .StartDate}} {{formatDateWork .EndDate}}</div>
</div>
</div>
<div class="row">
<div class="job-details col-xs-11">
<div class="profession">{{.Position}}</div>
<div class="description">
{{.Summary -}}
{{if .Highlights -}}
<div class="highlights"></div>
<ul class="list-group">
{{range .Highlights -}}
<li class="list-group-item">
{{.Title}}
{{if .Items -}}
<ul>
{{range .Items}}<li>{{.}}</li>{{end}}
</ul>
{{- end}}
</li>
{{- end}}
</ul>
{{- end}}
</div>
</div>
</div>
</div>
{{- end}}
</div>
{{- end}}
{{if .Awards -}}
<!-- AWARDS -->
<div class="box">
<h2><i class="fa fa-certificate ico"></i> Récompenses</h2>
<ul id="awards" class="clearfix">
{{range .Awards -}}
<li>
<div class="year pull-left">{{formatDatePub .Date}}</div>
<div class="description pull-right">
<h3>{{.Awarder}}</h3>
<p><i class="fa fa-trophy ico"></i> {{.Title}}</p>
<p>{{.Summary}}</p>
</div>
</li>
{{- end}}
</ul>
</div>
{{- end}}
{{if .Volunteer -}}
<!-- VOLUNTEER -->
<div class="box">
<h2><i class= "fa fa-group ico"></i> Bénévolat</h2>
{{range .Volunteer -}}
<div class="job clearfix">
<div class="row">
<div class="details">
<div class="where">{{.Organization}}</div>
{{if .URL -}}
<div class="address">
<a href="{{.URL}}" target= "_blank"><i class="fa fa-globe ico"></i> {{.URL}}</a>
</div>
{{- end}}
<div class="year">{{formatDateWork .StartDate}} {{formatDateWork .EndDate}}</div>
</div>
</div>
<div class="row">
<div class="job-details col-xs-11">
<div class="profession">{{.Position}}</div>
<div class="description">
{{.Summary -}}
{{if .Highlights -}}
<div class="highlights"></div>
<ul class="list-group">
{{range .Highlights -}}
<li class="list-group-item">{{.}}</li>
{{- end}}
</ul>
{{- end}}
</div>
</div>
</div>
</div>
{{- end}}
</div>
{{- end}}
</div>
<div class="col-xs-12 col-sm-5">
<!-- CONTACT -->
<div class="box clearfix">
<h2><i class="fa fa-bullseye ico"></i> Contact</h2>
{{if .Basic.ResumeLocation.City -}}
<div class="contact-item">
<div class="icon pull-left text-center"><span class="fa fa-map-marker fa-fw"></span></div>
{{if .Basic.ResumeLocation.Address}}<div class="title pull-right">{{.Basic.ResumeLocation.Address}}</div>{{- end}}
<div class="title {{if not .Basic.ResumeLocation.Address}}only {{- end}} pull-right">{{.Basic.ResumeLocation.City}}{{if .Basic.ResumeLocation.Region}}, {{.Basic.ResumeLocation.Region}}{{- end}}{{if .Basic.ResumeLocation.PostalCode}} {{.Basic.ResumeLocation.PostalCode}}{{- end}}{{if .Basic.ResumeLocation.CountryCode}} {{.Basic.ResumeLocation.CountryCode}}{{- end}}</div>
</div>
{{- end}}
{{if .Basic.Phone -}}
<div class="contact-item">
<div class="icon pull-left text-center"><span class="fa fa-phone fa-fw"></span></div>
<div class="title only pull-right">{{.Basic.Phone}}</div>
</div>
{{- end}}
{{if .Basic.Email -}}
<div class="contact-item">
<div class="icon pull-left text-center"><span class="fa fa-envelope fa-fw"></span></div>
<div class="title only pull-right"><a href="mailto:{{.Basic.Email}}" target="_blank">{{.Basic.Email}}</a></div>
</div>
{{- end}}
{{if .Basic.URL -}}
<div class="contact-item">
<div class="icon pull-left text-center"><span class="fa fa-globe fa-fw"></span></div>
<div class="title only pull-right"><a href="{{.Basic.URL}}" target="_blank">{{.Basic.URL}}</a></div>
</div>
{{- end}}
{{range .Basic.Profiles -}}
<div class="contact-item">
<div class="icon pull-left text-center"><span class="{{iconClass .Network}} fa-fw"></span></div>
<div class="title pull-right">{{.Network}}</div>
<div class="description pull-right"><a href="{{.URL}}" target="_blank">{{if .UserName}}{{.UserName}}{{- end}}{{if not .UserName}}{{.URL}}{{- end}}</a></div>
</div>
{{- end}}
</div>
{{if .Education -}}
<!-- EDUCATION -->
<div class="box">
<h2><i class="fa fa-university ico"></i> Formation</h2>
<ul id="education" class="clearfix">
{{range .Education -}}
<li>
<div class="year pull-left">{{formatDateEdu .StartDate}} {{formatDateEdu .EndDate}}</div>
<div class="description pull-right">
<h3>{{.Institution}}</h3>
{{if .StudyType}}<p><i class= "fa fa-graduation-cap ico"></i> {{.StudyType}}</p>{{end}}
<p>{{.Area}}</p>
{{if .GPA -}}
<p>
GPA: {{.GPA}}
</p>
{{- end}}
{{if .Courses -}}
<div>Courses</div>
<ul class="list-group">
{{range .Courses -}}
<li class="list-group-item">{{.}}</li>
{{- end}}
</ul>
{{- end}}
</div>
</li>
{{- end}}
</ul>
</div>
{{- end}}
{{if .Skills -}}
<!-- SKILLS -->
<div class="box">
<h2><i class="fa fa-tasks ico"></i> Compétences</h2>
{{range .Skills -}}
<div class="skills clearfix">
<div class="item-skills">
{{.Name}}
{{if .Level}}<span class="skill-level">{{.Level}}</span>{{- end}}
</div>
<div class="col-sm-offset-1 col-sm-12 clearfix">
{{range .Keywords -}}
<span class= "skill badge">{{.}}</span>
{{- end}}
</div>
</div>
{{- end}}
</div>
{{- end}}
{{if .Publications -}}
<!-- PUBLICATIONS -->
<div class="box">
<h2><i class="fa fa-book ico"></i> Publications</h2>
{{range .Publications -}}
<div class="publication panel panel-default">
<div class="panel-heading">
<div class="name panel-title">{{.Name}}</div>
</div>
<div class="panel-body">
{{if .Publisher -}}
<div class="publisher"><i class= "fa fa-bookmark ico"></i> {{.Publisher}}</div>
{{- end}}
<div class="year">{{formatDatePub .ReleaseDate}}</div>
{{if .URL -}}
<div class="address">
<a href="{{.URL}}" target= "_blank"><i class="fa fa-globe ico"></i> {{.URL}}</a>
</div>
{{- end}}
{{if .Summary -}}
<p>{{.Summary}}</p>
{{- end}}
</div>
</div>
{{- end}}
</div>
{{- end}}
{{if .Languages -}}
<!-- LANGUAGES -->
<div class="box">
<h2><i class="fa fa-language ico"></i> Langues</h2>
<ul class="list-group">
{{range .Languages -}}
<li class=" list-group-item">{{.Language}}<span class="skill badge pull-right">{{.Fluency}}</span></li>
{{- end}}
</ul>
</div>
{{- end}}
{{if .Interests -}}
<!-- HOBBIES -->
<div class="box">
<h2><i class="fa fa-heart ico"></i> Intérêts</h2>
{{range .Interests -}}
<div class="interests clearfix">
<div class="item-interests">
{{.Name -}}
</div>
<div class="col-sm-offset-1 col-sm-12 clearfix">
{{range .Keywords -}}
<span class= "interest badge">{{.}}</span>
{{- end}}
</div>
</div>
{{- end}}
</div>
{{- end}}
{{if .References -}}
<div class="box">
<h2><i class= "fa fa-check-square ico"></i> Références</h2>
{{range .References -}}
<blockquote>
<div>{{.Reference}}</div>
<footer>{{.Name}}</footer>
</blockquote><br>
{{- end}}
</div>
{{- end}}
</div>
</div>
</div>
</body>
</html>

View File

@ -1,276 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,600,700,800);
@charset "utf-8";
@-webkit-viewport { width: device-width; }
@-moz-viewport { width: device-width; }
@-ms-viewport { width: device-width; }
@-o-viewport { width: device-width; }
@viewport { width: device-width; }
body{
font-family: 'Open Sans', Arial, Tahoma;
font-weight: 400;
color: #363636;
background: #334960;
}
blockquote {
font-size: 1em;
}
.container{
margin-top: 80px;
margin-bottom: 15px;
background: #fff;
}
#photo-header{
margin-top: -75px;
}
#photo{
width: 160px;
height: 160px;
border-radius: 50%;
overflow: hidden;
padding: 5px;
background: #334960;
display: inline-block;
}
#photo img{
width: 150px;
height: 150px;
border-radius: 50%;
}
#text-header h1{
margin: 0;
padding: 0;
font-size: 1.5em;
font-weight: 700;
text-transform: uppercase;
letter-spacing: -1px;
}
#text-header h1::first-line{
font-size: 1.5em;
font-weight: 800;
line-height: 1.5em;
}
#text-header h1 span{
color: #334960;
opacity: 0.7;
}
#text-header h1 sup{
opacity: 0.5;
}
#text-header:after{
width: 100%;
height: 3px;
border-bottom: 1px solid #ddd;
margin-top: 15px;
content: '';
display: block;
}
.box{
padding-bottom: 10px;
margin-bottom: 25px;
}
.box h2{
color: #227c74;
font-size: 1.5em;
font-weight: 700;
text-transform: uppercase;
}
#awards,
#education{
margin-top: 20px;
margin-bottom: 0;
position: relative;
padding: 1em 0;
list-style: none;
}
#awards:before,
#education:before {
width: 5px;
height: 100%;
position: absolute;
left: 35px;
top: 0;
content: ' ';
display: block;
background: #32475c;
background: -moz-linear-gradient(top, #ffffff 0%, #32475c 7%, #32475c 89%, #ffffff 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(7%,#32475c), color-stop(89%,#32475c), color-stop(100%,#ffffff));
background: -webkit-linear-gradient(top, #ffffff 0%,#32475c 7%,#32475c 89%,#ffffff 100%);
background: -o-linear-gradient(top, #ffffff 0%,#32475c 7%,#32475c 89%,#ffffff 100%);
background: -ms-linear-gradient(top, #ffffff 0%,#32475c 7%,#32475c 89%,#ffffff 100%);
background: linear-gradient(to bottom, #ffffff 0%,#32475c 7%,#32475c 89%,#ffffff 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#ffffff',GradientType=0 );
}
#awards li,
#education li{
width: 100%;
z-index: 2;
position: relative;
float: left;
}
#awards .year,
#education .year{
width: 14%;
background: #fff;
padding: 10px;
font-weight: 700;
display: inline-block;
}
#awards .description,
#education .description{
width: 83%;
display: inline-block;
background: #eee;
margin-bottom: 10px;
position: relative;
padding: 10px;
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
}
#awards .description:after,
#education .description:after {
content: '';
position: absolute;
top: 15px;
right: 0;
left: -16px;
height: 0;
width: 0;
border: solid transparent;
border-right-color: #eee;
border-width: 8px;
pointer-events: none;
}
#awards .description h3,
#education .description h3{
font-size: 1.2em;
margin: 0;
padding: 0;
font-weight: 700;
}
#awards .description p,
#education .description p{
margin-top: 5px;
padding: 0;
}
.job{
margin-bottom: 15px;
}
.job .details {
margin-left: 3%;
width: 95%;
padding: 10px;
margin-bottom: 10px;
background: #eee;
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
}
.job .where{
font-size: 1.2em;
font-weight: bold;
}
.job .year{
opacity: 0.7;
}
.job .profession{
font-size: 1.2em;
font-weight: bold;
}
.job .description{
line-height: 1.5em;
}
.job .highlights{
padding: 5px 0;
font-weight: bold;
}
.job .job-details {
padding-left: 5%;
width: 100%;
}
.publication {
margin-bottom: 0;
}
.publication .name{
font-size: 1em;
font-weight: bold;
}
.publication .year{
opacity: 0.7;
}
.publication p{
margin: 0;
padding-top: 10px;
}
.contact-item{
width: 100%;
float: left;
}
.contact-item .icon{
padding: 10px;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
color: #32475c;
background: #eee;
}
.contact-item:last-child .icon{
border-bottom: none;
}
.contact-item .title{
width: 80%;
width: calc(100% - 55px);
font-weight: 700;
opacity: 0.9;
}
.contact-item .title.only{
margin-top: 10px;
}
.contact-item .description{
width: 80%;
width: calc(100% - 55px);
color: #334960;
}
.item-interests,
.item-skills{
height: 30px;
color: #334960;
padding: 5px 10px;
margin-bottom: 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 1.1em;
font-weight: 600;
}
.interest,
.skill{
color: #fff;
display: inline-block;
margin-right: 5px;
margin-bottom: 5px;
padding: 5px 10px;
background: #32475c;
position: relative;
font-size: .85em;
}
.skill-level {
background-color: #227c74;
border-radius: 4px;
color: #fff;
padding: 1px 8px;
font-size: .75em;
position: absolute;
margin: 1px 10px;
}
#language-skills .skill{
margin: 10px 0;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}

View File

@ -1,5 +1,5 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="{{.Language}}">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
@ -27,22 +27,22 @@
</div> </div>
{{- end}} {{- end}}
{{if .Basic.ResumeLocation.City}} {{if .Basic.Location.City}}
<span class="location"> <span class="location">
{{if .Basic.ResumeLocation.Address}} {{if .Basic.Location.Address}}
<span class="address">{{.Basic.ResumeLocation.Address}},</span> <span class="address">{{.Basic.Location.Address}},</span>
{{- end}} {{- end}}
{{if .Basic.ResumeLocation.PostalCode}} {{if .Basic.Location.PostalCode}}
<span class="postalCode">{{.Basic.ResumeLocation.PostalCode}},</span> <span class="postalCode">{{.Basic.Location.PostalCode}},</span>
{{- end}} {{- end}}
{{if .Basic.ResumeLocation.City}} {{if .Basic.Location.City}}
<span class="city">{{.Basic.ResumeLocation.City}},</span> <span class="city">{{.Basic.Location.City}},</span>
{{- end}} {{- end}}
{{if .Basic.ResumeLocation.Region}} {{if .Basic.Location.Region}}
<span class="region">{{.Basic.ResumeLocation.Region}}</span> <span class="region">{{.Basic.Location.Region}}</span>
{{- end}} {{- end}}
{{if .Basic.ResumeLocation.CountryCode}} {{if .Basic.Location.CountryCode}}
<span class="countryCode">{{.Basic.ResumeLocation.CountryCode}}</span> <span class="countryCode">{{.Basic.Location.CountryCode}}</span>
{{- end}} {{- end}}
</span> </span>
{{- end}} {{- end}}
@ -99,7 +99,7 @@
{{if .Skills}} {{if .Skills}}
<section class="section margin1"> <section class="section margin1">
<header> <header>
<h2 class='section-title'>Skills</h2> <h2 class='section-title'>{{.Lang.Skills}}</h2>
</header> </header>
<section id="skills"> <section id="skills">
{{range .Skills}} {{range .Skills}}
@ -119,7 +119,7 @@
{{if .Work}} {{if .Work}}
<section class="section"> <section class="section">
<header> <header>
<h2 class='section-title'>Work Experience <span class="item-count">({{len .Work}})</span></h2> <h2 class='section-title'>{{.Lang.WorkExperience}} <span class="item-count">({{len .Work}})</span></h2>
</header> </header>
<section id="work"> <section id="work">
{{range $index, $w := .Work}} {{range $index, $w := .Work}}
@ -135,15 +135,15 @@
{{if $w.Position}}<div class="position">{{$w.Position}}</div>{{end}} {{if $w.Position}}<div class="position">{{$w.Position}}</div>{{end}}
<div class="company">{{$w.Name}}</div> <div class="company">{{$w.Name}}</div>
<div class="date"> <div class="date">
<span class="startDate">{{formatDateWork $w.StartDate}}</span> <span class="startDate">{{formatDateMY $w.StartDate}}</span>
<span class="endDate">- {{formatDateWork $w.EndDate}}</span> <span class="endDate">- {{formatDateMY $w.EndDate}}</span>
</div> </div>
</header> </header>
{{- end}} {{- end}}
{{if $w.WorkLocation -}} {{if $w.Location -}}
<span class="location"> <span class="location">
<span class="fas fa-map-marker-alt"></span> <span class="fas fa-map-marker-alt"></span>
{{if $w.WorkLocation}}<span class="city">{{$w.WorkLocation}},</span>{{end}} {{if $w.Location}}<span class="city">{{$w.Location}},</span>{{end}}
</span> </span>
{{- end}} {{- end}}
{{if $w.URL}}<span class="website"> <a target="_blank" href="{{$w.URL}}">{{$w.URL}}</a></span>{{end}} {{if $w.URL}}<span class="website"> <a target="_blank" href="{{$w.URL}}">{{$w.URL}}</a></span>{{end}}
@ -175,7 +175,7 @@
{{if .Projects -}} {{if .Projects -}}
<section class="section"> <section class="section">
<header> <header>
<h2 class='section-title'>Projects <span class="item-count">({{len .Projects}})</span></h2> <h2 class='section-title'>{{.Lang.Projects}} <span class="item-count">({{len .Projects}})</span></h2>
</header> </header>
<section id="projects"> <section id="projects">
{{range $index, $p := .Projects}} {{range $index, $p := .Projects}}
@ -191,8 +191,8 @@
{{if $p.Name}}<div class="position">{{$p.Name}}</div>{{end}} {{if $p.Name}}<div class="position">{{$p.Name}}</div>{{end}}
{{if $p.StartDate -}} {{if $p.StartDate -}}
<div class="date"> <div class="date">
<span class="startDate">{{formatDateWork $p.StartDate}}</span> <span class="startDate">{{formatDateMY $p.StartDate}}</span>
<span class="endDate">- {{formatDateWork $p.EndDate}}</span> <span class="endDate">- {{formatDateMY $p.EndDate}}</span>
</div> </div>
{{- end}} {{- end}}
</header> </header>
@ -209,7 +209,17 @@
{{- end}} {{- end}}
<div class="item"> <div class="item">
{{if $p.Description}}<div class="summary"><p>{{$p.Description}}</p></div>{{end}} {{if $p.Description}}<div class="summary"><p>{{$p.Description}}</p></div>{{end}}
{{if $p.Highlights}}<ul class="highlights">{{range $p.Highlights}}<li>{{.}}</li>{{end}}</ul>{{end}} {{if $p.Highlights}}<ul class="highlights">
{{range $p.Highlights -}}
<li>{{.Title}}
{{if .Items -}}
<ul>
{{range .Items}}<li>{{.}}</li>{{end}}
</ul>
{{- end}}
</li>
{{- end}}
</ul>{{end}}
</div> </div>
</section> </section>
{{- end}} {{- end}}
@ -219,7 +229,7 @@
{{if .Volunteer -}} {{if .Volunteer -}}
<section class="section"> <section class="section">
<header> <header>
<h2 class='section-title'>Volunteer</h2> <h2 class='section-title'>{{.Lang.Volunteer}}</h2>
</header> </header>
<section id="volunteer"> <section id="volunteer">
{{range $index, $v := .Volunteer}} {{range $index, $v := .Volunteer}}
@ -237,8 +247,8 @@
<div class="organization">{{$v.Organization}}</div> <div class="organization">{{$v.Organization}}</div>
</div> </div>
<div class="date"> <div class="date">
<span class="startDate">{{formatDateWork $v.StartDate}}</span> <span class="startDate">{{formatDateMY $v.StartDate}}</span>
<span class="endDate"> - {{formatDateWork $v.EndDate}}</span> <span class="endDate"> - {{formatDateMY $v.EndDate}}</span>
</div> </div>
</header> </header>
{{- end}} {{- end}}
@ -255,7 +265,15 @@
{{if $v.Summary}}<div class="summary"><p>{{$v.Summary}}</p></div>{{end}} {{if $v.Summary}}<div class="summary"><p>{{$v.Summary}}</p></div>{{end}}
{{if $v.Highlights}} {{if $v.Highlights}}
<ul class="highlights"> <ul class="highlights">
{{range $v.Highlights}}<li>{{.}}</li>{{end}} {{range $v.Highlights -}}
<li>{{.Title}}
{{if .Items -}}
<ul>
{{range .Items}}<li>{{.}}</li>{{end}}
</ul>
{{- end}}
</li>
{{- end}}
</ul> </ul>
{{- end}} {{- end}}
</div> </div>
@ -267,7 +285,7 @@
{{if .Education -}} {{if .Education -}}
<section class="section"> <section class="section">
<header> <header>
<h2 class='section-title'>Education <span class="item-count">({{len .Education}})</span></h2> <h2 class='section-title'>{{.Lang.Education}} <span class="item-count">({{len .Education}})</span></h2>
</header> </header>
<section id="education"> <section id="education">
@ -286,8 +304,8 @@
{{if $e.Institution}} <div class="institution">{{$e.Institution}}</div>{{end}} {{if $e.Institution}} <div class="institution">{{$e.Institution}}</div>{{end}}
</div> </div>
<div class="date"> <div class="date">
{{if $e.StartDate}}<span class="startDate">{{formatDateEdu $e.StartDate}}</span>{{end}} {{if $e.StartDate}}<span class="startDate">{{formatDateY $e.StartDate}}</span>{{end}}
<span class="endDate"> - {{formatDateEdu $e.EndDate}} </span> <span class="endDate"> - {{formatDateY $e.EndDate}} </span>
</div> </div>
</header> </header>
{{if $e.Courses -}} {{if $e.Courses -}}
@ -310,7 +328,7 @@
{{if .Awards -}} {{if .Awards -}}
<section class="section"> <section class="section">
<header> <header>
<h2 class='section-title'>Awards</h2> <h2 class='section-title'>{{.Lang.Awards}}</h2>
</header> </header>
<section id="awards"> <section id="awards">
{{range $index, $a := .Awards}} {{range $index, $a := .Awards}}
@ -326,7 +344,7 @@
{{if $a.Title}}<div class="title">{{$a.Title}}</div>{{end}} {{if $a.Title}}<div class="title">{{$a.Title}}</div>{{end}}
{{if $a.Awarder}}<div class="awarder">{{$a.Awarder}}</div>{{end}} {{if $a.Awarder}}<div class="awarder">{{$a.Awarder}}</div>{{end}}
</div> </div>
{{if $a.Date}}<div class="date">{{formatDatePub $a.Date}}</div>{{end}} {{if $a.Date}}<div class="date">{{formatDateDMY $a.Date}}</div>{{end}}
</header> </header>
<div class="item"> <div class="item">
{{if $a.Summary}}<div class="summary"><p>{{$a.Summary}}</p></div>{{end}} {{if $a.Summary}}<div class="summary"><p>{{$a.Summary}}</p></div>{{end}}
@ -339,7 +357,7 @@
{{if .Publications -}} {{if .Publications -}}
<section class="section"> <section class="section">
<header> <header>
<h2 class='section-title'>Publications</h2> <h2 class='section-title'>{{.Lang.Publications}}</h2>
</header> </header>
<section id="publications"> <section id="publications">
{{range $index, $p := .Publications}} {{range $index, $p := .Publications}}
@ -366,7 +384,7 @@
{{- end}} {{- end}}
{{if $p.Publisher}}<span class="publisher"> in {{$p.Publisher}}</span>{{end}} {{if $p.Publisher}}<span class="publisher"> in {{$p.Publisher}}</span>{{end}}
</div> </div>
{{if $p.ReleaseDate}}<span class="date"> {{formatDatePub $p.ReleaseDate}} </span>{{end}} {{if $p.ReleaseDate}}<span class="date"> {{formatDateDMY $p.ReleaseDate}} </span>{{end}}
</header> </header>
<div class="item"> <div class="item">
@ -380,7 +398,7 @@
{{if .Languages -}} {{if .Languages -}}
<section class="section margin1"> <section class="section margin1">
<header> <header>
<h2 class='section-title'>Languages</h2> <h2 class='section-title'>{{.Lang.Languages}}</h2>
</header> </header>
<section id="languages"> <section id="languages">
{{range .Languages}} {{range .Languages}}
@ -402,7 +420,7 @@
{{if .Interests -}} {{if .Interests -}}
<section class="section margin1"> <section class="section margin1">
<header> <header>
<h2 class='section-title' class='section-title'>Interests</h2> <h2 class='section-title' class='section-title'>{{.Lang.Interests}}</h2>
</header> </header>
<section id="interests"> <section id="interests">
{{range .Interests}} {{range .Interests}}
@ -423,7 +441,7 @@
{{if .References -}} {{if .References -}}
<section class="section"> <section class="section">
<header> <header>
<h2 class='section-title'>References</h2> <h2 class='section-title'>{{.Lang.References}}</h2>
</header> </header>
<section id="references"> <section id="references">
{{range .References}} {{range .References}}

View File

@ -23,10 +23,9 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
package kendall package stackoverflow
import ( import (
"io/ioutil"
"jsonresume/themes" "jsonresume/themes"
"path" "path"
"strings" "strings"
@ -43,20 +42,18 @@ var Theme = themes.Theme{
Name: "stackoverflow", Name: "stackoverflow",
Directory: packageDirectory, Directory: packageDirectory,
Functions: template.FuncMap{ Functions: template.FuncMap{
"iconClass": themes.IconClass, "css": getCSS,
"formatDateWork": themes.FormatDateWork, "tolower": strings.ToLower,
"formatDateEdu": themes.FormatDateEdu,
"formatDatePub": themes.FormatDatePub,
"css": getCSS,
"tolower": strings.ToLower,
}, },
Template: fileTemplate,
} }
func init() { func init() {
t, _ := Asset(path.Join(packageDirectory, fileTemplate))
Theme.Template = string(t)
(&Theme).Register() (&Theme).Register()
} }
func getCSS() string { func getCSS() string {
r, _ := ioutil.ReadFile(path.Join(packageDirectory, fileCSS)) r, _ := Asset(path.Join(packageDirectory, fileCSS))
return string(r) return string(r)
} }

View File

@ -1,440 +0,0 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<title>CV de {{.Basic.Name}}</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.12/css/all.css" integrity="sha384-G0fIWCsCzJIMAVNQPfjH08cyYaUtMwjJwqiRKxxE/rx96Uroj1BtIQ6MLJuheaO9" crossorigin="anonymous">
<style>
{{css}}
</style>
</head>
<body>
<div id="resume">
<header id="header" class="clear">
{{if .Basic.Image -}}
<img class="picture" src="{{.Basic.Image}}" alt="{{.Basic.Name}}" />
<div class="middle">
<h1 class="name">{{.Basic.Name}}</h1>
<h2 class="label">{{.Basic.Label}}</h2>
</div>
{{else -}}
<div>
<h1 class="name">{{.Basic.Name}}</h1>
<h2 class="label">{{.Basic.Label}}</h2>
</div>
{{- end}}
{{if .Basic.ResumeLocation.City}}
<span class="location">
{{if .Basic.ResumeLocation.Address}}
<span class="address">{{.Basic.ResumeLocation.Address}},</span>
{{- end}}
{{if .Basic.ResumeLocation.PostalCode}}
<span class="postalCode">{{.Basic.ResumeLocation.PostalCode}},</span>
{{- end}}
{{if .Basic.ResumeLocation.City}}
<span class="city">{{.Basic.ResumeLocation.City}},</span>
{{- end}}
{{if .Basic.ResumeLocation.Region}}
<span class="region">{{.Basic.ResumeLocation.Region}}</span>
{{- end}}
{{if .Basic.ResumeLocation.CountryCode}}
<span class="countryCode">{{.Basic.ResumeLocation.CountryCode}}</span>
{{- end}}
</span>
{{- end}}
<div id="contact">
{{if .Basic.URL}}
<div class="website">
<span class="fas fa-external-link-alt"></span>
<a target="_blank" href="{{.Basic.URL}}">{{.Basic.URL}}</a>
</div>
{{- end}}
{{if .Basic.Email}}
<div class="email">
<span class="far fa-envelope"></span>
<a href="mailto:{{.Basic.Email}}">{{.Basic.Email}}</a>
</div>
{{- end}}
{{if .Basic.Phone}}
<div class="phone">
<span class="fas fa-mobile-alt"></span>
<a href="tel:{{.Basic.Phone}}">{{.Basic.Phone}}</a>
</div>
{{- end}}
</div>
{{if .Basic.Profiles}}
<div id="profiles">
{{range .Basic.Profiles}}
<div class="item">
{{if .Network}}
<div class="username">
<span class="fab fa-{{tolower .Network}} {{.Network}} social"></span>
{{if .URL}}
<span class="url">
<a target="_blank" href="{{.URL}}">{{.UserName}}</a>
</span>
{{else}}
<span>{{.UserName}}</span>
{{- end}}
</div>
{{- end}}
</div>
{{- end}}
</div>
{{- end}}
</header>
{{if .Basic.Summary}}
<section class="section main-summary">
<section>
<div>{{.Basic.Summary}}</div>
</section>
</section>
{{- end}}
{{if .Skills}}
<section class="section margin1">
<header>
<h2 class='section-title'>Compétences</h2>
</header>
<section id="skills">
{{range .Skills}}
<div class="item">
{{if .Name}}<h3 class="name">{{.Name}}</h3>{{end}}
{{if .Level}}<div class="level {{tolower .Level}}"><em>{{.Level}}</em><div class="bar"></div></div>{{end}}
{{if .Keywords -}}
<ul class="keywords">
{{range .Keywords}}<li>{{.}}</li>{{end}}
</ul>
{{- end}}
</div>
{{- end}}
</section>
</section>
{{- end}}
{{if .Work}}
<section class="section">
<header>
<h2 class='section-title'>Expérience Professionnelle <span class="item-count">({{len .Work}})</span></h2>
</header>
<section id="work">
{{range $index, $w := .Work}}
<section class="work-item">
{{if $w.Name -}}
{{if eq $index 0 -}}
<input id="work-item-{{$index}}" type="checkbox" class="toggle-item" checked="checked" />
{{else -}}
<input id="work-item-{{$index}}" type="checkbox" class="toggle-item" />
{{- end}}
<label for="work-item-{{$index}}"></label>
<header>
{{if $w.Position}}<div class="position">{{$w.Position}}</div>{{end}}
<div class="company">{{$w.Name}}</div>
<div class="date">
<span class="startDate">{{formatDateWork $w.StartDate}}</span>
<span class="endDate">- {{formatDateWork $w.EndDate}}</span>
</div>
</header>
{{- end}}
{{if $w.WorkLocation -}}
<span class="location">
<span class="fas fa-map-marker-alt"></span>
{{if $w.WorkLocation}}<span class="city">{{$w.WorkLocation}},</span>{{end}}
</span>
{{- end}}
{{if $w.URL}}<span class="website"> <a target="_blank" href="{{$w.URL}}">{{$w.URL}}</a></span>{{end}}
{{if $w.Keywords -}}
<ul class="keywords">
{{range $w.Keywords}}<li>{{.}}</li>{{end}}
</ul>
{{- end}}
<div class="item" id="work-item">
{{if $w.Summary}}<div class="summary"><p>{{$w.Summary}}</p></div>{{end}}
{{if $w.Highlights -}}
<ul class="highlights">
{{range $w.Highlights -}}
<li>{{.Title}}
{{if .Items -}}
<ul>
{{range .Items}}<li>{{.}}</li>{{end}}
</ul>
{{- end}}
</li>
{{- end}}
</ul>{{end}}
</div>
</section>
{{- end}}
</section>
</section>
{{- end}}
{{if .Projects -}}
<section class="section">
<header>
<h2 class='section-title'>Projets <span class="item-count">({{len .Projects}})</span></h2>
</header>
<section id="projects">
{{range $index, $p := .Projects}}
<section class="project-item">
{{if eq $index 0 -}}
<input id="project-item-{{$index}}" type="checkbox" class="toggle-item" checked="checked" />
{{else -}}
<input id="project-item-{{$index}}" type="checkbox" class="toggle-item" />
{{- end}}
<label for="project-item-{{$index}}"></label>
{{if $p.Name -}}
<header>
{{if $p.Name}}<div class="position">{{$p.Name}}</div>{{end}}
{{if $p.StartDate -}}
<div class="date">
<span class="startDate">{{formatDateWork $p.StartDate}}</span>
<span class="endDate">- {{formatDateWork $p.EndDate}}</span>
</div>
{{- end}}
</header>
{{- end}}
{{if $p.URL}}
<span class="website">
<a target="_blank" href="{{$p.URL}}">{{$p.URL}}</a>
</span>
{{- end}}
{{if $p.Keywords -}}
<ul class="keywords">
{{range $p.Keywords}}<li>{{.}}</li>{{end}}
</ul>
{{- end}}
<div class="item">
{{if $p.Description}}<div class="summary"><p>{{$p.Description}}</p></div>{{end}}
{{if $p.Highlights}}<ul class="highlights">{{range $p.Highlights}}<li>{{.}}</li>{{end}}</ul>{{end}}
</div>
</section>
{{- end}}
</section>
</section>
{{- end}}
{{if .Volunteer -}}
<section class="section">
<header>
<h2 class='section-title'>Bénévolat</h2>
</header>
<section id="volunteer">
{{range $index, $v := .Volunteer}}
<section class="volunteer-item">
{{if $v.Organization -}}
{{if eq $index 0 -}}
<input id="volunteer-item-{{$index}}" type="checkbox" class="toggle-item" checked="checked" />
{{else -}}
<input id="volunteer-item-{{$index}}" type="checkbox" class="toggle-item" />
{{- end}}
<label for="volunteer-item-{{$index}}"></label>
<header>
<div class="header-left">
{{if $v.Position}}<div class="position">{{$v.Position}}</div>{{end}}
<div class="organization">{{$v.Organization}}</div>
</div>
<div class="date">
<span class="startDate">{{formatDateWork $v.StartDate}}</span>
<span class="endDate"> - {{formatDateWork $v.EndDate}}</span>
</div>
</header>
{{- end}}
{{if $v.URL -}}
<div class="website">
<a target="_blank" href="{{$v.URL}}">{{$v.URL}}</a>
</div>
{{- end}}
{{if $v.Keywords}}<ul class="keywords">
{{range $v.Keywords}}<li>{{.}}</li>{{end}}
</ul>{{end}}
<div class="item">
<div class="summary"><p></p></div>
{{if $v.Summary}}<div class="summary"><p>{{$v.Summary}}</p></div>{{end}}
{{if $v.Highlights}}
<ul class="highlights">
{{range $v.Highlights}}<li>{{.}}</li>{{end}}
</ul>
{{- end}}
</div>
</section>
{{- end}}
</section>
</section>
{{- end}}
{{if .Education -}}
<section class="section">
<header>
<h2 class='section-title'>Formation <span class="item-count">({{len .Education}})</span></h2>
</header>
<section id="education">
{{range $index, $e := .Education}}
<section class="education-item">
{{if eq $index 0 -}}
<input id="education-item-{{$index}}" type="checkbox" class="toggle-item" checked="checked" />
{{else -}}
<input id="education-item-{{$index}}" type="checkbox" class="toggle-item" />
{{- end}}
<label for="education-item-{{$index}}"></label>
<header class="clear">
<div class="header-left">
{{if $e.StudyType}}<div class="studyType">{{$e.StudyType}}</div>{{end}}
{{if $e.Area}}<div class="area">{{$e.Area}}</div>{{end}}
{{if $e.Institution}} <div class="institution">{{$e.Institution}}</div>{{end}}
</div>
<div class="date">
{{if $e.StartDate}}<span class="startDate">{{formatDateEdu $e.StartDate}}</span>{{end}}
<span class="endDate"> - {{formatDateEdu $e.EndDate}} </span>
</div>
</header>
{{if $e.Courses -}}
<ul class="courses">
{{range $e.Courses}}<li>{{.}}</li>{{end}}
</ul>
{{- end}}
<div class="item">
{{if $e.GPA -}}
<div class='gpa'>
<strong> Grade:</strong> <span>{{$e.GPA}}</span>
</div>
{{- end}}
</div>
</section>
{{- end}}
</section>
</section>
{{- end}}
{{if .Awards -}}
<section class="section">
<header>
<h2 class='section-title'>Récompenses</h2>
</header>
<section id="awards">
{{range $index, $a := .Awards}}
<section class="award-item">
{{if eq $index 0 -}}
<input id="award-item-{{$index}}" type="checkbox" class="toggle-item" checked="checked" />
{{else -}}
<input id="award-item-{{$index}}" type="checkbox" class="toggle-item" />
{{- end}}
<label for="award-item-{{$index}}"></label>
<header>
<div class="header-left">
{{if $a.Title}}<div class="title">{{$a.Title}}</div>{{end}}
{{if $a.Awarder}}<div class="awarder">{{$a.Awarder}}</div>{{end}}
</div>
{{if $a.Date}}<div class="date">{{formatDatePub $a.Date}}</div>{{end}}
</header>
<div class="item">
{{if $a.Summary}}<div class="summary"><p>{{$a.Summary}}</p></div>{{end}}
</div>
</section>
{{- end}}
</section>
</section>
{{- end}}
{{if .Publications -}}
<section class="section">
<header>
<h2 class='section-title'>Publications</h2>
</header>
<section id="publications">
{{range $index, $p := .Publications}}
<section class="publication-item">
{{if eq $index 0 -}}
<input id="publication-item-{{$index}}" type="checkbox" class="toggle-item" checked="checked" />
{{else -}}
<input id="publication-item-{{$index}}" type="checkbox" class="toggle-item" />
{{- end}}
<label for="publication-item-{{$index}}"></label>
<header>
<div class="header-left">
{{if $p.Name -}}
<span class="name">
{{if $p.URL -}}
<span class="website">
<a target="_blank" href="{{$p.URL}}">{{$p.Name}}</a>
</span>
{{else -}}
{{$p.Name}}
{{- end}}
</span>
{{- end}}
{{if $p.Publisher}}<span class="publisher"> in {{$p.Publisher}}</span>{{end}}
</div>
{{if $p.ReleaseDate}}<span class="date"> {{formatDatePub $p.ReleaseDate}} </span>{{end}}
</header>
<div class="item">
{{if $p.Summary}}<div class="summary"><p>{{$p.Summary}}</p></div>{{end}}
</div>
</section>
{{- end}}
</section>
</section>
{{- end}}
{{if .Languages -}}
<section class="section margin1">
<header>
<h2 class='section-title'>Langues</h2>
</header>
<section id="languages">
{{range .Languages}}
<div class="display">
{{if .Language}}<h3 class="language">{{.Language}}</h3>{{end}}
<div class="item">
{{if .Fluency -}}
<div class="level fluency {{tolower .Fluency}}">
<em>{{.Fluency}}</em>
<div class="bar"></div>
</div>
{{- end}}
</div>
</div>
{{- end}}
</section>
</section>
{{- end}}
{{if .Interests -}}
<section class="section margin1">
<header>
<h2 class='section-title' class='section-title'>Intérêts</h2>
</header>
<section id="interests">
{{range .Interests}}
<div class="item">
{{if .Name}}<h3 class="name">{{.Name}}</h3>{{end}}
{{if .Keywords -}}
<ul class="keywords">
{{range .Keywords}}
<li>{{.}}</li>
{{- end}}
</ul>
{{- end}}
</div>
{{- end}}
</section>
</section>
{{- end}}
{{if .References -}}
<section class="section">
<header>
<h2 class='section-title'>Références</h2>
</header>
<section id="references">
{{range .References}}
<div class="item">
{{if .Reference}}<blockquote class="reference"> &#8220;&#32;{{.Reference}}&#32;&#8221; </blockquote>{{end}}
{{if .Name}}<div class="name"> {{.Name}} </div>{{end}}
</div>
{{- end}}
</section>
</section>
{{- end}}
</div>
</body>
</html>

View File

@ -1,63 +0,0 @@
/*
* Copyright (c) 2018 Arnaud Ysmal. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
package kendall
import (
"io/ioutil"
"jsonresume/themes"
"path"
"strings"
"text/template"
)
const (
packageDirectory = "themes/stackoverflowfr"
fileCSS = "style.css"
fileTemplate = "resume.template"
)
var Theme = themes.Theme{
Name: "stackoverflowfr",
Directory: packageDirectory,
Functions: template.FuncMap{
"iconClass": themes.IconClass,
"formatDateWork": themes.FormatDateWorkFR,
"formatDateEdu": themes.FormatDateEduFR,
"formatDatePub": themes.FormatDatePubFR,
"css": getCSS,
"tolower": strings.ToLower,
},
Template: fileTemplate,
}
func init() {
(&Theme).Register()
}
func getCSS() string {
r, _ := ioutil.ReadFile(path.Join(packageDirectory, fileCSS))
return string(r)
}

View File

@ -1,771 +0,0 @@
/********************************************
* reset from
* http://meyerweb.com/eric/tools/css/reset/
*******************************************/
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
vertical-align: baseline;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}
ol,
ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/****************
* COMMONS
****************/
body,
html {
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
font-size: 13px;
color: #40484f;
font-weight: 400;
letter-spacing: 0;
line-height: 1.46153846;
text-align: left;
-webkit-text-size-adjust: 100%;
}
p {
display: block;
margin-bottom: 1.3em;
}
a {
color: #0095ff;
text-decoration: none;
}
a:hover {
color: #0c65a5;
text-decoration: underline;
}
ul {
margin-top: 1rem;
}
li {
list-style-type: square;
list-style-position: outside;
margin-left: 1.3em;
}
.highlights>li>p {
margin-bottom: 0.5em;
}
h1 {
font-size: 2rem;
}
h2 {
font-size: 1.67rem;
}
h3 {
font-size: 1.27rem;
}
em {
color: #757575;
}
blockquote {
margin-bottom: 1em;
}
strong {
font-weight: 700;
}
/* main container */
#resume {
padding: 1rem;
margin-top: 2rem;
}
/* every section wrapper */
.section {
margin-bottom: 1rem;
}
section .location {
margin-right: .5em;
color: #606d76;
font-weight: 700;
}
#contact {
margin-top: .5rem;
}
#profiles .item {
padding: 0;
}
#header>#profiles,
#header>#contact,
#skills,
#languages,
#interests {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
-webkit-justify-content: flex-start;
justify-content: flex-start;
}
#header>div {
line-height: 1.5;
}
#header>div>div {
margin-right: 1.2em;
}
#header h1.name {
font-size: 2.8rem;
font-weight: 100;
line-height: 100%;
}
#header h2.label {
color: #202931;
font-size: 1.47rem;
font-weight: 300;
}
#header .picture {
width: 11em;
float: right;
border-radius: 4px;
}
.main-summary {
background: #f1f8ff;
padding: 1.2em 1em;
margin-top: 1rem;
}
.main-summary p {
margin: .15em 0 0;
}
h2.section-title {
display: inline-block;
background: #fff;
padding: 0 1em 0.3em 0;
color: #ff6d1f;
text-transform: uppercase;
font-weight: 600;
border: none;
font-size: .9rem;
}
.section>header {
position: relative;
}
.fa {
margin-right: 0.25em;
}
.section>header::after {
position: absolute;
left: 0;
top: .7em;
height: 1px;
background: #ccc;
content: "";
width: 100%;
z-index: -100;
display: block;
}
.section.main-summary>section {
margin: 0;
}
.section>section>header {
font-size: 1.38rem;
position: relative;
margin-top: .7em;
}
.section>section>header:first-of-type {
margin: 0;
}
.section>section>header .space-left {
position: absolute;
left: -1.56rem;
top: 5px;
color: #aaa;
line-height: 1;
opacity: 0;
}
.position,
.company,
.organization,
.institution,
.date,
.area,
.studyType,
.title,
.awarder {
display: inline;
}
.position,
.studyType,
.area,
.title,
.language,
.name {
font-weight: 600;
}
.company::before,
.institution::before,
.organization::before,
.awarder::before {
content: "at "
}
.company,
.institution,
.organization,
.awarder {
color: #606d76;
font-weight: 400;
}
.section header .date {
font-size: 1rem;
display: inline-table;
padding: .1em 0;
font-weight: 600;
}
ul.keywords,
ul.courses {
margin-top: .5em;
}
ul.keywords li,
ul.courses li {
display: inline-block;
margin: 2px 2px 2px 0;
padding: 4px 5px 5px;
font-size: .9rem;
line-height: 1;
text-transform: lowercase;
color: #3e6d8e;
background-color: #dfeaf1;
border: 0 solid #dfeaf1;
white-space: nowrap;
}
ul.keywords li:hover,
ul.courses li:hover {
background: #dfeaf0;
}
.item {
padding: .5em 0;
}
.gpa {
padding-bottom: .5em;
}
.fa.social {
font-size: 1.1em;
}
/* Social Media Brand Colors */
.google-plus {
color: #dd4b39;
}
.tumblr {
color: #32506d;
}
.foursquare {
color: #0072b1;
}
.facebook {
color: #3b5998;
}
.linkedin {
color: #007bb6;
}
.pinterest {
color: #cb2027;
}
.dribbble {
color: #ea4c89;
}
.instagram {
color: #517fa4;
}
.twitter {
color: #00aced;
}
.soundcloud {
color: #ff3a00;
}
.wordpress {
color: #21759b;
}
.youtube {
color: #bb0000;
}
.github {
color: #171515;
}
.stack-overflow {
color: #828386;
position: relative;
}
.flickr {
color: #ff0084;
}
.reddit {
color: #ff4500;
}
.hacker-news {
color: #ff6600;
}
.stack-overflow::after {
position: absolute;
left: 0;
content: '\f16c';
color: #f68a1f;
overflow: hidden;
height: 100%;
}
.telegram {
color: #2291c3;
}
#languages .item,
#skills .item,
#interests .item {
width: 15em;
padding: 0 .5em .5em 0;
border-bottom: none;
}
#skills .item {
width: 16em;
}
#skills .item .keywords {
width: 15em;
}
/* Skill chart */
.level {
margin-bottom: .5em;
}
.level .bar {
border: 1px solid #ddd;
display: block;
width: 10em;
height: 5px;
position: relative;
}
.level .bar::after {
position: absolute;
content: " ";
top: 0;
left: 0;
background: black;
height: 5px;
}
.level.beginner .bar::after {
background: #EB5F51;
width: 2.5em;
}
.level.intermediate .bar::after {
background: #ffdf1f;
width: 5em;
}
.level.advanced .bar::after,
.level.fluent .bar::after {
background: #5CB85C;
width: 7.5em;
}
.level.master .bar::after,
.level.native.speaker .bar::after {
background: #59C596;
width: 10em;
}
#references .item {
padding-left: .5em;
border-left: 5px solid #ff6d1f;
}
.toggle-item {
visibility: hidden;
}
/******************
* HELPER CLASSES
******************/
.clear::after {
content: "";
display: table;
clear: both;
}
.display {
display: block;
opacity: 1 !important;
}
.margin1 {
margin-bottom: .5rem;
}
/****************
* TABLET
****************/
@media screen and (min-width: 602px) {
#resume {
width: 80%;
margin: 0 auto;
}
}
/****************
* LAPTOP
****************/
@media screen and (min-width: 1025px) {
li {
margin-left: 1.5em;
}
#resume {
width: 820px;
margin: 2rem auto;
}
.section>section>header .space-left {
opacity: 1;
cursor: pointer;
}
.section>section {
margin-left: 1.67rem;
}
.toggle-item {
transform: translate(-9999px);
}
.toggle-item+label {
display: block;
}
.toggle-item:checked+label:after {
content: "\f0d7";
}
.toggle-item+label:after {
float: left;
cursor: pointer;
margin-left: -20px;
color: #aaa;
font-size: 16px;
font-weight: 900;
font-family: "Font Awesome 5 Free";
content: "\f0da";
}
.toggle-item~.item {
height: 0;
opacity: 0;
}
.toggle-item:checked~.item {
height: auto;
opacity: 1;
transition: all .5s linear;
}
.company::before,
.institution::before,
.organization::before,
.awarder::before {
content: "| ";
}
.header-left {
float: left;
width: 70%;
word-break: normal;
}
.section header .date {
float: right;
padding: .2em;
}
.display {
display: none;
}
.display:not(.none) {
display: block;
}
}
@media print {
#resume {
margin: 0;
padding: 0;
-ms-word-wrap: break-word;
word-wrap: break-word;
line-height: 1.3;
/*font-family: Arial, Georgia, "Lucida Grande", sans-serif;*/
}
@page {
margin: 1cm 1.4cm;
}
.item-count {
display: none;
}
.company::before,
.institution::before,
.organization::before,
.awarder::before {
content: "at ";
}
.main-summary {
padding: 2rem 0;
}
.section {
margin: .8rem 0;
padding: 0;
}
.section header {
padding-bottom: .15rem;
}
.section .location {
padding-bottom: .15rem;
}
.stack-overflow::after {
content: "";
}
.fa.social {
color: #828386;
}
ul {
margin-top: .4em;
}
ul,
li {
padding: 0;
}
ul.keywords li,
ul.courses li {
margin: 0;
padding: 0;
font-size: .8rem;
text-transform: lowercase;
}
ul.keywords li::after,
ul.courses li::after {
padding: 0 0 0 .1rem;
content: " |";
}
ul.keywords::before,
ul.courses::before {
font-size: .8rem;
font-weight: 600;
}
ul.keywords::before {
content: "Skills acquired: ";
}
#skills .keywords::before {
content: '';
}
.section p {
margin: 0;
padding: 0;
}
ul.courses::before {
content: "Major courses: ";
}
ul.keywords li:last-of-type::after,
ul.courses li:last-of-type::after {
content: "";
}
.level em {
font-style: normal;
padding: .1em 0;
}
.level .bar {
display: none;
}
#profiles .item {
padding: 0;
}
.item.display {
display: block;
opacity: 1 !important;
}
}

View File

@ -29,11 +29,27 @@ import (
"fmt" "fmt"
"io" "io"
"jsonresume/model" "jsonresume/model"
"path"
"strings" "strings"
"text/template" "text/template"
"time"
) )
type LangString struct {
TitlePrefix string
About string
Contact string
WorkExperience string
Awards string
Volunteer string
Education string
Skills string
Publications string
Languages string
Interests string
References string
Projects string
}
type Theme struct { type Theme struct {
Name string Name string
Directory string Directory string
@ -42,14 +58,53 @@ type Theme struct {
} }
var Themes map[string]*Theme var Themes map[string]*Theme
var Langs = map[string]LangString{
"en": LangString{
TitlePrefix: "Resume of",
About: "About",
Contact: "Contact",
WorkExperience: "Work Experience",
Awards: "Awards",
Volunteer: "Volunteer",
Education: "Education",
Skills: "Skills",
Publications: "Publications",
Languages: "Languages",
Interests: "Interests",
References: "References",
Projects: "Projects",
},
}
var CommonFuncs = map[string]template.FuncMap{
"en": template.FuncMap{
"iconClass": iconClass,
"formatDateY": formatDateY,
"formatDateMY": formatDateMY,
"formatDateDMY": formatDateDMY,
},
}
func init() { func init() {
Themes = make(map[string]*Theme) Themes = make(map[string]*Theme)
setupFrenchTranslation()
}
type TemplateData struct {
*model.Resume
Lang LangString
} }
func (t *Theme) Render(r *model.Resume, w io.Writer) error { func (t *Theme) Render(r *model.Resume, w io.Writer) error {
tmpl := template.Must(template.New(t.Template).Funcs(t.Functions).ParseFiles(path.Join(t.Directory, t.Template))) if r.Language == "" {
return tmpl.Execute(w, r) r.Language = "en"
}
l, exists := Langs[r.Language]
if !exists {
return fmt.Errorf("Unsupported language %s", r.Language)
}
f, _ := CommonFuncs[r.Language]
tmpl := template.Must(template.New(t.Name).Funcs(f).Funcs(t.Functions).Parse(t.Template))
return tmpl.Execute(w, &TemplateData{r, l})
} }
func (t *Theme) Register() error { func (t *Theme) Register() error {
@ -60,8 +115,7 @@ func (t *Theme) Register() error {
return nil return nil
} }
// Common functions func iconClass(network string) string {
func IconClass(network string) string {
network = strings.ToLower(network) network = strings.ToLower(network)
switch network { switch network {
case "google-plus": case "google-plus":
@ -99,23 +153,98 @@ func IconClass(network string) string {
return "fa fa-" + network return "fa fa-" + network
} }
func FormatDateWork(date model.ResumeDate) string { func formatDateY(date model.ResumeDate) string {
if date.IsZero() {
return "Present"
}
return fmt.Sprintf("%s %d", date.Month().String(), date.Year())
}
func FormatDateEdu(date model.ResumeDate) string {
if date.IsZero() { if date.IsZero() {
return "Present" return "Present"
} }
return fmt.Sprintf("%d", date.Year()) return fmt.Sprintf("%d", date.Year())
} }
func FormatDatePub(date model.ResumeDate) string { func formatDateMY(date model.ResumeDate) string {
if date.IsZero() {
return "Present"
}
return fmt.Sprintf("%s %d", date.Month().String(), date.Year())
}
func formatDateDMY(date model.ResumeDate) string {
if date.IsZero() { if date.IsZero() {
return "Present" return "Present"
} }
return fmt.Sprintf("%d %s %d", date.Day(), date.Month().String(), date.Year()) return fmt.Sprintf("%d %s %d", date.Day(), date.Month().String(), date.Year())
} }
func setupFrenchTranslation() {
Langs["fr"] = LangString{
TitlePrefix: "CV de",
About: "À propos",
Contact: "Contact",
WorkExperience: "Expérience Professionnelle",
Awards: "Récompenses",
Volunteer: "Bénévolat",
Education: "Formation",
Skills: "Compétences",
Publications: "Publications",
Languages: "Langues",
Interests: "Intérêts",
References: "Références",
Projects: "Projets",
}
CommonFuncs["fr"] = template.FuncMap{
"iconClass": iconClass,
"formatDateY": formatDateYFR,
"formatDateMY": formatDateMYFR,
"formatDateDMY": formatDateDMYFR,
}
}
func getMonthFR(date model.ResumeDate) string {
switch date.Month() {
case time.January:
return "Janvier"
case time.February:
return "Février"
case time.March:
return "Mars"
case time.April:
return "Avril"
case time.May:
return "Mai"
case time.June:
return "Juin"
case time.July:
return "Juillet"
case time.August:
return "Août"
case time.September:
return "Septembre"
case time.October:
return "Octobre"
case time.November:
return "Novembre"
case time.December:
return "Décembre"
}
return ""
}
func formatDateYFR(date model.ResumeDate) string {
if date.IsZero() {
return "Présent"
}
return fmt.Sprintf("%d", date.Year())
}
func formatDateMYFR(date model.ResumeDate) string {
if date.IsZero() {
return "Présent"
}
return fmt.Sprintf("%s %d", getMonthFR(date), date.Year())
}
func formatDateDMYFR(date model.ResumeDate) string {
if date.IsZero() {
return "Présent"
}
return fmt.Sprintf("%d %s %d", date.Day(), getMonthFR(date), date.Year())
}

View File

@ -1,82 +0,0 @@
/*
* Copyright (c) 2018 Arnaud Ysmal. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
package themes
import (
"fmt"
"jsonresume/model"
)
func getMonthFR(date model.ResumeDate) string {
switch date.Month() {
case 1:
return "Janvier"
case 2:
return "Février"
case 3:
return "Mars"
case 4:
return "Avril"
case 5:
return "Mai"
case 6:
return "Juin"
case 7:
return "Juillet"
case 8:
return "Août"
case 9:
return "Septembre"
case 10:
return "Octobre"
case 11:
return "Novembre"
case 12:
return "Décembre"
}
return ""
}
func FormatDateWorkFR(date model.ResumeDate) string {
if date.IsZero() {
return "Présent"
}
return fmt.Sprintf("%s %d", getMonthFR(date), date.Year())
}
func FormatDateEduFR(date model.ResumeDate) string {
if date.IsZero() {
return "Présent"
}
return fmt.Sprintf("%d", date.Year())
}
func FormatDatePubFR(date model.ResumeDate) string {
if date.IsZero() {
return "Présent"
}
return fmt.Sprintf("%d %s %d", date.Day(), getMonthFR(date), date.Year())
}