content/pages/writing/curriculum-vitae.11ty.js

/**
* @file Defines the layout for my curriculum vitae
* @author Reuben L. Lillie <reubenlillie@gmail.com>
* @since 1.0.0
*/


/**
* Acts as front matter data in JavaScript templates
* @see {@link https://www.11ty.dev/docs/languages/javascript/#optional-data-method Optional `data` method in JavaScript templates in Eleventy}
*/

export var data = {
date: 'Last Modified',
layout: 'layouts/content',
shortTitle: 'CV',
showDate: true,
tags: 'writing',
title: 'Curriculum Vitae',
useContentTitle: false,
weight: 4
}

/**
* Trim a four-digit year to two digits
* @param {number|string} year Four-digit year
* @return {string} The year’s last two digits
*/

function trimYear(year) {
var trimmed = year.toString().substr(2)
return `'${trimmed}`
}

/**
* Defines markup for a degree program listing
* @param {Object} degree Data for an educational degree program
* @return {string} HTML
*/

function degreeCard({
start,
end,
institution: {name: school, address: {city, state}, website},
degree: {abbr: degree, name: title, major, concentration},
}
) {
var startISO = start.toISOString()
var endISO = end ? end.toISOString() : null
return `<!-- degreeCard() -->
<article>
<p class="flex">
<span class="min-width">
<time datetime="
${end ? endISO: startISO}">${end
? end.getFullYear()
: `${start.getFullYear()}`}
</time>
</span>
<span>
<span>
<abbr title="
${title}">${degree}</abbr>, <a href="${website}">${school}</a>, ${city}, ${state.abbr}
</span><br>
<span>
${major}${concentration ? `, ${concentration}` : ''}</span>
</span>
</p>
</article>
`

}

/**
* Defines markup for a degree program listing
* @param {Object} degree Data for an educational degree program
* @return {string} HTML
*/

function roleCard({
role,
start,
end,
institution: {name: school, departments},
}
) {
var startISO = start.toISOString()
var endISO = end ? end.toISOString() : null
return `<!-- roleCard() -->
<article>
<div class="flex">
<span class="min-width">
<time datetime="
${end ? endISO: startISO}">${end
? end.getFullYear()
: `${start.getFullYear()}`}
</time>
</span>
<div>
<span>
${role}, ${school}</span>
<ul class="no-margin-block">
${departments.map(({name, coursework}) => `<!--table-->
<li>
${name}: ${coursework}</li>`

).join('\n')}

<tbody>
</ul>
</div>
<div>
</article>
`

}

/**
* Defines markup for an award or honor
* @param {Object} degree Data for an educational degree program
* @return {string} HTML
*/

function awardCard({
name: award,
organization: {name: org, website},
years
}
) {
years = Array.isArray(years)
? years.map((year, index) => index === 0 ? year : trimYear(year)).join(', ')
: `${years.start ? years.start : ''}${years.end ? trimYear(years.end) : ''}`
return `<!--awardCard()-->
<article>
<p class="flex">
<span class="min-width">
${years}</span>
<span>
${award}, ${website ? `<a href="${website}">${org}</a>` : org}</span>
</p>
</article>
`

}

/**
* List language proficiency
* @param {Object[]} Language data
* @return {string} HTML
*/

function listLang({name, proficiency}) {
return `<!--listLang()-->
<span>
${name}${proficiency ? `, ${proficiency}`: ''}</span>`

}

/**
* Defines markup for my curriculum vitae
* @return {string} HTML
* @see {@link https://www.11ty.dev/docs/quicktips/not-found/ 404 pages in Eleventy}
*/

export function render({
appointments,
author: {
name,
contact: {
address: {street, city, state, zip},
email,
phone,
social,
orcid_id,
website
},
},
awards,
degrees,
fellowships,
languages: {ancient, modern, programming, singing},
papers,
presentations,
publications,
research,
societies,
title,
}
) {
publications = this.sortBy(publications, 'date', true)
presentations = presentations.filter(item => item.cv !== false)
presentations = this.sortBy([...papers, ...presentations], 'date', true)

/**
* Defines a row for the languages table
* @param {string} arr Key for an array of language objects
* @param {string} heading The text content for the row’s `<th>`
* @param {string} separator Placed between array items
* @return {string} HTML
*/

function tableRow(arr, heading, separator = '') {
return arr
? `<!--tableRow()-->
<tr>
<th scope="row">
${heading}</th>
<td>
${arr.map(item => listLang(item)).join(separator)}
</td>
</tr>
`

: '<!--no arr passed to tableRow()-->'
}

return `<!--content/pages/curriculum-vitae.11ty.js-->
<section class="text-center">
<p id="title">
${title}</p>
<h1>
${name.fullName}</h1>
<address>
${street}<br>
${city}, ${state} ${zip}<br>
${email ? `<a href="mailto:${email}?subject=${title}">${email}</a><br>` : ''}
${phone ? `<a href="tel:${phone.tel}">${phone.formatted}</a><br>` : ''}
${orcid_id ? `<a href="https://orcid.org/${orcid_id}">ORCID iD: ${orcid_id}</a><br>` : ''}
${website ? `<a href="${website}">${website.split('/')[2]}</a><br>` : ''}
<ul class="flex space-between no-padding-inline-start no-list-style">
${social.filter(account => account.cv)
.map(account => this.socialLink(account))
.join('&amp;nbsp;')}

</ul>
</address>
</section>
<section id="education">
<h2>Education</h2>
${degrees.reverse().map(program => degreeCard(program)).join('\n')}
</section>
<section id="appointments">
<h2>Academic Appointments</h2>
${appointments.map(appointment => roleCard(appointment)).join('\n')}
</section>
<section id="fellowships">
<h2>Fellowships and Apprenticeships</h2>
${fellowships.reverse().map(fellowship => awardCard(fellowship)).join('\n')}
</section>
<section id="awards">
<h2>Honors and Awards</h2>
${awards.reverse().map(award => awardCard(award)).join('\n')}
</section>
<section id="research">
<h2>Current Research</h2>
${research.map(item => this.authorDateReference(item)).join('\n')}
</section>
<section id="publications">
<h2>Publications</h2>
${publications.map(item => this.authorDateReference(item)).join('\n')}
</section>
<section id="papers">
<h2>Papers and Presentations</h2>
${presentations.map(item => this.authorDateReference(item)).join('\n')}
</section>
<section id="languages">
<table>
<caption>Languages</caption>
${tableRow(ancient, 'Ancient', '; ')}
${tableRow(modern, 'Modern', '; ')}
${tableRow(programming, 'Programming', '; ')}
${tableRow(singing, 'Additional Singing Experience', ', ')}
</table>
</section>
<section>
<h2>Professional Associations</h2>
<ul>
${societies.map(society => `<li>${society.website
? `<a href="${society.website}">${society.name}</a>`
: society.name}
</li>`
).join('\n')}

</ul>
</section>
`

}