1
0
Fork 0

chore(dev): Removed blog from the dev site

This commit is contained in:
Joost De Cock 2022-10-02 21:58:34 +02:00
parent c3be46c487
commit 8c65b9d132
6 changed files with 26 additions and 440 deletions

View file

@ -1,70 +0,0 @@
import Head from 'next/head'
const rss = (lang, type, title) => ({
title,
type: "application/rss+xml",
href: `/feeds/${type}-${lang}.rss.xml`
})
const atom = (lang, type, title) => ({
title,
type: "application/rss+atom",
href: `/feeds/${type}-${lang}.atom.xml`
})
const json = (lang, type, title) => ({
title,
type: "application/json",
href: `/feeds/${type}-${lang}.json`
})
const feeds = {
en: [
atom('en', 'blog', "Atom feed of FreeSewing.org blog posts"),
json('en', 'blog', "JSON feed of FreeSewing.org blog posts"),
rss( 'en', 'blog', "RSS feed of FreeSewing.org blog posts"),
atom('en', 'showcase', "Atom feed of FreeSewing.org showcase posts"),
json('en', 'showcase', "JSON feed of FreeSewing.org showcase posts"),
rss( 'en', 'showcase', "RSS feed of FreeSewing.org showcase posts"),
],
de: [
atom('de', 'blog', "Atom-Feed von FreeSewing.org-Blogbeiträgen"),
json('de', 'blog', "JSON-Feed von FreeSewing.org-Blogbeiträgen"),
rss( 'de', 'blog', "RSS-Feed von FreeSewing.org-Blogbeiträgen"),
atom('de', 'showcase', "Atom-Feed von FreeSewing.org-Galeriebeiträgen"),
json('de', 'showcase', "JSON-Feed von FreeSewing.org-Galeriebeiträgen"),
rss( 'de', 'showcase', "RSS-Feed von FreeSewing.org-Galeriebeiträgen"),
],
es: [
atom('es', 'blog', "Fuente Atom de las publicaciones del blog FreeSewing.org"),
json('es', 'blog', "Fuente JSON de las publicaciones del blog FreeSewing.org"),
rss( 'es', 'blog', "Fuente RSS de las publicaciones del blog FreeSewing.org"),
atom('es', 'showcase', "Fuente Atom de publicaciones de exhibición de FreeSewing.org"),
json('es', 'showcase', "Fuente JSON de publicaciones de exhibición de FreeSewing.org"),
rss( 'es', 'showcase', "Fuente RSS de publicaciones de exhibición de FreeSewing.org"),
],
fr: [
atom('fr', 'blog', "Flux Atom des articles du blog FreeSewing.org"),
json('fr', 'blog', "Flux JSON des articles du blog FreeSewing.org"),
rss( 'fr', 'blog', "Flux RSS des articles du blog FreeSewing.org"),
atom('fr', 'showcase', "Flux Atom des articles du galerie FreeSewing.org"),
json('fr', 'showcase', "Flux JSON des articles du galerie FreeSewing.org"),
rss( 'fr', 'showcase', "Flux RSS des articles du galerie FreeSewing.org"),
],
nl: [
atom('nl', 'blog', "Atom feed van FreeSewing.org blog posts"),
json('nl', 'blog', "JSON feed van FreeSewing.org blog posts"),
rss( 'nl', 'blog', "RSS feed van FreeSewing.org blog posts"),
atom('nl', 'showcase', "Atom feed van FreeSewing.org voorbeelden"),
json('nl', 'showcase', "JSON feed van FreeSewing.org voorbeelden"),
rss( 'nl', 'showcase', "RSS feed van FreeSewing.org voorbeelden"),
],
}
const Feeds = ({ lang='en' }) => (
<Head>
{feeds[lang].map(feed => <link key={feed.href} {...feed} />)}
</Head>
)
export default Feeds

View file

@ -5,25 +5,22 @@ import { useHotkeys } from 'react-hotkeys-hook'
// Layouts components
import LayoutWrapper from 'site/components/wrappers/layout'
import Docs from 'site/components/layouts/docs'
// Add feeds
import Feeds from 'site/components/feeds.js'
// Modal
import Modal from 'shared/components/modal'
/* This component should wrap all page content */
const PageWrapper= ({
title="FIXME: No title set",
noSearch=false,
app=false,
layout=Docs,
crumbs=false,
children=[]
const PageWrapper = ({
title = 'FIXME: No title set',
noSearch = false,
app = false,
layout = Docs,
crumbs = false,
children = [],
}) => {
const swipeHandlers = useSwipeable({
onSwipedLeft: evt => (app.primaryMenu) ? app.setPrimaryMenu(false) : null,
onSwipedRight: evt => (app.primaryMenu) ? null : app.setPrimaryMenu(true),
trackMouse: true
onSwipedLeft: () => (app.primaryMenu ? app.setPrimaryMenu(false) : null),
onSwipedRight: () => (app.primaryMenu ? null : app.setPrimaryMenu(true)),
trackMouse: true,
})
const router = useRouter()
@ -43,7 +40,9 @@ const PageWrapper= ({
app: app,
title: title,
crumbs: crumbs,
search, setSearch, toggleSearch: () => setSearch(!search),
search,
setSearch,
toggleSearch: () => setSearch(!search),
noSearch: noSearch,
}
@ -56,12 +55,8 @@ const PageWrapper= ({
data-theme={app.theme}
key={app.theme} // This forces the data-theme update
>
<Feeds lang={app.locale} />
<LayoutWrapper {...childProps}>
{Layout
? <Layout {...childProps}>{children}</Layout>
: children
}
{Layout ? <Layout {...childProps}>{children}</Layout> : children}
</LayoutWrapper>
{app.popup && <Modal cancel={() => app.setPopup(false)}>{app.popup}</Modal>}
</div>
@ -69,4 +64,3 @@ const PageWrapper= ({
}
export default PageWrapper

View file

@ -1,168 +0,0 @@
import Page from 'site/components/wrappers/page.js'
import useApp from 'site/hooks/useApp.js'
import TimeAgo from 'react-timeago'
import MdxWrapper from 'shared/components/wrappers/mdx'
import mdxCompiler from 'shared/mdx/compiler'
import Head from 'next/head'
import Lightbox from 'shared/components/lightbox.js'
import ImageWrapper from 'shared/components/wrappers/img.js'
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
import { strapiHost } from 'shared/config/freesewing.mjs'
import { strapiImage } from 'shared/utils'
const Author = ({ author }) => (
<div id="author" className="flex flex-col lg:flex-row m-auto p-2 items-center">
<div className="theme-gradient w-40 h-40 p-2 rounded-full aspect-square hidden lg:block">
<div
className={`
w-lg bg-cover bg-center rounded-full aspect-square
hidden lg:block
`}
style={{backgroundImage: `url(${strapiHost}${author?.image?.sizes?.small?.url})`}}
>
</div>
</div>
<div className="theme-gradient p-2 rounded-full aspect-square w-40 h-40 lg:hidden m-auto">
<img
className={`block w-full h-full mx-auto rounded-full`}
src={`${strapiHost}${author?.image?.sizes.small.url}`}
alt={author?.displayname}
width={author?.image?.sizes.small.w}
height={author?.image?.sizes.small.h}
/>
</div>
<div className={`
text-center p-2 px-4 rounded-r-lg bg-opacity-50
lg:text-left
`}
>
<p className="text-xl">
<span className="font-semibold"> {author?.displayname}</span>
<span className="text-sm pl-2 opacity-70">Wrote this</span>
</p>
<div className="prose mdx">
<MdxWrapper mdx={author?.mdx} />
</div>
</div>
</div>
)
const PostPage = ({ post, author }) => {
const app = useApp()
return (
<Page app={app} title={post.title}>
<Head>
<meta property="og:title" content={post.title} key="title" />
<meta property="og:type" content="article" key='type' />
<meta property="og:description" content={post.intro || post.title} key='description' />
<meta property="og:article:author" content={author.displayname} key='author' />
<meta property="og:url" content={`https://freesewing.dev/blog/${post.slug}`} key='url' />
<meta property="og:image" content={`https://canary.backend.freesewing.org/og-img/en/dev/blog/${post.slug}`} key='image' />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:locale" content="en_US" key='locale' />
<meta property="og:site_name" content="freesewing.dev" key='site' />
</Head>
<article className="mb-12">
<div className="flex flex-row justify-between text-sm mb-1 mt-2">
<span><TimeAgo date={post.date} /> [{post.date}]</span>
<span>
By <a
href="#author"
className="text-secondary hover:text-secondary-focus"
>
{author.displayname || 'FIXME: No displayname'}
</a>
</span>
</div>
<figure>
<Lightbox>
<ImageWrapper>
<img
src={`${strapiHost}${post.image.url}`}
alt={post.caption}
className="shadow m-auto"
/>
</ImageWrapper>
<figcaption
className="text-center mb-8 prose m-auto mt-1"
dangerouslySetInnerHTML={{__html: post.caption}}
/>
</Lightbox>
</figure>
<div className="strapi prose lg:prose-lg mb-12 m-auto">
<MdxWrapper mdx={post.mdx} app={app} />
</div>
<div className="max-w-prose text-lg lg:text-xl">
<Author author={author} />
</div>
</article>
</Page>
)
}
/*
* getStaticProps() is used to fetch data at build-time.
*
* On this page, it is loading the blog content from strapi.
*
* This, in combination with getStaticPaths() below means this
* page will be used to render/generate all blog content.
*
* To learn more, see: https://nextjs.org/docs/basic-features/data-fetching
*/
export async function getStaticProps({ params, locale }) {
const { slug } = params
const post = await fetch(
`${strapiHost}/blogposts?_locale=${locale}&dev_ne=true&slug_eq=${slug}`
)
.then(response => response.json())
.then(data => data[0])
.catch(err => console.log(err))
return {
props: {
post: {
slug,
...(await mdxCompiler(post.body)),
title: post.title,
date: post.date,
caption: post.caption,
image: {
w: post.image.width,
h: post.image.height,
url: post.image.url
},
},
author: {
displayname: post.author.displayname,
slug: post.author.slug,
about: post.author.about,
image: strapiImage(post.author.picture, ['small']),
...(await mdxCompiler(post.author.about)),
},
...(await serverSideTranslations(locale)),
}
}
}
export const getStaticPaths = async () => {
const paths = await fetch(
`${strapiHost}/blogposts?_locale=en&dev_ne=true&_limit=-1`
)
.then(response => response.json())
.then(data => data.map(post => `/blog/${post.slug}`))
.catch(err => console.log(err))
return {
paths: [ ...paths ],
fallback: false,
}
}
export default PostPage

View file

@ -1,107 +0,0 @@
import Page from 'site/components/wrappers/page.js'
import useApp from 'site/hooks/useApp.js'
import Link from 'next/link'
import TimeAgo from 'react-timeago'
import { strapiHost } from 'shared/config/freesewing.mjs'
import { strapiImage } from 'shared/utils'
import { useTranslation } from 'next-i18next'
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
const strapi = "https://posts.freesewing.org"
const textShadow = {
style: {
textShadow: "1px 1px 1px #000000, -1px -1px 1px #000000, 1px -1px 1px #000000, -1px 1px 1px #000000, 2px 2px 1px #000000"
}
}
const Preview = ({ app, post }) => (
<div className="shadow rounded-lg">
<Link href={`/blog/${post.slug}`}>
<a title={post.title} className="hover:underline">
<div className="bg-base-100 w-full aspect-video shadow flex flex-column items-end rounded-lg" style={{
backgroundImage: `url(${strapi}${post.image.sizes.medium.url})`,
backgroundSize: 'cover',
}}>
<div className="grow"></div>
<div className="text-right mb-3 lg:mb-8">
<div className={`
bg-neutral text-neutral-content bg-opacity-40 text-right
px-4 py-1
lg:px-8 lg:py-4
`}>
<h5 className={`
text-neutral-content
text-xl font-bold
md:text-2xl md:font-normal
xl:text-3xl
`} {...textShadow}
>
{post.title}
</h5>
<p className={`
hidden md:block
m-0 p-1 -mt-2
text-neutral-content
leading-normal text-sm font-normal
opacity-70
`}{ ...textShadow}>
<TimeAgo date={post.date} /> by <strong>{post.author}</strong>
</p>
</div>
</div>
</div>
</a>
</Link>
</div>
)
const BlogIndexPage = (props) => {
const app = useApp()
const { t } = useTranslation()
return (
<Page app={app} title={t('blog')} slug='blog'>
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2 max-w-7xl">
{props.posts.map(post => <Preview app={app} post={post} key={post.slug}/>)
}
</div>
</Page>
)
}
export default BlogIndexPage
/*
* getStaticProps() is used to fetch data at build-time.
*
* On this page, it is loading the blog content from strapi.
*
* This, in combination with getStaticPaths() below means this
* page will be used to render/generate all blog content.
*
* To learn more, see: https://nextjs.org/docs/basic-features/data-fetching
*/
export async function getStaticProps({ params, locale }) {
const posts = await fetch(
`${strapiHost}/blogposts?_locale=en&_sort=date:DESC&dev_eq=true`
)
.then(response => response.json())
.then(data => data)
.catch(err => console.log(err))
return {
props: {
posts: posts.map(post => ({
slug: post.slug,
title: post.title,
date: post.date,
author: post.author.displayname,
image: strapiImage(post.image, ['medium']),
})),
...(await serverSideTranslations(locale)),
}
}
}

View file

@ -22,7 +22,6 @@ import remarkRehype from 'remark-rehype'
import rehypeSanitize from 'rehype-sanitize'
import rehypeStringify from 'rehype-stringify'
import yaml from 'yaml'
import { getPosts } from '../../shared/prebuild/strapi.mjs'
import { getMdxFileList } from '../../shared/prebuild/mdx.mjs'
import config from '../algolia.config.mjs'
dotenv.config()
@ -30,70 +29,13 @@ dotenv.config()
/*
* Initialize Algolia client
*/
const client = algoliasearch(
config.algolia.app,
process.env.ALGOLIA_API_WRITE_KEY
)
const client = algoliasearch(config.algolia.app, process.env.ALGOLIA_API_WRITE_KEY)
const index = client.initIndex(config.algolia.index)
/*
* Turn a Strapi blog post into an object ready for indexing
*/
const transformBlogpost = post => ({
objectID: `/blog/${post.slug}`,
page: `/blog/${post.slug}`,
title: post.title,
date: post.date,
slug: post.slug,
body: post.body,
author: post.author,
caption: post.caption,
type: 'blog',
})
/*
* Turn a Strapi author into an object ready for indexing
*/
const transformAuthor = author => ({
objectID: `/blog/authors/${author.name}`,
page: `/blog/authors/${author.name}`,
name: author.name,
displayname: author.displayname,
about: author.about,
})
/*
* Get and index blog posts and author info from Strapi
*/
const indexStrapiContent = async () => {
// Say hi
console.log(`🗂️ Indexing Strapi content to Algolia`)
const authors = {}
const rawPosts = await getPosts('blog', 'dev', 'en')
// Extract list of authors
for (const [slug, post] of Object.entries(rawPosts)) {
authors[post.author.slug] = transformAuthor(post.author)
rawPosts[slug].author = post.author.slug
}
// Index posts to Algolia
index
.saveObjects(Object.values(rawPosts).map(post => transformBlogpost(post)))
.then(({ objectIDs }) => null)
.catch(err => console.log(err))
// Index authors to Algolia
index
.saveObjects(Object.values(authors))
.then(({ objectIDs }) => null)
.catch(err => console.log(err))
}
/*
* Loads markdown from disk and compiles it into HTML for indexing
*/
const markdownLoader = async file => {
const markdownLoader = async (file) => {
const md = await fs.promises.readFile(file, 'utf-8')
const page = await unified()
@ -124,12 +66,10 @@ const clearIndex = async () => {
await index.clearObjects()
}
/*
* Get and index markdown content
*/
const indexMarkdownContent = async () => {
// Say hi
console.log(`🗂️ Indexing Markdown content to Algolia`)
@ -145,19 +85,15 @@ const indexMarkdownContent = async () => {
await index.clearObjects()
await index
.saveObjects(pages)
.then(({ objectIDs }) => null)
.catch(err => console.log(err))
.then(() => null)
.catch((err) => console.log(err))
}
const run = async () => {
if (
process.env.VERCEL_ENV === 'production' ||
process.env.FORCE_ALGOLIA
) {
if (process.env.VERCEL_ENV === 'production' || process.env.FORCE_ALGOLIA) {
console.log()
await clearIndex()
await indexMarkdownContent()
await indexStrapiContent()
console.log()
} else {
console.log()
@ -168,4 +104,3 @@ const run = async () => {
}
run()

View file

@ -9,13 +9,15 @@ import { prebuildLab } from './lab.mjs'
const SITE = process.env.SITE || 'lab'
const run = async () => {
if (SITE !== 'lab') {
if (SITE === 'org') {
const mdxPages = await prebuildMdx(SITE)
const [posts, authors] = await prebuildStrapi(SITE)
const [posts] = await prebuildStrapi(SITE)
prebuildNavigation(mdxPages, posts, SITE)
} else {
await prebuildLab()
}
} else if (SITE === 'dev') {
const mdxPages = await prebuildMdx(SITE)
prebuildNavigation(mdxPages, false, SITE)
} else await prebuildLab()
await prebuildI18n(SITE)
await prebuildContributors(SITE)
await prebuildPatrons(SITE)