feat(shared): Add dynamic OG images
This commit is contained in:
parent
d36643d4a8
commit
2472ab1824
22 changed files with 141 additions and 169 deletions
|
@ -28,16 +28,16 @@
|
|||
</g>
|
||||
<g>
|
||||
<text class="gray-300 tiny italic center">
|
||||
<tspan x="100" y="179">intro_1</tspan>
|
||||
<tspan x="100" y="190">intro_2</tspan>
|
||||
<tspan x="100" y="179">__intro_1__</tspan>
|
||||
<tspan x="100" y="190">__intro_2__</tspan>
|
||||
</text>
|
||||
<text class="gray-200 big bold center">
|
||||
<tspan x="100" y="95">1title_1</tspan>
|
||||
<tspan x="100" y="90">2title_1</tspan>
|
||||
<tspan x="100" dy="24">2title_2</tspan>
|
||||
<tspan x="100" y="80">3title_1</tspan>
|
||||
<tspan x="100" dy="24">3title_2</tspan>
|
||||
<tspan x="100" dy="24">3title_3</tspan>
|
||||
<tspan x="100" y="95">__1title_1__</tspan>
|
||||
<tspan x="100" y="90">__2title_1__</tspan>
|
||||
<tspan x="100" dy="24">__2title_2__</tspan>
|
||||
<tspan x="100" y="80">__3title_1__</tspan>
|
||||
<tspan x="100" dy="24">__3title_2__</tspan>
|
||||
<tspan x="100" dy="24">__3title_3__</tspan>
|
||||
</text>
|
||||
<text class="bold" x="6" y="15">
|
||||
<tspan dx="0" fill="#f87171">F</tspan>
|
||||
|
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
title: Motivation
|
||||
title: My reasoning behind FreeSewing's Revenue Pledge
|
||||
---
|
||||
|
||||
<Note>
|
||||
|
@ -9,7 +9,7 @@ his motivations for [the FreeSewing revenue pledge](/docs/about/pledge/)
|
|||
|
||||
</Note>
|
||||
|
||||
You probably assume that we ask for money to keep the servers running. But that's not exactly true.
|
||||
You probably assume that I ask for money to keep the servers running. But that's not exactly true.
|
||||
|
||||
I don't know if you're familiar with the phrase **noblesse oblige** but it essentially means that privilege entails responsibility.
|
||||
|
||||
|
@ -49,7 +49,7 @@ because FreeSewing is a force for good.
|
|||
Here's the tricky part: People give less once they know the money goes to charity.
|
||||
I wish it wasn't the case, but it is.
|
||||
|
||||
So we're presenting [our subscription options](/community/join) like you would see on a for-profit site.
|
||||
So I'm presenting [the subscription options](/patrons/join) like you would see on a for-profit site.
|
||||
It seems more intuitive this way, and also just works better.
|
||||
|
||||
Yes, everything is free, and the money doesn't actually go to paying the server bills
|
||||
|
|
|
@ -28,7 +28,7 @@ ${banner}
|
|||
entryPoints: ['src/index.mjs'],
|
||||
format: 'esm',
|
||||
outfile: 'dist/index.mjs',
|
||||
external: ['./local-config.mjs'],
|
||||
external: ['./local-config.mjs', 'sharp'],
|
||||
metafile: process.env.VERBOSE ? true : false,
|
||||
minify: process.env.NO_MINIFY ? false : true,
|
||||
sourcemap: true,
|
||||
|
|
|
@ -59,7 +59,11 @@ const introAsLines = (intro, type) => {
|
|||
// Does it fit on one line?
|
||||
if (intro.length <= imgConfig.templates.chars[type].intro) return [intro]
|
||||
// Two lines it is
|
||||
return splitLine(intro, imgConfig.templates.chars[type].intro)
|
||||
const lines = splitLine(intro, imgConfig.templates.chars[type].intro)
|
||||
if (lines[1].length > imgConfig.templates.chars[type].intro)
|
||||
lines[1] = lines[1].slice(0, imgConfig.templates.chars[type].intro) + '…'
|
||||
|
||||
return lines
|
||||
}
|
||||
|
||||
/* Hide unused placeholders */
|
||||
|
@ -67,11 +71,11 @@ const hidePlaceholders = (list, type) => {
|
|||
let svg = templates[type]
|
||||
for (const i of list) {
|
||||
svg = svg
|
||||
.replace(`${i}title_1`, '')
|
||||
.replace(`${i}title_2`, '')
|
||||
.replace(`${i}title_3`, '')
|
||||
.replace(`${i}title_4`, '')
|
||||
.replace(`${i}title_5`, '')
|
||||
.replace(`__${i}title_1__`, '')
|
||||
.replace(`__${i}title_2__`, '')
|
||||
.replace(`__${i}title_3__`, '')
|
||||
.replace(`__${i}title_4__`, '')
|
||||
.replace(`__${i}title_5__`, '')
|
||||
}
|
||||
|
||||
return svg
|
||||
|
@ -82,61 +86,70 @@ const decorateSvg = (data) => {
|
|||
let svg
|
||||
// Single title line
|
||||
if (data.title.length === 1) {
|
||||
svg = hidePlaceholders([2, 3, 4, 5], data.type).replace(`1title_1`, data.title[0])
|
||||
svg = hidePlaceholders([2, 3, 4, 5], data.type).replace(`__1title_1__`, data.title[0])
|
||||
}
|
||||
// Double title line
|
||||
else if (data.title.length === 2) {
|
||||
svg = hidePlaceholders([1, 3, 4, 5], data.type)
|
||||
.replace(`2title_1`, data.title[0])
|
||||
.replace(`2title_2`, data.title[1])
|
||||
.replace(`__2title_1__`, data.title[0])
|
||||
.replace(`__2title_2__`, data.title[1])
|
||||
}
|
||||
// Triple title line
|
||||
else if (data.title.length === 3) {
|
||||
svg = hidePlaceholders([1, 2, 4, 5], data.type)
|
||||
.replace(`3title_1`, data.title[0])
|
||||
.replace(`3title_2`, data.title[1])
|
||||
.replace(`3title_3`, data.title[2])
|
||||
.replace(`__3title_1__`, data.title[0])
|
||||
.replace(`__3title_2__`, data.title[1])
|
||||
.replace(`__3title_3__`, data.title[2])
|
||||
}
|
||||
// Quadruple title line
|
||||
else if (data.title.length === 4) {
|
||||
svg = hidePlaceholders([1, 2, 3, 5], data.type)
|
||||
.replace(`4title_1`, data.title[0])
|
||||
.replace(`4title_2`, data.title[1])
|
||||
.replace(`4title_3`, data.title[2])
|
||||
.replace(`4title_4`, data.title[3])
|
||||
.replace(`__4title_1__`, data.title[0])
|
||||
.replace(`__4title_2__`, data.title[1])
|
||||
.replace(`__4title_3__`, data.title[2])
|
||||
.replace(`__4title_4__`, data.title[3])
|
||||
}
|
||||
// Quintuple title line
|
||||
else if (data.title.length === 5) {
|
||||
svg = hidePlaceholders([1, 2, 3, 4], data.type)
|
||||
.replace(`5title_1`, data.title[0])
|
||||
.replace(`5title_2`, data.title[1])
|
||||
.replace(`5title_3`, data.title[2])
|
||||
.replace(`5title_4`, data.title[3])
|
||||
.replace(`5title_5`, data.title[4])
|
||||
.replace(`__5title_1__`, data.title[0])
|
||||
.replace(`__5title_2__`, data.title[1])
|
||||
.replace(`__5title_3__`, data.title[2])
|
||||
.replace(`__5title_4__`, data.title[3])
|
||||
.replace(`__5title_5__`, data.title[4])
|
||||
}
|
||||
|
||||
return svg
|
||||
.replace(`intro_1`, data.intro[0] || '')
|
||||
.replace(`intro_2`, data.intro[1] || '')
|
||||
.replace('site', data.site || '')
|
||||
.replace(`__intro_1__`, data.intro[0] || '')
|
||||
.replace(`__intro_2__`, data.intro[1] || '')
|
||||
.replace('__site__', data.site || '')
|
||||
}
|
||||
|
||||
export function ImgController() {}
|
||||
|
||||
const parseInput = (req) => {
|
||||
let input = {}
|
||||
if (req.params.data) {
|
||||
try {
|
||||
input = JSON.parse(decodeURIComponent(req.params.data))
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
} else input = req.body
|
||||
|
||||
return input
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate an Open Graph image
|
||||
* See: https://freesewing.dev/reference/backend/api
|
||||
*/
|
||||
ImgController.prototype.generate = async (req, res) => {
|
||||
const input = parseInput(req)
|
||||
/*
|
||||
* Extract body parameters
|
||||
*/
|
||||
const {
|
||||
site = false,
|
||||
title = 'Please provide a title',
|
||||
intro = 'Please provide an intro',
|
||||
type = 'wide',
|
||||
} = req.body
|
||||
const { site = false, title = '', intro = '', type = 'wide' } = input
|
||||
if (site && imgConfig.sites.indexOf(site) === -1)
|
||||
return res.status(400).send({ error: 'invalidSite' })
|
||||
|
||||
|
|
|
@ -7,4 +7,7 @@ export function imgRoutes(tools) {
|
|||
|
||||
// Generate an image
|
||||
app.post('/img', (req, res) => Img.generate(req, res, tools))
|
||||
|
||||
// Generate an image
|
||||
app.get('/img/:data', (req, res) => Img.generate(req, res, tools))
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Components
|
||||
import Head from 'next/head'
|
||||
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
|
||||
import { Robot } from 'shared/components/robot/index.mjs'
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
|
@ -12,23 +11,7 @@ import { NavLinks, MainSections } from 'shared/components/navigation/sitenav.mjs
|
|||
const namespaces = [...pageNs]
|
||||
|
||||
const Page404 = () => (
|
||||
<PageWrapper title="404: Page not found">
|
||||
<Head>
|
||||
<meta property="og:type" content="article" key="type" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="There's nothing here. If you followed a link to get here, that link is broken"
|
||||
key="description"
|
||||
/>
|
||||
<meta property="og:article:author" content="Joost De Cock" key="author" />
|
||||
<meta property="og:image" content={`https://freesewing.dev/og/404/og.png`} 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:url" content={`https://freesewing.dev/`} key="url" />
|
||||
<meta property="og:locale" content="en_US" key="locale" />
|
||||
<meta property="og:site_name" content="freesewing.dev" key="site" />
|
||||
</Head>
|
||||
<PageWrapper title="404: Page not found" intro="We could not find what you are looking for">
|
||||
<BaseLayout>
|
||||
<BaseLayoutLeft>
|
||||
<MainSections />
|
||||
|
|
|
@ -3,8 +3,8 @@ import { pages } from 'site/prebuild/docs.en.mjs'
|
|||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import { loadMdxAsStaticProps } from 'shared/mdx/load.mjs'
|
||||
import { freeSewingConfig as config } from 'shared/config/freesewing.config.mjs'
|
||||
// Components
|
||||
import Head from 'next/head'
|
||||
import { PageWrapper, ns } from 'shared/components/wrappers/page.mjs'
|
||||
//import { components } from 'shared/components/mdx/index.mjs'
|
||||
import { MdxWrapper } from 'shared/components/wrappers/mdx.mjs'
|
||||
|
@ -27,24 +27,6 @@ import {
|
|||
*/
|
||||
const DocsPage = ({ page, slug, frontmatter, mdx, mdxSlug }) => (
|
||||
<PageWrapper {...page} title={frontmatter.title} intro={frontmatter.intro}>
|
||||
<Head>
|
||||
<meta property="og:title" content={frontmatter.title} key="title" />
|
||||
<meta property="og:type" content="article" key="type" />
|
||||
<meta property="og:description" content={frontmatter.intro} key="type" />
|
||||
<meta property="og:article:author" content="Joost De Cock" key="author" />
|
||||
<meta
|
||||
property="og:image"
|
||||
content={`https://canary.backend.freesewing.org/og-img/en/org/${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:url" content={`https://freesewing.dev/${slug}`} key="url" />
|
||||
<meta property="og:locale" content="en" key="locale" />
|
||||
<meta property="og:site_name" content="freesewing.dev" key="site" />
|
||||
<title>{frontmatter.title}</title>
|
||||
</Head>
|
||||
<BaseLayout>
|
||||
<BaseLayoutLeft>
|
||||
<MainSections />
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Components
|
||||
import Head from 'next/head'
|
||||
import { PageWrapper } from 'shared/components/wrappers/page.mjs'
|
||||
import { PageLink } from 'shared/components/link.mjs'
|
||||
import { Highlight } from 'shared/components/mdx/highlight.mjs'
|
||||
|
@ -28,25 +27,11 @@ const Card = ({ bg = 'bg-base-200', textColor = 'text-base-content', title, chil
|
|||
* or set them manually.
|
||||
*/
|
||||
const HomePage = ({ page }) => (
|
||||
<PageWrapper {...page}>
|
||||
<Head>
|
||||
<meta property="og:type" content="article" key="type" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Documentation and tutorials for FreeSewing developers and contributors"
|
||||
key="description"
|
||||
/>
|
||||
<meta property="og:article:author" content="Joost De Cock" key="author" />
|
||||
<meta property="og:image" content="https://freesewing.dev/og/og.png" 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:url" content="https://freesewing.dev/" key="url" />
|
||||
<meta property="og:locale" content="en_US" key="locale" />
|
||||
<meta property="og:site_name" content="freesewing.dev" key="site" />
|
||||
<title>{title}</title>
|
||||
</Head>
|
||||
|
||||
<PageWrapper
|
||||
{...page}
|
||||
title="FreeSewing.dev"
|
||||
intro="Documentation and tutorials for FreeSewing developers and contributors"
|
||||
>
|
||||
<div className="max-w-7xl m-auto px-0 mt-24 px-4">
|
||||
<FreeSewingIcon className="h-36 w-36 m-auto" />
|
||||
<h1 className="text-center font-heavy drop-shadow-md px-4">
|
||||
|
|
|
@ -25,7 +25,7 @@ const SearchPage = ({ page }) => {
|
|||
)
|
||||
|
||||
return (
|
||||
<PageWrapper {...page}>
|
||||
<PageWrapper {...page} title="Search" intro="Use the FreeSewing.dev site search">
|
||||
<BaseLayout>
|
||||
<BaseLayoutLeft>
|
||||
<MainSections />
|
||||
|
|
|
@ -75,7 +75,7 @@ prebuildRunner({
|
|||
* Only prebuild the Open Graph (og) images in production
|
||||
* Will be skipped in development mode to save time
|
||||
*/
|
||||
ogImages: true, //'productionOnly',
|
||||
ogImages: false, // We currently don't prebuild these images
|
||||
|
||||
/*
|
||||
* Only prebuild the patron info in production
|
||||
|
|
|
@ -3,7 +3,6 @@ import { nsMerge } from 'shared/utils.mjs'
|
|||
// Hooks
|
||||
import { useContext } from 'react'
|
||||
// Components
|
||||
import Head from 'next/head'
|
||||
import {
|
||||
BaseLayout,
|
||||
BaseLayoutLeft,
|
||||
|
@ -22,37 +21,11 @@ import { PrevNext } from 'shared/components/prev-next.mjs'
|
|||
|
||||
export const ns = nsMerge(navNs, 'docs', metaNs)
|
||||
|
||||
export const FrontmatterHead = ({ frontmatter, slug, locale }) => (
|
||||
<Head>
|
||||
<meta property="og:title" content={frontmatter.title} key="title" />
|
||||
<meta property="og:type" content="article" key="type" />
|
||||
<meta property="og:description" content={frontmatter.intro || frontmatter.title} key="type" />
|
||||
<meta
|
||||
property="og:article:author"
|
||||
content={frontmatter.author || frontmatter.maker || 'Joost De Cock'}
|
||||
key="author"
|
||||
/>
|
||||
<meta
|
||||
property="og:image"
|
||||
content={`https://canary.backend.freesewing.org/og-img/en/org/${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:url" content={`https://freesewing.org/${slug}`} key="url" />
|
||||
<meta property="og:locale" content={locale || 'en'} key="locale" />
|
||||
<meta property="og:site_name" content="freesewing.org" key="site" />
|
||||
<title>{frontmatter.title + '- FreeSewing.org'}</title>
|
||||
</Head>
|
||||
)
|
||||
|
||||
export const DocsLayout = ({ children = [], frontmatter }) => {
|
||||
const { slug, locale } = useContext(NavigationContext)
|
||||
|
||||
return (
|
||||
<>
|
||||
<FrontmatterHead {...{ frontmatter, slug, locale }} />
|
||||
<BaseLayout>
|
||||
<BaseLayoutLeft>
|
||||
<MainSections />
|
||||
|
|
|
@ -5,7 +5,6 @@ import { Lightbox } from 'shared/components/lightbox.mjs'
|
|||
import { ImageWrapper } from 'shared/components/wrappers/img.mjs'
|
||||
import { TimeAgo, ns as timeagoNs } from 'shared/components/timeago/index.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { FrontmatterHead } from './docs.mjs'
|
||||
import {
|
||||
BaseLayout,
|
||||
BaseLayoutLeft,
|
||||
|
@ -81,7 +80,6 @@ export const PostLayout = ({ mdx, slug, frontmatter, locale, type, dir }) => {
|
|||
|
||||
return (
|
||||
<BaseLayout>
|
||||
<FrontmatterHead {...{ frontmatter, slug, locale }} />
|
||||
<BaseLayoutLeft>
|
||||
<MainSections />
|
||||
<NavLinks />
|
||||
|
|
|
@ -11,6 +11,7 @@ const BlogPage = ({ dir, page, mdx, frontmatter }) => {
|
|||
return (
|
||||
<PageWrapper
|
||||
{...page}
|
||||
intro={frontmatter.intro}
|
||||
title={frontmatter.title}
|
||||
layout={(props) => (
|
||||
<PostLayout
|
||||
|
|
|
@ -58,12 +58,13 @@ const HomePage = ({ page }) => {
|
|||
}, [account.username])
|
||||
|
||||
return (
|
||||
<PageWrapper {...page} layout={BareLayout}>
|
||||
<PageWrapper
|
||||
{...page}
|
||||
layout={BareLayout}
|
||||
title="FreeSewing.org"
|
||||
intro={t('homepage:freePatterns')}
|
||||
>
|
||||
<ForceAccountCheck />
|
||||
<Head>
|
||||
<title>FreeSewing.org</title>
|
||||
</Head>
|
||||
|
||||
<div className="text-center w-full m-auto">
|
||||
<FreeSewingIcon className="w-36 h-36 mt-0 lg:mt-8 lg:w-56 lg:h-=56 mt-4 m-auto pr-6" />
|
||||
<h1 className="font-bold -mt-8 lg:-mt-4" style={{ letterSpacing: '-0.1rem' }}>
|
||||
|
|
|
@ -12,6 +12,7 @@ const ShowcasePage = ({ dir, page, mdx, frontmatter }) => {
|
|||
<PageWrapper
|
||||
{...page}
|
||||
title={frontmatter.title}
|
||||
intro={frontmatter.intro}
|
||||
layout={(props) => (
|
||||
<PostLayout
|
||||
{...props}
|
||||
|
|
|
@ -36,7 +36,7 @@ const ShowcaseIndexPage = ({ page }) => {
|
|||
: Object.keys(posts[page.locale])
|
||||
|
||||
return (
|
||||
<PageWrapper {...page} layout={BareLayout}>
|
||||
<PageWrapper {...page} title={t('sections:showcase')} layout={BareLayout}>
|
||||
<div className="p-4 m-auto">
|
||||
<h1 className="text-center">FreeSewing - {t('sections:showcase')}</h1>
|
||||
<div className="max-w-7xl m-auto">
|
||||
|
|
|
@ -85,7 +85,7 @@ prebuildRunner({
|
|||
* Only prebuild the Open Graph (og) images in production
|
||||
* Will be skipped in development mode to save time
|
||||
*/
|
||||
ogImages: 'productionOnly',
|
||||
ogImages: false, // We do not currently prebuild these
|
||||
|
||||
/*
|
||||
* Only prebuild the patron info in production
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
// __SDEFILE__ - This file is a dependency for the stand-alone environment
|
||||
// Dependencies
|
||||
import React, { useState, useEffect, useContext } from 'react'
|
||||
import { nsMerge } from 'shared/utils.mjs'
|
||||
import { ogUrl, nsMerge } from 'shared/utils.mjs'
|
||||
import { siteConfig } from 'site/site.config.mjs'
|
||||
// Context
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
// Hooks
|
||||
|
@ -21,7 +22,14 @@ export const PageWrapper = (props) => {
|
|||
/*
|
||||
* Deconstruct props
|
||||
*/
|
||||
const { layout = DefaultLayout, footer = true, header = true, children = [], path = [] } = props
|
||||
const {
|
||||
layout = DefaultLayout,
|
||||
footer = true,
|
||||
header = true,
|
||||
locale = 'en',
|
||||
children = [],
|
||||
path = [],
|
||||
} = props
|
||||
// Title is typically set in props.t but check props.title too
|
||||
const pageTitle = props.t ? props.t : props.title ? props.title : null
|
||||
|
||||
|
@ -60,6 +68,25 @@ export const PageWrapper = (props) => {
|
|||
{props.intro && (
|
||||
<meta property="og:description" content={props.intro} key="description" />
|
||||
)}
|
||||
<meta property="og:title" content={pageTitle} key="title" />
|
||||
<meta property="og:type" content="article" key="type" />
|
||||
<meta property="og:article:author" content="Joost De Cock" key="author" />
|
||||
<meta
|
||||
property="og:image"
|
||||
content={`${ogUrl({ site: siteConfig.tld, title: pageTitle, intro: props.intro })}`}
|
||||
key="image"
|
||||
/>
|
||||
<meta property="og:image:type" content="image/png" />
|
||||
<meta property="og:image:width" content="2400" />
|
||||
<meta property="og:image:height" content="1260" />
|
||||
<meta
|
||||
property="og:url"
|
||||
content={`https://FreeSewing.${siteConfig.tld}/${path.join('/')}`}
|
||||
key="url"
|
||||
/>
|
||||
<meta property="og:locale" content={locale} key="locale" />
|
||||
<meta property="og:site_name" content={`FreeSewing.${siteConfig.tld}`} key="site" />
|
||||
<title>{pageTitle}</title>
|
||||
</Head>
|
||||
)}
|
||||
<div
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import axios from 'axios'
|
||||
import { freeSewingConfig as config } from '../config/freesewing.config.mjs'
|
||||
import { slugToOgImg } from '../utils.mjs'
|
||||
import get from 'lodash.get'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
const slugToImg = (slug, language) => `${language}_${slug.split('/').join('_')}.png`
|
||||
|
||||
export const generateImage = async ({ title, intro, site, slug, language }) => {
|
||||
let result
|
||||
try {
|
||||
|
@ -14,7 +13,7 @@ export const generateImage = async ({ title, intro, site, slug, language }) => {
|
|||
{ title, intro, site, type: 'wide' },
|
||||
{ responseType: 'arraybuffer' }
|
||||
)
|
||||
const file = path.resolve('..', site, 'public', 'img', 'og', slugToImg(slug, language))
|
||||
const file = path.resolve('..', site, 'public', 'img', 'og', slugToOgImg(slug, language))
|
||||
await fs.promises.writeFile(file, result.data)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
|
|
|
@ -7,6 +7,7 @@ import orderBy from 'lodash.orderby'
|
|||
import unset from 'lodash.unset'
|
||||
import { cloudflareConfig } from './config/cloudflare.mjs'
|
||||
import { mergeOptions } from '@freesewing/core'
|
||||
import { freeSewingConfig as config } from './config/freesewing.config.mjs'
|
||||
|
||||
const slugifyConfig = {
|
||||
replacement: '-', // replace spaces with replacement character, defaults to `-`
|
||||
|
@ -491,3 +492,8 @@ export const workbenchHash = ({ settings = {}, view = 'draft' }) =>
|
|||
|
||||
export const getSearchParam = (name = 'id') =>
|
||||
typeof window === 'undefined' ? undefined : new URLSearchParams(window.location.search).get(name)
|
||||
|
||||
export const slugToOgImg = (slug, language) => `${language}_${slug.split('/').join('_')}.png`
|
||||
|
||||
export const ogUrl = ({ site = false, title, intro }) =>
|
||||
`${config.backend}/img/${encodeURIComponent(JSON.stringify({ site, title, intro }))}`
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue