Merge pull request #157 from ipfs/feat/hide-future-posts

Hide future posts/links and auto publish them on speficied date
This commit is contained in:
Zé Bateira
2021-04-21 14:59:17 +01:00
committed by GitHub
13 changed files with 207 additions and 36 deletions
+6 -13
View File
@@ -27,23 +27,16 @@ fields:
- type: datetime
name: date
label: Date
description: '"Published on" date. Remember this is <em>only</em> a list date for
display; posts are not automatically published!'
description: '"Published on" date.<br><br>To schedule this post for future publishing, simply
set the date to the future.<br><br><strong><em>WARNING</em></strong><em>: Data
is saved in the </em><a href="https://github.com/ipfs/ipfs-blog" title="" target="_blank"><em>ipfs/ipfs-blog</em></a><em>
public GitHub repo as soon as you hit the save button. So any sensitive information
will also be publicly available on GitHub, but hidden from the website blog.ipfs.io.</em>'
config:
required: true
date_format: YYYY/MM/DD
export_format: YYYY-MM-DD
- name: publishing_date
type: datetime
label: Publishing Date
config:
required: false
date_format:
time_format:
display_utc: true
description: When the post should be published.<br>Use this to schedule publishing
the post in the future.<br>If you don't want to schedule, just ignore this.
default: now
display_utc: false
- type: text
name: permalink
label: Permalink
+11 -5
View File
@@ -35,17 +35,23 @@ fields:
export_format: YYYY-MM-DD
description: For <strong>events</strong>, use the date of the event itself.<br>For
all other link types, use the date the original item was published.
- name: publishing_date
- name: publish_date
type: datetime
label: Publishing Date
description: When the link should be published.<br>Use this to schedule publishing
the link in the future.<br>If you don't want to schedule, just ignore this.
label: Publish Date
description: 'When
the link should be published.<br>Use this to schedule publishing the link in
the future.<br>If you don't want to schedule, leave this blank.<br><br><strong><em>WARNING</em></strong><em>:
Data is saved in the </em><a href="https://github.com/ipfs/ipfs-blog" title=""
target="_blank"><em>ipfs/ipfs-blog</em></a><em> public GitHub repo as soon as
you hit the Save button. This means anything you save will also be publicly
visible on GitHub, but not on the blog.ipfs.io site. Be careful if you are drafting something sensitive!</em>'
config:
required: false
date_format:
time_format:
display_utc: true
default: now
export_format: YYYY-MM-DDThh:mm:ssZ
default: ''
- type: text
name: path
label: URL
@@ -0,0 +1,26 @@
name: Check for scheduled posts to publish
on:
schedule:
- cron: '* 4,16 * * *'
jobs:
check-n-publish:
name: Check for scheduled posts and publish if any found
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2
- name: Install dependencies
run: npm ci
- name: Check for scheduled posts
run: echo "::set-output name=should_publish::$(${{ github.workspace }}/scripts/scheduled-publishing.js)"
id: should_publish_step
- name: Trigger Fleek Build
if: ${{ steps.should_publish_step.outputs.should_publish == 'true' }}
id: deploy
uses: fleekhq/action-deploy@v1
with:
apiKey: ${{ secrets.FLEEK_API_KEY }}
- name: Scheduled posts published
if: ${{ steps.should_publish_step.outputs.should_publish == 'true' }}
run: echo "Check https://blog.ipfs.io"
+2
View File
@@ -33,6 +33,7 @@
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-vue": "^7.9.0",
"gray-matter": "^4.0.2",
"husky": "^6.0.0",
"lint-staged": "^10.5.4",
"lodash": "^4.17.21",
@@ -41,6 +42,7 @@
"markdown-it-task-lists": "^2.1.1",
"markdown-it-video": "^0.6.3",
"npm-run-all": "^4.1.5",
"p-map": "^4.0.0",
"postcss": "^7.0.35",
"prettier": "^2.2.1",
"slug": "^4.0.4",
+2
View File
@@ -30,6 +30,7 @@
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-vue": "^7.9.0",
"gray-matter": "^4.0.2",
"husky": "^6.0.0",
"lint-staged": "^10.5.4",
"lodash": "^4.17.21",
@@ -38,6 +39,7 @@
"markdown-it-task-lists": "^2.1.1",
"markdown-it-video": "^0.6.3",
"npm-run-all": "^4.1.5",
"p-map": "^4.0.0",
"postcss": "^7.0.35",
"prettier": "^2.2.1",
"slug": "^4.0.4",
+98
View File
@@ -0,0 +1,98 @@
#!/usr/bin/env node
'use strict'
/**
* Scheduled Publishing of posts and links.
* This script checks for any blog posts and links that are scheduled to
* be published, but are to be published today. If there is at least
* one found, a build is trigged in fleek, updating the website
* with the latest data.
*/
const fs = require('fs')
const path = require('path')
const pMap = require('p-map')
const matter = require('gray-matter')
const dayjs = require('dayjs')
const isBetween = require('dayjs/plugin/isBetween')
dayjs.extend(isBetween)
async function main() {
// read files contents concurrently, 10 at a time
const contentDir = path.resolve(__dirname, '../src/_blog')
const files = await pMap(
await fs.promises.readdir(contentDir),
(filename) => {
if (!filename.endsWith('.md')) {
return null
}
return fs.promises.readFile(path.resolve(contentDir, filename), 'utf8')
},
{ concurrency: 10 }
)
const output = files
// exclude possible nulls
.filter((result) => !!result)
// process files into publishable items (posts or links)
.reduce((items, fileContent) => {
const metadata = matter(fileContent).data
if (metadata.type && metadata.data) {
// links
items.push(...metadata.data)
} else {
items.push(metadata)
}
return items
}, [])
// check if there is at least one publish date in the future
.some((item) => {
let publishDate
// blog post
if (item.permalink) {
publishDate = item.date
}
// links
if (item.url && item.publish_date) {
publishDate = item.publish_date
}
if (!publishDate) {
return false
}
// we trim to the hour to avoid counting the initial delays on triggering
// the job, which could cause the time calculations to exclude specific
// scheduled dates and times.
const now = dayjs(new Date()).startOf('hour')
const timeMatch = dayjs(new Date(publishDate)).isBetween(
now.subtract(12, 'hour'),
now
)
// using stderr since stdout is used for GH workflow output
if (timeMatch) {
console.error(`Found post/link to publish: "${item.title}"`)
}
return timeMatch
})
if (!output) {
console.error('Nothing found to publish.')
}
// output true or false: should trigger publish or not
// GH Workflow step reads from stdout
console.log(output)
}
main()
+42 -2
View File
@@ -1,4 +1,32 @@
const slug = require('slug')
const dayjs = require('dayjs')
function shouldBeHidden(frontmatter) {
const isDateInFuture = (date) => dayjs(new Date(date)).isAfter(dayjs())
let shouldHide = frontmatter.hidden || false
// sitemap config
if (frontmatter.sitemap) {
shouldHide = shouldHide || frontmatter.sitemap.exclude
}
// scheduled posts
// see auto-publishing of scheduled posts here: https://github.com/ipfs/ipfs-blog/issues/147
if (
!shouldHide &&
frontmatter.permalink && // permalink is unique to posts
frontmatter.date
) {
shouldHide = shouldHide || isDateInFuture(frontmatter.date)
}
// scheduled links (path is unique to links)
if (!shouldHide && frontmatter.path && frontmatter.publish_date) {
shouldHide = shouldHide || isDateInFuture(frontmatter.publish_date)
}
return shouldHide
}
module.exports = (options, context) => ({
extendPageData($page) {
@@ -18,8 +46,8 @@ module.exports = (options, context) => ({
frontmatter.authorKey = authorKey
}
// exclude a page from the feed & robots if excluded from sitemap
if (frontmatter.sitemap && frontmatter.sitemap.exclude) {
// exclude hidden pages (sitemap config, future publishes, etc)
if (shouldBeHidden(frontmatter)) {
frontmatter.feed = {
enable: false,
}
@@ -30,6 +58,18 @@ module.exports = (options, context) => ({
} else {
frontmatter.meta = [noIndex]
}
frontmatter.hidden = true
$page.hidden = true
}
// set links has hidden (future publishes, etc)
if (frontmatter.data) {
frontmatter.data.forEach((item) => {
if (shouldBeHidden(item)) {
item.hidden = true
}
})
}
},
})
+2 -8
View File
@@ -129,14 +129,8 @@ export default {
return false
}
if (
page.frontmatter &&
(page.frontmatter.sitemap ? !page.frontmatter.sitemap.exclude : true)
) {
result.push({
...page,
category: defaultCategory,
})
if (page.frontmatter && !page.frontmatter.hidden) {
result.push({ ...page, category: defaultCategory })
}
})
+12 -1
View File
@@ -1,5 +1,5 @@
<template>
<Layout v-if="!$frontmatter.type">
<Layout v-if="isVisible">
<article itemscope itemtype="https://schema.org/BlogPosting">
<PostHero
:title="$page.title"
@@ -46,7 +46,18 @@ export default {
data: () => ({
showComments: null,
}),
computed: {
// hidden field set in plugins/pageData.js
isVisible() {
return !this.$root.$page.hidden
},
},
mounted() {
if (!this.isVisible) {
// path to 404 is relative to support ipfs sub path deployments
return this.$router.replace({ path: '../404' })
}
const ipfsPathRegExp = /^(\/(?:ipfs|ipns)\/[^/]+)/
const ipfsPathPrefix =
(window.location.pathname.match(ipfsPathRegExp) || [])[1] || ''
+5 -4
View File
@@ -1,4 +1,4 @@
export const checkItem = ({
export function checkItem({
postType,
tags,
title,
@@ -7,7 +7,7 @@ export const checkItem = ({
searchedText = [],
activeCategory = '',
activeAuthor = '',
}) => {
}) {
if (activeCategory && decodeURI(activeCategory) !== postType) {
return false
}
@@ -40,13 +40,13 @@ export const checkItem = ({
return true
}
export const parseProtectedPost = (
export function parseProtectedPost(
post,
activeTags = [],
searchedText = [],
activeCategory = '',
activeAuthor = ''
) => {
) {
if (!post.frontmatter.data) {
return []
}
@@ -55,6 +55,7 @@ export const parseProtectedPost = (
post.frontmatter.data.forEach((item) => {
if (
item.hidden ||
!checkItem({
postType: post.frontmatter.type,
tags: item.tags,
@@ -7,6 +7,7 @@ author: Dietrich Ayala
header_image: "/086-ipfs-in-opera-for-android-header-image.png"
tags:
- browsers
- opera
- mobile
---
-2
View File
@@ -6,7 +6,6 @@ sitemap:
data:
- title: IPFS Community Meetup, April 2021
date: 2021-04-27
publishing_date:
path: https://www.meetup.com/San-Francisco-IPFS/events/276123324/
card_image: "/2021-04-15-cardheader-ipfs-meetup-nft-april2021.png"
tags:
@@ -14,7 +13,6 @@ data:
- official meetup
- title: Cal Hacks hello:world
date: 2021-04-16
publishing_date: 2021-04-15 17:06:47 +0000
path: https://helloworld.calhacks.io/
card_image: "/2021-04-15-cardheader-hello-world.png"
tags:
-1
View File
@@ -1,5 +1,4 @@
---
publishing_date:
title: Welcome to IPFS Weekly 131
description: Uniswap Interface hosting on IPFS, a call for Filecoin user testers,
and more from around the ecosystem!