1
0
mirror of https://github.com/kremalicious/blog.git synced 2024-06-30 05:31:56 +02:00

Merge pull request #107 from kremalicious/feature/changelog

changelog component
This commit is contained in:
Matthias Kretschmann 2018-11-22 01:35:29 +01:00 committed by GitHub
commit 7ef223a465
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 259 additions and 36 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>
</p>
## Table of Contents
---
- [Table of Contents](#table-of-contents)
- [🎉 Features](#-features)
- [🎆 EXIF extraction](#-exif-extraction)
- [💰 Cryptocurrency donation via Web3/MetaMask](#-cryptocurrency-donation-via-web3metamask)
- [🔍 Search](#-search)
- [🕸 Related Posts](#-related-posts)
- [🐝 Coinhive](#-coinhive)
- [📝 GitHub changelog rendering](#-github-changelog-rendering)
- [🏆 SEO component](#-seo-component)
- [📈 Matomo (formerly Piwik) analytics tracking](#-matomo-formerly-piwik-analytics-tracking)
- [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)
### 📝 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
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
npm i
# GITHUB_TOKEN is required for some parts
cp .env.sample .env
vi .env
npm start
```

View File

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

View File

@ -1,5 +1,17 @@
const path = require('path')
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 siteConfig = require('./config')
const sources = require('./gatsby/sources')
// required for gatsby-plugin-meta-redirect
require('regenerator-runtime/runtime')
@ -9,34 +21,7 @@ module.exports = {
...siteConfig
},
plugins: [
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'posts',
path: path.join(__dirname, 'content', 'posts')
}
},
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'photos',
path: path.join(__dirname, 'content', 'photos')
}
},
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'media',
path: path.join(__dirname, 'content', 'media')
}
},
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'images',
path: path.join(__dirname, 'src', 'images')
}
},
...sources,
'gatsby-plugin-sharp',
'gatsby-transformer-sharp',
{

46
gatsby/sources.js Normal file
View File

@ -0,0 +1,46 @@
const path = require('path')
module.exports = [
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'posts',
path: path.join(__dirname, '..', 'content', 'posts')
}
},
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'photos',
path: path.join(__dirname, '..', 'content', 'photos')
}
},
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'media',
path: path.join(__dirname, '..', 'content', 'media')
}
},
{
resolve: 'gatsby-source-filesystem',
options: {
name: '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.
}
}
]

View File

@ -55,6 +55,7 @@
"gatsby-remark-images": "^3.0.0",
"gatsby-remark-smartypants": "^2.0.6",
"gatsby-source-filesystem": "^2.0.8",
"gatsby-source-graphql": "^2.0.6",
"gatsby-transformer-remark": "^2.1.12",
"gatsby-transformer-sharp": "^2.1.8",
"graphql": "^0.13.2",
@ -74,6 +75,8 @@
"react-qr-svg": "^2.1.0",
"react-time": "^4.3.0",
"react-transition-group": "^2.5.0",
"remark": "^10.0.1",
"remark-react": "^4.0.3",
"slugify": "^1.3.3",
"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 Changelog from '../atoms/Changelog'
// Remove lead paragraph from content
const PostContent = ({ post }) => {
let content
const separator = '<!-- more -->'
const changelog = post.frontmatter.changelog
content = post.html
let content = post.html
if (post.frontmatter.type === 'post') {
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 = {

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,69 @@
@import 'variables';
.changelogTitle {
margin-top: $spacer * 3;
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-large: 1.15rem;
$font-size-small: .8rem;
$font-size-small: .85rem;
$font-size-mini: .7rem;
$font-size-h1: 2.5rem;

View File

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