mirror of
https://github.com/kremalicious/blog.git
synced 2024-12-22 09:13:35 +01:00
changelog component
This commit is contained in:
parent
b2b617e7eb
commit
24057c7d83
1
.env.sample
Normal file
1
.env.sample
Normal file
@ -0,0 +1 @@
|
||||
GITHUB_TOKEN=your_token
|
29
README.md
29
README.md
@ -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
|
||||
```
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 siteConfig = require('./config')
|
||||
|
||||
@ -37,6 +49,20 @@ module.exports = {
|
||||
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-transformer-sharp',
|
||||
{
|
||||
|
@ -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"
|
||||
},
|
||||
|
@ -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 = {
|
||||
|
86
src/components/atoms/Changelog.jsx
Normal file
86
src/components/atoms/Changelog.jsx
Normal 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
|
68
src/components/atoms/Changelog.module.scss
Normal file
68
src/components/atoms/Changelog.module.scss
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -112,6 +112,7 @@ export const pageQuery = graphql`
|
||||
style {
|
||||
publicURL
|
||||
}
|
||||
changelog
|
||||
}
|
||||
fields {
|
||||
slug
|
||||
|
Loading…
Reference in New Issue
Block a user