mirror of
https://github.com/kremalicious/blog.git
synced 2024-12-22 17:23:50 +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>
|
<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
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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',
|
||||||
{
|
{
|
||||||
|
@ -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"
|
||||||
},
|
},
|
||||||
|
@ -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 = {
|
||||||
|
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-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;
|
||||||
|
@ -112,6 +112,7 @@ export const pageQuery = graphql`
|
|||||||
style {
|
style {
|
||||||
publicURL
|
publicURL
|
||||||
}
|
}
|
||||||
|
changelog
|
||||||
}
|
}
|
||||||
fields {
|
fields {
|
||||||
slug
|
slug
|
||||||
|
Loading…
Reference in New Issue
Block a user