Skip to content

Commit

Permalink
Move post fetching and processing to api and model classes
Browse files Browse the repository at this point in the history
* Remove some readmes
  • Loading branch information
Morgan Brown committed Feb 9, 2019
1 parent ab0dce3 commit 2f737d8
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 89 deletions.
16 changes: 0 additions & 16 deletions .eslintrc.js

This file was deleted.

20 changes: 20 additions & 0 deletions api/posts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import axios from 'axios'

export default {
async bySha (sha) {
const { data } = await axios.get(`https://api.github.com/repos/mhgbrown/nuxt-ghpages-blog-content/git/blobs/${sha}?access_token=${process.env.GITHUB_TOKEN}`)
return data
},
async all () {
const postsPath = 'posts/'
const url = `https://api.github.com/repos/mhgbrown/nuxt-ghpages-blog-content/git/trees/master?recursive=1&access_token=${process.env.GITHUB_TOKEN}`
const { data } = await axios.get(url)
return data.tree.reduce((memo, node) => {
if (node.path.startsWith(postsPath)) {
memo.push(node)
}

return memo
}, [])
}
}
7 changes: 0 additions & 7 deletions assets/README.md

This file was deleted.

7 changes: 0 additions & 7 deletions components/README.md

This file was deleted.

43 changes: 43 additions & 0 deletions models/post.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import postsClient from '../api/posts'

class Post {
static async all () {
const rawPosts = await postsClient.all()
return rawPosts.map(rawPost => this._fromNode(rawPost))
}

static async bySha (sha) {
const rawPost = await postsClient.bySha(sha)
return this._fromBlob(rawPost)
}

static _fromNode (node) {
const post = new this(node)
const pathPrefix = 'posts/'
post.name = node.path.replace(pathPrefix, '')
post.title = this._extractTitle(post.name)
post.date = this._extractDate(post.name)
return post
}

static _fromBlob (blob) {
const post = new this(blob)
post.content = ''
return post
}

static _extractTitle (name) {
return name.replace(/\.md$/, '')
.replace(/^\d{4}-\d{1,2}-\d{1,2}-/, '')
}

static _extractDate (name) {
return /^\d{4}-\d{1,2}-\d{1,2}/.exec(name)[0]
}

constructor (nodeOrBlob) {
this.sha = nodeOrBlob.sha
}
}

export default Post
36 changes: 19 additions & 17 deletions nuxt.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin')
const axios = require('axios')
const pkg = require('./package')
import VuetifyLoaderPlugin from 'vuetify-loader/lib/plugin'
import pkg from './package'
import Post from './models/post'

module.exports = {
export default {
mode: 'universal',

/*
Expand Down Expand Up @@ -51,26 +51,28 @@ module.exports = {
'@nuxtjs/axios'
],

/*
** Environment variables to inject
*/
env: {
GITHUB_TOKEN: process.env.GITHUB_TOKEN
},

/**
* Static generation configuration
*/
generate: {
interval: 100,

async routes () {
try {
const postsDirectory = 'posts/'
const url = `https://api.github.com/repos/mhgbrown/nuxt-ghpages-blog-content/git/trees/master?recursive=1&access_token=${process.env.GITHUB_TOKEN}`
const response = await axios.get(url)
return response.data.tree.reduce((memo, node) => {
if (node.path.startsWith(postsDirectory)) {
// NB: route is actually the same as node.path in my case
memo.push({
route: `/posts/${node.sha}`,
payload: node
})
const posts = await Post.all()
return posts.map((post) => {
return {
route: `/posts/${post.sha}`,
payload: post
}

return memo
}, [])
})
} catch (error) {
// eslint-disable-next-line no-console
console.error(error.response)
Expand Down
3 changes: 1 addition & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
},
"dependencies": {
"@nuxtjs/axios": "^5.3.6",
"abab": "^2.0.0",
"cross-env": "^5.2.0",
"gray-matter": "^4.0.2",
"highlightjs": "^9.12.0",
Expand Down
6 changes: 0 additions & 6 deletions pages/README.md

This file was deleted.

15 changes: 14 additions & 1 deletion pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,25 @@
sm8
md6
>
Hello!
<h1>My Posts</h1>
<ul>
<li v-for="post in posts" :key="post.sha">
<router-link :to="{ name: 'posts-id', params: { id: post.sha } }">{{ post.title }}</router-link>
</li>
</ul>
</v-flex>
</v-layout>
</template>

<script>
import Post from '@/models/post'
export default {
async asyncData () {
const posts = await Post.all()
return {
posts
}
}
}
</script>
58 changes: 52 additions & 6 deletions pages/posts/_id.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,67 @@
sm8
md6
>
{{ post.sha }}
<p>{{ matter.data.title }}</p>
{{matter}}
</v-flex>
</v-layout>
</template>

<script>
import Post from '@/models/post'
import * as matter from 'gray-matter'
import Remarkable from 'remarkable'
import hljs from 'highlightjs'
import { atob } from 'abab'
// MDN sourced function to properly decode chinese, etc characters
function b64DecodeUnicode (str) {
// Going backwards: from bytestream, to percent-encoding, to original string.
return decodeURIComponent(atob(str).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
}).join(''))
}
// Actual default values
const md = new Remarkable({
highlight (str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return hljs.highlight(lang, str).value
} catch (err) {}
}
try {
return hljs.highlightAuto(str).value
} catch (err) {}
return '' // use external default escaping
}
})
export default {
asyncData ({ params, error, payload }) {
if (payload) {
async asyncData ({ params, error, payload }) {
try {
const post = await Post.bySha(params.id)
return {
post: payload
post
}
} catch (error) {
// eslint-disable-next-line no-console
console.error(error.response)
throw error
}
},
computed: {
decodedContent () {
return b64DecodeUnicode(this.post.content)
},
matter () {
return matter(this.decodedContent)
},
html () {
return md(this.matter.content)
}
throw new Error('No payload')
}
}
</script>
7 changes: 0 additions & 7 deletions plugins/README.md

This file was deleted.

10 changes: 0 additions & 10 deletions static/README.md

This file was deleted.

10 changes: 0 additions & 10 deletions store/README.md

This file was deleted.

0 comments on commit 2f737d8

Please sign in to comment.