snipette-gridsome/src/templates/GhostPost.vue

235 lines
6.8 KiB
Vue

<template>
<Layout>
<header class="site-header outer">
<div class="inner">
<Navbar :logo="true"/>
</div>
</header>
<!-- <FloatingHeader/> -->
<main id="site-main" class="site-main outer">
<div class="inner">
<article :class="postClass">
<header class="post-full-header">
<section class="post-full-meta" v-if="thisPost.tags">
<time class="post-full-meta-date" :datetime="thisPost.date | moment('d, MMMM YYYY')">{{ thisPost.date | moment("d, MMMM YYYY") }}</time>
<span class="date-divider">/</span>
<a
:href="thisPost.tags[0].path"
>{{ thisPost.tags[0].title.replace('-', ' ') }}</a>
</section>
<h1 class="post-full-title">{{ thisPost.title }}</h1>
</header>
<figure v-if="thisPost.image" class="post-full-image">
<g-image :src="thisPost.image|changeUrls" :alt="thisPost.title"/>
</figure>
<section class="post-full-content">
<div class="post-content" v-html="fullPost"></div>
</section>
<!-- Email subscribe form at the bottom of the page -->
<section v-if="Admin.site.subscribers" class="subscribe-form">
<h3 class="subscribe-form-title">Subscribe to {{ $static.metadata.ghost.title }}</h3>
<p>Get the latest posts delivered right to your inbox</p>
<subscribeForm placeholder="youremail@example.com"/>
</section>
<bylineMultiple :author="thisPost.authors" v-if="thisPost.authors && thisPost.authors.length > 1"/>
<bylineSingle :author="thisPost.authors" v-if="thisPost.authors && thisPost.authors.length == 1" />
<!-- NOTE Comment section -->
<!-- <section class="post-full-comments">
If you want to embed comments, this is a good place to do it!
</section>-->
</article>
</div>
</main>
<PreviousNext :id="thisPost.id" :tag="thisPost.tags[0]" :posts="thisPost.tags[0].belongsTo.edges" v-if="thisPost.tags"/>
</Layout>
</template>
<style type="text/css">
.post-full-content hr {
border: 0;
height: 3rem;
display: block;
background-image: url(https://media.snipettemag.com/manual-uploads/snip-grey-small.png);
background-size: contain;
background-repeat: no-repeat;
background-position: 50%;
}
.post-full-content hr::after {
display: none;
}
</style>
<script>
import Admin from "../../data/admin.yml";
import Navbar from "../components/Navbar";
import FloatingHeader from "../components/FloatingHeader";
import subscribeForm from "../components/subscribeForm";
import bylineMultiple from "../components/bylineMultiple";
import bylineSingle from "../components/bylineSingle";
import PreviousNext from "../components/PreviousNext";
import changeUrls from '../filters/changeUrls';
export default {
metaInfo() {
let bodyAttrs;
if (this.$page.post) {
bodyAttrs = `post-template tag-${this.$page.post.tags[0].title}`
} else {
bodyAttrs = "page-template"
}
let baseUrl = this.$static.metadata.siteUrl||this.$static.metadata.ghost.url
let meta = [
{ property: 'og:site_name', content: 'Snipette' },
{ property: 'og:type', content: 'article' },
{ property: 'og:title', content: this.thisPost.title },
{ property: 'og:description', content: this.thisPost.description },
{ property: 'og:url', content: baseUrl + this.thisPost.path },
{ property: 'og:image', content: changeUrls(this.thisPost.image) },
{ property: 'article:published_time', content: this.thisPost.date },
]
if (this.thisPost.tags) {
for (var i=0; i<this.thisPost.tags.length; i++) {
meta.push({ property: 'article:tag', content: this.thisPost.tags[i].title })
}
}
if (Admin.social_media && Admin.social_media.facebook) {
meta.push({ property: 'article:publisher', content: 'https://www.facebook.com/' + Admin.social_media.facebook })
}
meta = meta.concat([
{ property: 'twitter:card', content: 'summary_large_image' },
{ property: 'twitter:title', content: this.thisPost.title },
{ property: 'twitter:description', content: this.thisPost.description },
{ property: 'twitter:url', content: baseUrl + this.thisPost.path },
{ property: 'twitter:image', content: changeUrls(this.thisPost.image) },
{ property: 'twitter:label1', content: 'Written by' },
{ property: 'twitter:data1', content: this.thisPost.authors ? this.thisPost.authors[0].name : '' },
{ property: 'twitter:label2', content: 'Filed under' },
{ property: 'twitter:data2', content: this.thisPost.tags ? this.thisPost.tags.map((t)=>{return t.title}).join(',') : '' },
])
if (Admin.social_media && Admin.social_media.twitter) {
meta.push({ property: 'twitter:site', content: '@' + Admin.social_media.twitter })
}
return {
title: this.$page.post ? this.$page.post.title : this.$page.page.title,
meta: meta,
bodyAttrs: {
class: bodyAttrs
}
};
},
components: {
Navbar,
FloatingHeader,
subscribeForm,
bylineMultiple,
bylineSingle,
PreviousNext
},
filters: {
changeUrls: changeUrls
},
computed: {
Admin() {
return Admin;
},
fullPost() {
let thisPost = this.$page.post || this.$page.page
return changeUrls(thisPost.content);
},
postClass() {
let classes = []
if (this.$page.post) {
classes.push("post-full");
classes.push("post");
if (!this.$page.post.image) {
classes.push("no-image");
}
const postTagClass = "tag-" + this.$page.post.tags[0].title;
classes.push(postTagClass);
} else {
classes.push("page-full");
classes.push("page");
}
return classes;
},
thisPost() {
// Return post or page, whichever exists
return this.$page.page || this.$page.post
}
}
};
</script>
<page-query>
query Post ($path: String!) {
post: ghostPost (path: $path) {
id
title
path
date: published_at (format: "D. MMMM YYYY")
tags {
id
slug
path
title: name
belongsTo {
edges {
node {
... on GhostPost {
id
title
path
}
}
}
}
}
authors {
name
id
slug
image: profile_image
}
description: excerpt
content: html
image: feature_image
}
page: ghostPage (path: $path) {
id
title
path
date: updated_at (format: "D. MMMM YYYY")
description: excerpt
content: html
}
}
</page-query>
<static-query>
query Metadata {
metadata {
siteUrl
ghost {
title
url
}
}
}
</static-query>