1
0
mirror of https://github.com/kremalicious/blog.git synced 2024-12-22 17:23:50 +01:00

changelog component

This commit is contained in:
Matthias Kretschmann 2018-11-21 23:39:09 +01:00
parent b2b617e7eb
commit 24057c7d83
Signed by: m
GPG Key ID: 606EEEF3C479A91F
10 changed files with 224 additions and 7 deletions

1
.env.sample Normal file
View File

@ -0,0 +1 @@
GITHUB_TOKEN=your_token

View File

@ -13,15 +13,15 @@
<a href="https://greenkeeper.io/"><img src="https://badges.greenkeeper.io/kremalicious/blog.svg" /></a> <a href="https://greenkeeper.io/"><img src="https://badges.greenkeeper.io/kremalicious/blog.svg" /></a>
</p> </p>
## Table of Contents ---
- [Table of Contents](#table-of-contents)
- [🎉 Features](#-features) - [🎉 Features](#-features)
- [🎆 EXIF extraction](#-exif-extraction) - [🎆 EXIF extraction](#-exif-extraction)
- [💰 Cryptocurrency donation via Web3/MetaMask](#-cryptocurrency-donation-via-web3metamask) - [💰 Cryptocurrency donation via Web3/MetaMask](#-cryptocurrency-donation-via-web3metamask)
- [🔍 Search](#-search) - [🔍 Search](#-search)
- [🕸 Related Posts](#-related-posts) - [🕸 Related Posts](#-related-posts)
- [🐝 Coinhive](#-coinhive) - [🐝 Coinhive](#-coinhive)
- [📝 GitHub changelog rendering](#-github-changelog-rendering)
- [🏆 SEO component](#-seo-component) - [🏆 SEO component](#-seo-component)
- [📈 Matomo (formerly Piwik) analytics tracking](#-matomo-formerly-piwik-analytics-tracking) - [📈 Matomo (formerly Piwik) analytics tracking](#-matomo-formerly-piwik-analytics-tracking)
- [gatsby-redirect-from](#gatsby-redirect-from) - [gatsby-redirect-from](#gatsby-redirect-from)
@ -112,6 +112,26 @@ If you want to know how this works, have a look at the respective component unde
- [`src/components/atoms/Coinhive.jsx`](src/components/atoms/Coinhive.jsx) - [`src/components/atoms/Coinhive.jsx`](src/components/atoms/Coinhive.jsx)
### 📝 GitHub changelog rendering
Adds ability to show contents of a changelog, rendered from a `CHANGELOG.md` on GitHub from the given repository. The use case is to enhance release posts about projects hosted on GitHub. Makes use of the GitHub GraphQL API via [gatsby-source-graphql](https://www.gatsbyjs.org/packages/gatsby-source-graphql/).
Adding this to a post's YAML frontmatter:
```yaml
changelog: gatsby-plugin-matomo
```
will render this at the end of the post:
<img width="700" alt="screen shot 2018-11-21 at 23 03 38" src="https://user-images.githubusercontent.com/90316/48870593-bc74dd00-ede1-11e8-9051-df55ab7b48d1.png">
See it live on [Matomo plugin for Gatsby](https://kremalicious.com/gatsby-plugin-matomo#changelog).
If you want to know how this works, have a look at the respective component under
- [`src/components/atoms/Changelog.jsx`](src/components/atoms/Changelog.jsx)
### 🏆 SEO component ### 🏆 SEO component
Includes a SEO component which automatically switches all required `meta` tags for search engines, Twitter Cards, and Facebook OpenGraph tags based on the browsed route/page. Includes a SEO component which automatically switches all required `meta` tags for search engines, Twitter Cards, and Facebook OpenGraph tags based on the browsed route/page.
@ -159,6 +179,11 @@ Then install dependencies and start everything up:
```bash ```bash
npm i npm i
# GITHUB_TOKEN is required for some parts
cp .env.sample .env
vi .env
npm start npm start
``` ```

View File

@ -4,6 +4,7 @@ date: 2018-11-01T19:08:00.367Z
title: Matomo plugin for Gatsby title: Matomo plugin for Gatsby
image: gatsby-plugin-matomo-teaser.png image: gatsby-plugin-matomo-teaser.png
changelog: gatsby-plugin-matomo
tags: tags:
- goodies - goodies

View File

@ -1,3 +1,15 @@
require('dotenv').config()
if (!process.env.GITHUB_TOKEN) {
// eslint-disable-next-line
console.warn(`
A GitHub token is required to build some parts of the blog.
Check the README https://github.com/kremalicious/blog#-development.
`)
}
const path = require('path') const path = require('path')
const siteConfig = require('./config') const siteConfig = require('./config')
@ -37,6 +49,20 @@ module.exports = {
path: path.join(__dirname, 'src', 'images') path: path.join(__dirname, 'src', 'images')
} }
}, },
{
resolve: 'gatsby-source-graphql',
options: {
typeName: 'GitHub',
fieldName: 'github',
url: 'https://api.github.com/graphql',
headers: {
Authorization: `bearer ${process.env.GITHUB_TOKEN}`
},
// Additional options to pass to node-fetch
fetchOptions: {},
refetchInterval: 300 // 5 min.
}
},
'gatsby-plugin-sharp', 'gatsby-plugin-sharp',
'gatsby-transformer-sharp', 'gatsby-transformer-sharp',
{ {

View File

@ -55,6 +55,7 @@
"gatsby-remark-images": "^3.0.0", "gatsby-remark-images": "^3.0.0",
"gatsby-remark-smartypants": "^2.0.6", "gatsby-remark-smartypants": "^2.0.6",
"gatsby-source-filesystem": "^2.0.8", "gatsby-source-filesystem": "^2.0.8",
"gatsby-source-graphql": "^2.0.6",
"gatsby-transformer-remark": "^2.1.12", "gatsby-transformer-remark": "^2.1.12",
"gatsby-transformer-sharp": "^2.1.8", "gatsby-transformer-sharp": "^2.1.8",
"graphql": "^0.13.2", "graphql": "^0.13.2",
@ -74,6 +75,8 @@
"react-qr-svg": "^2.1.0", "react-qr-svg": "^2.1.0",
"react-time": "^4.3.0", "react-time": "^4.3.0",
"react-transition-group": "^2.5.0", "react-transition-group": "^2.5.0",
"remark": "^10.0.1",
"remark-react": "^4.0.3",
"slugify": "^1.3.3", "slugify": "^1.3.3",
"web3": "^1.0.0-beta.36" "web3": "^1.0.0-beta.36"
}, },

View File

@ -1,12 +1,13 @@
import React from 'react' import React, { Fragment } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Changelog from '../atoms/Changelog'
// Remove lead paragraph from content // Remove lead paragraph from content
const PostContent = ({ post }) => { const PostContent = ({ post }) => {
let content
const separator = '<!-- more -->' const separator = '<!-- more -->'
const changelog = post.frontmatter.changelog
content = post.html let content = post.html
if (post.frontmatter.type === 'post') { if (post.frontmatter.type === 'post') {
if (content.includes(separator)) { if (content.includes(separator)) {
@ -17,7 +18,12 @@ const PostContent = ({ post }) => {
} }
} }
return <div dangerouslySetInnerHTML={{ __html: content }} /> return (
<Fragment>
<div dangerouslySetInnerHTML={{ __html: content }} />
{changelog && <Changelog repo={changelog} />}
</Fragment>
)
} }
PostContent.propTypes = { PostContent.propTypes = {

View File

@ -0,0 +1,86 @@
import React from 'react'
import PropTypes from 'prop-types'
import { StaticQuery, graphql } from 'gatsby'
import remark from 'remark'
import remarkReact from 'remark-react'
import styles from './Changelog.module.scss'
const queryGithub = graphql`
query GitHubReposInfo {
github {
viewer {
repositories(first: 100, privacy: PUBLIC, isFork: false) {
edges {
node {
name
url
owner {
login
}
object(expression: "master:CHANGELOG.md") {
id
... on GitHub_Blob {
text
}
}
}
}
}
}
}
}
`
const Changelog = ({ repo }) => (
<StaticQuery
query={queryGithub}
render={data => {
const repositoriesGitHub = data.github.viewer.repositories.edges
let repoFilteredArray = repositoriesGitHub
.map(({ node }) => {
if (node.name === repo) return node
})
.filter(n => n)
const repoMatch = repoFilteredArray[0]
const { object, url, owner } = repoMatch
if (repoMatch === undefined || object === undefined) return null
const changelogHtml =
object &&
remark()
.use(remarkReact)
.processSync(object.text).contents
const filePathUrl = `${url}/tree/master/CHANGELOG.md`
const filePathDisplay = `${owner.login}/${repo}:CHANGELOG.md`
return (
<div className={styles.changelog}>
<h2 className={styles.changelogTitle} id="changelog">
Changelog
</h2>
<div className={styles.changelogContent}>
{changelogHtml}
<p className={styles.changelogSource}>
<em>
sourced from{' '}
<a href={filePathUrl}>
<code>{filePathDisplay}</code>
</a>
</em>
</p>
</div>
</div>
)
}}
/>
)
Changelog.propTypes = {
repo: PropTypes.string.isRequired
}
export default Changelog

View File

@ -0,0 +1,68 @@
@import 'variables';
.changelogTitle {
margin-bottom: 0;
}
.changelogContent {
padding-top: $spacer * 2;
padding-left: $spacer / 2;
margin-left: $spacer / 2;
border-left: 1px solid $brand-grey-dimmed;
h2 {
position: relative;
&::before {
content: '';
width: .4rem;
height: .4rem;
border-radius: 50%;
display: inline-block;
background: $color-headings;
position: absolute;
left: -($spacer / 1.5);
top: $font-size-large / 3;
}
}
h2,
h3 {
font-size: $font-size-large;
background: none;
padding: 0;
margin-left: 0;
margin-top: $spacer / 8;
margin-bottom: $spacer / $line-height;
}
ul {
font-size: $font-size-small;
margin-left: $spacer / 8;
}
}
.changelogSource {
font-size: $font-size-mini;
font-family: $font-family-base;
font-weight: $font-weight-base;
padding-top: $spacer / 2;
padding-bottom: $spacer / 2;
&,
a {
color: $brand-grey-light;
}
a {
margin-left: $spacer / 8;
code {
font-size: ($font-size-mini * .9);
}
&:hover {
color: $link-color;
}
}
}

View File

@ -45,7 +45,7 @@ $font-size-root: 18px;
$font-size-base: 1rem; $font-size-base: 1rem;
$font-size-large: 1.15rem; $font-size-large: 1.15rem;
$font-size-small: .8rem; $font-size-small: .85rem;
$font-size-mini: .7rem; $font-size-mini: .7rem;
$font-size-h1: 2.5rem; $font-size-h1: 2.5rem;

View File

@ -112,6 +112,7 @@ export const pageQuery = graphql`
style { style {
publicURL publicURL
} }
changelog
} }
fields { fields {
slug slug