get most site metadata from the resume

This commit is contained in:
Matthias Kretschmann 2019-11-19 22:49:17 +01:00
parent b46b006dd7
commit e84de746c7
Signed by: m
GPG Key ID: 606EEEF3C479A91F
7 changed files with 53 additions and 52 deletions

View File

@ -16,9 +16,9 @@
- [🎉 Features](#-features)
- [⛵️ Lighthouse score](#-lighthouse-score)
- [🗂 JSON Resume](#-json-resume)
- [💍 One data file to rule all pages](#-one-data-file-to-rule-all-pages)
- [🐱 GitHub repositories](#-github-repositories)
- 🗂 JSON Resume](#-json-resume)
- [💅 Theme switcher](#-theme-switcher)
- [🏆 SEO component](#-seo-component)
- [📇 Client-side vCard creation](#-client-side-vcard-creation)
@ -38,37 +38,17 @@
## 🎉 Features
The whole [portfolio](https://matthiaskretschmann.com) is a React-based Single Page App built with [Gatsby v2](https://www.gatsbyjs.org).
The whole [portfolio](https://matthiaskretschmann.com) is a React-based single page app built with [Gatsby v2](https://www.gatsbyjs.org).
Most metadata is powered by one `resume.json` file based on [🗂 JSON Resume](#-json-resume), and one `projects.yml` file to [define the displayed projects](#-one-data-file-to-rule-all-pages).
### ⛵️ Lighthouse score
![Lighthouse scores](https://lighthouse.now.sh/?perf=100&pwa=100&a11y=100&bp=100&seo=100)
### 💍 One data file to rule all pages
All content is powered by one YAML file where all the portfolio's projects are defined. The project description itself is transformed from Markdown written inside the YAML file into HTML on build time.
Gatsby automatically creates pages from each item in that file utilizing the [`Project.jsx`](src/templates/Project.jsx) template.
- [`gatsby-node.js`](gatsby-node.js)
- [`content/projects.yml`](content/projects.yml)
- [`src/templates/Project.jsx`](src/templates/Project.jsx)
### 🐱 GitHub repositories
The open source section at the bottom of the front page shows selected GitHub repositories, sourced from GitHub.
On build time, all my public repositories are fetched from GitHub, then filtered against the ones defined in `content/repos.yml`, sorted by the last push date, and provided via the page context of the front page.
If you want to know how, have a look at the respective components:
- [`gatsby-node.js`](gatsby-node.js)
- [`content/repos.yml`](content/repos.yml)
- [`src/components/molecules/Repository.jsx`](src/components/molecules/Repository.jsx)
### 🗂 JSON Resume
Resume page based on [JSON Resume](https://jsonresume.org) standard. Most site metadata and social profiles are defined in [`content/resume.json`](content/resume.json) and used throughout the site.
Most site metadata and social profiles are defined in [`content/resume.json`](content/resume.json) based on the [JSON Resume](https://jsonresume.org) standard and used throughout the site as a custom React hook. Additionally, a resume page is created under `/resume`.
If you want to know how, have a look at the respective components:
@ -76,6 +56,28 @@ If you want to know how, have a look at the respective components:
- [`src/pages/resume/index.jsx`](src/pages/resume/index.jsx)
- [`src/hooks/use-resume.js`](src/hooks/use-resume.js)
### 💍 One data file to rule all pages
All displayed project content is powered by one YAML file where all the portfolio's projects are defined. The project description itself is transformed from Markdown written inside the YAML file into HTML on build time.
Gatsby automatically creates pages from each item in that file utilizing the [`Project.jsx`](src/templates/Project.jsx) template.
- [`content/projects.yml`](content/projects.yml)
- [`gatsby-node.js`](gatsby-node.js)
- [`src/templates/Project.jsx`](src/templates/Project.jsx)
### 🐱 GitHub repositories
The open source section at the bottom of the front page shows selected GitHub repositories, sourced from GitHub.
On build time, all my public repositories are fetched from GitHub, then filtered against the ones defined in `content/repos.yml`, sorted by the last push date, and provided via the `pageContext` of the front page.
If you want to know how, have a look at the respective components:
- [`gatsby-node.js`](gatsby-node.js)
- [`content/repos.yml`](content/repos.yml)
- [`src/components/molecules/Repository.jsx`](src/components/molecules/Repository.jsx)
### 💅 Theme switcher
Includes a theme switcher which allows user to toggle between a light and a dark theme. Switching between them also happens automatically based on user's local sunset and sunrise times. Uses Cloudflare's geo location HTTP header functionality.

View File

@ -1,9 +1,6 @@
# more personal metadata can be found in ./resume.json
# most personal metadata can be found in ./resume.json
- title: Matthias Kretschmann
tagline: Designer & Developer
description: Portfolio of web & ui designer/developer hybrid Matthias Kretschmann.
url: https://matthiaskretschmann.com
- description: Portfolio of web & ui designer/developer hybrid Matthias Kretschmann.
img: ../src/images/twitter-card.png
availability:

View File

@ -2,13 +2,15 @@ const path = require('path')
const fs = require('fs')
const yaml = require('js-yaml')
const meta = yaml.load(fs.readFileSync('./content/meta.yml', 'utf8'))
const { title, url, matomoSite, matomoUrl } = meta[0]
const resume = require('./content/resume.json')
const { matomoSite, matomoUrl } = meta[0]
const { name, website } = resume.basics
require('dotenv').config()
module.exports = {
siteMetadata: {
siteUrl: `${url}`
siteUrl: `${website}`
},
plugins: [
'gatsby-transformer-yaml',
@ -50,7 +52,7 @@ module.exports = {
resolve: 'gatsby-plugin-matomo',
options: {
siteId: `${matomoSite}`,
siteUrl: `${url}`,
siteUrl: `${website}`,
matomoUrl: `${matomoUrl}`,
localScript: '/piwik.js'
}
@ -58,7 +60,7 @@ module.exports = {
{
resolve: 'gatsby-plugin-manifest',
options: {
name: title.toLowerCase(),
name: name.toLowerCase(),
short_name: 'mk',
start_url: '/',
background_color: '#e7eef4',

6
package-lock.json generated
View File

@ -12308,9 +12308,9 @@
"integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ=="
},
"handlebars": {
"version": "4.5.2",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.2.tgz",
"integrity": "sha512-29Zxv/cynYB7mkT1rVWQnV7mGX6v7H/miQ6dbEpYTKq5eJBN7PsRB+ViYJlcT6JINTSu4dVB9kOqEun78h6Exg==",
"version": "4.5.3",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz",
"integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==",
"dev": true,
"requires": {
"neo-async": "^2.6.0",

View File

@ -5,36 +5,36 @@ import { useMeta } from '../../hooks/use-meta'
import { useResume } from '../../hooks/use-resume'
const MetaTags = ({ title, description, url, image, meta }) => {
const resume = useResume()
const twitterHandle = resume.basics.profiles.filter(
const { basics } = useResume()
const twitterHandle = basics.profiles.filter(
({ network }) => network === 'Twitter'
)[0].username
return (
<Helmet
defaultTitle={`${meta.title.toLowerCase()} { ${meta.tagline.toLowerCase()} }`}
titleTemplate={`%s // ${meta.title.toLowerCase()} { ${meta.tagline.toLowerCase()} }`}
defaultTitle={`${basics.name.toLowerCase()} { ${basics.label.toLowerCase()} }`}
titleTemplate={`%s // ${basics.name.toLowerCase()} { ${basics.label.toLowerCase()} }`}
title={title}
>
<html lang="en" />
{/* General tags */}
<meta name="description" content={description} />
<meta name="image" content={`${meta.url}${image}`} />
<meta name="image" content={`${basics.website}${image}`} />
<link rel="canonical" href={url} />
{/* OpenGraph tags */}
<meta property="og:url" content={url} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={`${meta.url}${image}`} />
<meta property="og:image" content={`${basics.website}${image}`} />
{/* Twitter Card tags */}
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:creator" content={twitterHandle} />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={`${meta.url}${image}`} />
<meta name="twitter:image" content={`${basics.website}${image}`} />
</Helmet>
)
}
@ -53,12 +53,13 @@ SEO.propTypes = {
export default function SEO({ project }) {
const meta = useMeta()
const { basics } = useResume()
const title = (project && project.title) || null
const description = (project && project.fields.excerpt) || meta.description
const image =
(project && project.img.childImageSharp.twitterImage.src) ||
meta.img.childImageSharp.resize.src
const url = (project && `${meta.url}${project.slug}`) || meta.url
const url = (project && `${basics.website}${project.slug}`) || basics.website
return (
<MetaTags

View File

@ -2,10 +2,10 @@ import React from 'react'
import PropTypes from 'prop-types'
import { Link } from 'gatsby'
import posed from 'react-pose'
import { useMeta } from '../../hooks/use-meta'
import { moveInBottom } from '../atoms/Transitions'
import { ReactComponent as Logo } from '../../images/logo.svg'
import styles from './LogoUnit.module.scss'
import { useResume } from '../../hooks/use-resume'
LogoUnit.propTypes = {
minimal: PropTypes.bool,
@ -13,16 +13,18 @@ LogoUnit.propTypes = {
}
export default function LogoUnit({ minimal }) {
const { title, tagline } = useMeta()
const { basics } = useResume()
const Animation = posed.div(moveInBottom)
return (
<Animation>
<Link className={minimal ? styles.minimal : styles.logounit} to={'/'}>
<Logo className={styles.logo} />
<h1 className={`p-name ${styles.title}`}>{title.toLowerCase()}</h1>
<h1 className={`p-name ${styles.title}`}>
{basics.name.toLowerCase()}
</h1>
<p className={`p-job-title ${styles.description}`}>
{tagline.toLowerCase()}
{basics.label.toLowerCase()}
</p>
</Link>
</Animation>

View File

@ -3,10 +3,7 @@ import { useStaticQuery, graphql } from 'gatsby'
const query = graphql`
query Meta {
metaYaml {
title
tagline
description
url
img {
childImageSharp {
resize(width: 980) {