Create Ghost templates for Posts, Authors, and Views

This commit is contained in:
Hippo 2019-12-18 19:24:22 +05:30
parent 04d421edb1
commit e264253c16
11 changed files with 2545 additions and 1636 deletions

View File

@ -4,6 +4,12 @@ module.exports = {
siteDescription: 'The professional publishing platform',
titleTemplate: `%s - Gridsome`,
templates: {
GhostPost: '/:slug',
GhostTag: '/tag/:slug',
GhostAuthor: '/author/:slug'
},
plugins: [
{
use: '@gridsome/plugin-google-analytics',
@ -12,29 +18,16 @@ module.exports = {
}
},
{
use: '@gridsome/source-filesystem',
use: '@gridsome/source-ghost',
options: {
path: 'blog/*.md',
typeName: 'Post',
route: '/:slug',
refs: {
author: 'Author',
tags: {
typeName: 'Tag',
route: '/tag/:title',
create: true
}
baseUrl: process.env.GHOST_API_URL,
contentKey: process.env.GHOST_CONTENT_KEY,
routes: {
post: '/:slug',
page: '/:slug',
author: '/author/:slug'
}
}
},
{
use: '@gridsome/source-filesystem',
options: {
// TODO Use yaml file as data source
path: 'data/author/*.md',
typeName: 'Author',
route: '/author/:id'
}
}
]
}

View File

@ -8,11 +8,14 @@
},
"dependencies": {
"@gridsome/plugin-google-analytics": "^0.1.0",
"@gridsome/source-filesystem": "^0.3.0",
"@gridsome/transformer-remark": "^0.2.0",
"gridsome": "^0.5.0",
"node-sass": "^4.11.0",
"@gridsome/source-filesystem": "^0.6.0",
"@gridsome/source-ghost": "^0.2.0",
"@gridsome/transformer-remark": "^0.3.0",
"gridsome": "^0.7.0"
},
"devDependencies": {
"node-sass": "^4.12.0",
"sass-loader": "^7.1.0",
"vue-moment": "^4.0.0"
}
}
}

View File

@ -1,8 +1,8 @@
<template>
<article :class="articleClass">
<a v-if="cardData.image" class="post-card-image-link" :href="cardData.path">
<a v-if="cardData.coverImage" class="post-card-image-link" :href="cardData.path">
<!-- FIXME Background size cover -->
<div class="post-card-image" :style="'background-image: url(' + cardData.image + ')'"></div>
<div class="post-card-image" :style="'background-image: url(' + cardData.coverImage + ')'"></div>
</a>
<div class="post-card-content">
<a class="post-card-content-link" :href="cardData.path">
@ -10,21 +10,21 @@
<span
v-if="cardData.tags"
class="post-card-tags"
>{{ cardData.tags.title.replace('-', ' ') }}</span>
>{{ cardData.tags[0].name.replace('-', ' ') }}</span>
<h2 class="post-card-title">{{ cardData.title }}</h2>
</header>
<section class="post-card-excerpt">
<p>{{ cardData.content | stripHTML | truncate(190, '...') }}</p>
<p>{{ cardData.description | stripHTML | truncate(190, '...') }}</p>
</section>
</a>
<footer class="post-card-meta">
<ul class="author-list">
<li v-for="author in cardData.author" class="author-list-item" :key="author.name">
<li v-for="author in cardData.authors" class="author-list-item" :key="author.slug">
<div class="author-name-tooltip">{{ author.name }}</div>
<a v-if="author.image" :href="'/author/' + author.id" class="static-avatar">
<a v-if="author.image" :href="'/author/' + author.slug" class="static-avatar">
<img class="author-profile-image" :src="author.image" :alt="author.name" />
</a>
<a v-else :href="'/author/' + author.id" class="static-avatar author-profile-image">
<a v-else :href="'/author/' + author.slug" class="static-avatar author-profile-image">
<Avatar/>
</a>
</li>
@ -52,16 +52,20 @@ export default {
if (this.cardData.fields === null) {
classes.push("no-image");
}
const cardTagClass = "post-" + this.cardData.tags;
classes.push(cardTagClass);
for (var i=0;i<this.cardData.tags.length;i++) {
var cardTagClass = "post-" + this.cardData.tags[i].slug;
classes.push(cardTagClass);
}
return classes;
}
},
filters: {
truncate: (text, length, suffix) => {
if (!text) return text
return text.substring(0, length) + suffix;
},
stripHTML: text => {
if (!text) return text
return text.replace(/<[^>]+>/g, '')
}
}

View File

@ -4,13 +4,14 @@
<div class="inner">
<div class="read-next-feed">
<article
v-if="posts.length > 1"
class="read-next-card"
:style="'background-image: url(' + Admin.site.cover_image + ')'"
>
<header class="read-next-card-header">
<small class="read-next-card-header-sitetitle">&mdash; {{ Admin.site.title }} &mdash;</small>
<h3 class="read-next-card-header-title">
<a :href="'/tag/' + tag">{{ tag.replace('-', ' ') | capitalizeFilter }}</a>
<a :href="tag.path">{{ tag.title.replace('-', ' ') | capitalizeFilter }}</a>
</h3>
</header>
<div class="read-next-divider">
@ -22,13 +23,14 @@
</div>
<div class="read-next-card-content">
<ul>
<li v-for="post in posts" :key="post.node.id">
<li v-for="post in posts.slice(0, 3)"
:key="post.node.id">
<a :href="post.node.path">{{ post.node.title }}</a>
</li>
</ul>
</div>
<footer class="read-next-card-footer">
<a :href="'/tag/' + this.tag">See all {{ posts.length }} posts </a>
<a :href="this.tag.path">See all {{ posts.length }} posts </a>
</footer>
</article>
<Card
@ -84,7 +86,7 @@ export default {
},
methods: {
getPreviousNext() {
const allBlogs = this.$static.allPost.edges;
const allBlogs = this.$static.allGhostPost.edges;
for (let i = 0; i < allBlogs.length; i++) {
if (allBlogs[i].node.id === this.currentPostId) {
if (i > 0) {
@ -102,25 +104,27 @@ export default {
<static-query>
query Blog {
allPost(order: ASC) {
allGhostPost(order: ASC) {
edges {
node {
title
description: excerpt
date: published_at (format: "D. MMMM YYYY")
path
slug
id
title
path
tags {
title
}
image
author {
id
name
image
}
content
timeToRead
coverImage: feature_image
authors {
name
url
slug
image: profile_image
}
tags {
name
}
}
}
}
}
</static-query>
</static-query>

View File

@ -9,19 +9,19 @@
v-for="author in author"
:key="author.name"
:href="'/author/' + author.id"
>{{ author.name }}</a>
>{{ author.name }},</a>
</p>
</div>
<ul class="author-list" v-on:mouseleave="hideAuthorCard">
<!-- FIXME Appear only single card on hover -->
<li
v-on:mouseover="authorCardHovered = authorUsername"
v-on:mouseover="authorCardHovered = author.slug"
v-for="author in author"
:key="author.name"
:key="author.slug"
class="author-list-item"
>
<div :class="{'author-card': true, hovered: authorCardHovered === authorUsername }">
<div :class="{'author-card': true, hovered: authorCardHovered === author.slug }">
<div class="basic-info">
<img
v-if="author.image"
@ -51,7 +51,7 @@
</div>
</div>
<a v-if="author.image" :href="'/author/' + author.id" class="moving-avatar">
<a v-if="author.image" :href="'/author/' + author.slug" class="moving-avatar">
<img class="author-profile-image" :src="author.image" :alt="author.name">
</a>
<a v-else :href="'/author/' + author.id" class="moving-avatar author-profile-image">

View File

@ -8,16 +8,16 @@
<section class="author-card-content">
<h4 class="author-card-name">
<a :href="'/author/' + authorData.id">
<a :href="'/author/' + authorData.slug">
{{ authorData.name }}
</a>
</h4>
<p v-if="authorData.tagline">{{ authorData.tagline }}</p>
<p v-else>Read <a :href="'/author/' + authorData.id">more posts</a> by this author.</p>
<p v-else>Read <a :href="'/author/' + authorData.slug">more posts</a> by this author.</p>
</section>
</section>
<div class="post-full-footer-right">
<a class="author-card-button" :href="'/author/' + authorData.id">Read More</a>
<a class="author-card-button" :href="'/author/' + authorData.slug">Read More</a>
</div>
</footer>
</template>

View File

@ -1,15 +1,20 @@
<template>
<Layout>
<header :class=HeroBgClass :style=HeroBgImage>
<header
:class=HeroBgClass>
<div class="inner">
<div class="site-header-content">
<h1 class="site-title">
<img v-if="Admin.site.logo != ''" class="site-logo" :src="Admin.site.logo" :alt="Admin.site.title" />
<p v-if="Admin.site.logo === ''">
{{ Admin.site.title }}
<img v-if="$static.metadata.ghost.logo != ''" class="site-logo"
:src="$static.metadata.ghost.logo"
:alt="$static.metadata.siteTitle|$static.metadata.ghost.title" />
<p v-if="$static.metadata.ghost.logo === ''">
{{ $static.metadata.title }}
</p>
</h1>
<h2 class="site-description">{{ Admin.site.description}}</h2>
<h2 class="site-description">
{{ $static.metadata.siteDescription|$static.metadata.ghost.description}}
</h2>
</div>
<Navbar :logo=false />
</div>
@ -19,7 +24,7 @@
<main id="site-main" class="site-main outer">
<div class="inner">
<div class="post-feed">
<Card v-for="{ node } in $page.allPost.edges" :key="node.id" :cardData="node" />
<Card v-for="{ node } in $page.posts.edges" :key="node.id" :cardData="node" />
</div>
</div>
</main>
@ -27,7 +32,6 @@
</template>
<script>
import Admin from '../../data/admin.yml';
import Navbar from '../components/Navbar'
import Card from '../components/Card';
@ -41,48 +45,67 @@
Navbar, Card
},
computed: {
Admin() {
return Admin
},
HeroBgImage() {
if (Admin.site.cover_image) {
HeroBgImage(metadata) {
if (metadata.cover_image) {
return {
backgroundImage: 'url(' + Admin.site.cover_image + ')'
backgroundImage: 'url(' + $static.metadata.cover_image + ')'
}
}
},
HeroBgClass() {
if (Admin.site.cover_image) {
return 'site-header outer'
} else {
return 'site-header outer no-cover'
}
return 'site-header outer no-cover'
}
}
}
</script>
<page-query>
query Home ($page: Int) {
allPost (page: $page, order: ASC) {
edges {
node {
id
title
path
tags {
title
}
image
content
author {
id
name
image
}
timeToRead
{
posts: allGhostPost(
sortBy: "published_at",
order: DESC,
) {
edges {
node {
title
description: excerpt
date: published_at (format: "D. MMMM YYYY")
path
slug
id
coverImage: feature_image
authors {
name
url
slug
image: profile_image
}
tags {
name
slug
}
}
}
}
</page-query>
}
</page-query>
<static-query>
query Admin {
metadata {
siteName
siteDescription
siteUrl
ghost {
title
url
logo
description
navigation {
url
label
}
}
}
}
</static-query>

View File

@ -9,7 +9,7 @@
<h2 v-if="bio = true" class="author-bio">{{ $page.author.bio }}</h2>
<div class="author-meta">
<div v-if="location = true" class="author-location">{{ $page.author.location }}
<div v-if="$page.author.location" class="author-location">{{ $page.author.location }}
<span class="bull">&bull;</span>
</div>
@ -102,34 +102,36 @@
</style>
<page-query>
query Author ($id: String!) {
author (id: $id) {
query Author ($path: String!) {
author: ghostAuthor (path: $path) {
name
image
image: profile_image
bio
location
website
twitter
facebook
belongsTo {
edges {
node {
...on Post {
id
...on GhostPost {
title
author {
id
name
image
}
description: excerpt
date: published_at (format: "D. MMMM YYYY")
path
image
content
timeToRead
slug
id
coverImage: feature_image
authors {
name
url
slug
image: profile_image
}
tags {
name
}
}
}
}
}
}
}
</page-query>
</page-query>

View File

@ -16,8 +16,8 @@
<time class="post-full-meta-date" :datetime="$page.post.date | moment('d, MMMM YYYY')">{{ $page.post.date | moment("d, MMMM YYYY") }}</time>
<span class="date-divider">/</span>
<a
:href="'/tag/' + $page.post.tags.title"
>{{ $page.post.tags.title.replace('-', ' ') }}</a>
:href="$page.post.tags[0].path"
>{{ $page.post.tags[0].title.replace('-', ' ') }}</a>
</section>
<h1 class="post-full-title">{{ $page.post.title }}</h1>
</header>
@ -37,8 +37,8 @@
<subscribeForm placeholder="youremail@example.com"/>
</section>
<bylineMultiple :author="$page.post.author" v-if="$page.post.author.length > 1"/>
<bylineSingle :author="$page.post.author" v-else/>
<bylineMultiple :author="$page.post.authors" v-if="$page.post.authors.length > 1"/>
<bylineSingle :author="$page.post.authors" v-else/>
<!-- NOTE Comment section -->
<!-- <section class="post-full-comments">
@ -48,7 +48,7 @@
</div>
</main>
<PreviousNext :id="$page.post.id" :tag="$page.post.tags.title" :posts="$page.post.tags.belongsTo.edges"/>
<PreviousNext :id="$page.post.id" :tag="$page.post.tags[0]" :posts="$page.post.tags[0].belongsTo.edges"/>
</Layout>
</template>
@ -66,7 +66,7 @@ export default {
return {
title: this.$page.post.title,
bodyAttrs: {
class: `post-template tag-${this.$page.post.tags.title}`
class: `post-template tag-${this.$page.post.tags[0].title}`
}
};
},
@ -87,7 +87,7 @@ export default {
if (!this.$page.post.image) {
classes.push("no-image");
}
const postTagClass = "tag-" + this.$page.post.tags.title;
const postTagClass = "tag-" + this.$page.post.tags[0].title;
classes.push(postTagClass);
return classes;
}
@ -95,17 +95,21 @@ export default {
};
</script>
<page-query>
query BlogPost ($path: String!) {
post (path: $path) {
query Post ($path: String!) {
post: ghostPost (path: $path) {
id
title
date
path
date: published_at (format: "D. MMMM YYYY")
tags {
title
id
slug
path
title: name
belongsTo {
edges {
node {
... on Post {
... on GhostPost {
id
title
path
@ -114,15 +118,15 @@ export default {
}
}
}
image
author {
id
authors {
name
image
tagline
bio
id
slug
image: profile_image
}
content
description: excerpt
content: html
image: feature_image
}
}
</page-query>

View File

@ -61,28 +61,33 @@ export default {
</script>
<page-query>
query Tags ($id: String!) {
tag (id: $id) {
title
query Tags ($path: String!) {
tag: ghostTag (path: $path) {
title: name
belongsTo {
edges {
node {
...on Post {
id
...on GhostPost {
title
description: excerpt
date: published_at (format: "D. MMMM YYYY")
path
image
author {
id
slug
id
coverImage: feature_image
authors {
name
url
slug
image: profile_image
}
tags {
name
image
}
content
timeToRead
}
}
}
}
}
}
</page-query>
</page-query>

3849
yarn.lock

File diff suppressed because it is too large Load Diff