Merge pull request #29 from tmshv/fix/opengraph-update

OpenGraph update
This commit is contained in:
tmshv authored and GitHub committed 2020-02-25 02:32:02 +03:00
commit ad2c0367d0
11 files changed
+222 -134

No files matched your search

+14 -16
View File
@@ -3,8 +3,8 @@ import { App } from 'src/components/App'
import { tail } from 'lodash' import { tail } from 'lodash'
import { Page } from 'src/components/Page' import { Page } from 'src/components/Page'
import { Meta } from 'src/components/Meta' import { Meta } from 'src/components/Meta'
import { meta } from 'src/lib/meta' import { MetaBuilder } from 'src/lib/meta'
import { createApiUrl, requestGet, wrapInitialProps, IResponseItems } from 'src/next-lib' import { createApiUrl, requestGet, IResponseItems } from 'src/next-lib'
import { NextPage } from 'next' import { NextPage } from 'next'
import { IBreadcumbsPart, IMeta, IPage } from 'src/types' import { IBreadcumbsPart, IMeta, IPage } from 'src/types'
@@ -15,11 +15,10 @@ function array<T>(value: T | T[]) {
} }
type Props = { type Props = {
page: any
title: string title: string
content: string content: string
breadcrumb: IBreadcumbsPart[] breadcrumb: IBreadcumbsPart[]
meta: IMeta meta?: IMeta
} }
const Index: NextPage<Props> = props => ( const Index: NextPage<Props> = props => (
@@ -32,7 +31,9 @@ const Index: NextPage<Props> = props => (
> >
<Head> <Head>
<title>{props.title}</title> <title>{props.title}</title>
{/* <Meta meta={props.meta} /> */} {!props.meta ? null : (
<Meta meta={props.meta} />
)}
</Head> </Head>
<Page <Page
@@ -54,29 +55,26 @@ export const unstable_getStaticProps = async (ctx: any) => {
if (!page) { if (!page) {
throw new Error(`Not found: ${slug}`) throw new Error(`Not found: ${slug}`)
} }
const image = page.preview ? page.preview.artifacts.fb : {} const description = page.description ?? undefined
const breadcrumbSize = page.breadcrumb?.length ?? 0 const breadcrumbSize = page?.breadcrumb?.length ?? 0
const breadcrumb = breadcrumbSize < 2 ? null : page.breadcrumb const breadcrumb = breadcrumbSize < 2 ? null : page.breadcrumb
const meta = (new MetaBuilder())
.setImage(page.preview)
.setTitle(page.title)
.setDescription(description)
.build()
return { return {
props: { props: {
page,
content: page.data, content: page.data,
title: page.title, title: page.title,
meta: meta({ meta,
title: page.title,
image: image.src,
imageWidth: image.width,
imageHeight: image.height,
}),
breadcrumb, breadcrumb,
} }
} }
} }
export const unstable_getStaticPaths = async () => { export const unstable_getStaticPaths = async () => {
console.log('call all unstable_getStaticPaths')
const urls = await requestGet<IResponseItems<string>>(createApiUrl(`/api/pages/urls`), null) const urls = await requestGet<IResponseItems<string>>(createApiUrl(`/api/pages/urls`), null)
if (!urls) { if (!urls) {
return null return null
+13 -17
View File
@@ -1,16 +1,16 @@
import Head from 'next/head' import Head from 'next/head'
import { get } from 'lodash'
import { App } from 'src/components/App' import { App } from 'src/components/App'
import { Article } from 'src/components/Article' import { Article } from 'src/components/Article'
import { Html } from 'src/components/Html' import { Html } from 'src/components/Html'
import { Meta } from 'src/components/Meta' import { Meta } from 'src/components/Meta'
import { meta } from 'src/lib/meta' import { MetaBuilder } from 'src/lib/meta'
import { createApiUrl, requestGet, IResponseItems } from 'src/next-lib' import { createApiUrl, requestGet, IResponseItems } from 'src/next-lib'
import { NextPage } from 'next' import { NextPage } from 'next'
import { IArticle } from 'src/types' import { IArticle, IMeta } from 'src/types'
type Props = { type Props = {
meta: any title: string
meta: IMeta
data: IArticle data: IArticle
} }
@@ -25,11 +25,11 @@ const Page: NextPage<Props> = props => {
showAuthor={true} showAuthor={true}
> >
<Head> <Head>
<title>{props.data.title}</title> <title>{props.title}</title>
<Meta meta={props.meta} /> <Meta meta={props.meta} />
</Head> </Head>
<Article <Article
title={props.data.title} title={props.title}
date={props.data.date} date={props.data.date}
tags={props.data.tags} tags={props.data.tags}
shareable={true} shareable={true}
@@ -43,31 +43,27 @@ const Page: NextPage<Props> = props => {
} }
export const unstable_getStaticProps = async (ctx: any) => { export const unstable_getStaticProps = async (ctx: any) => {
const pageUrl = '/'
const id = ctx.params.slug const id = ctx.params.slug
const data = await requestGet(createApiUrl(`/api/articles/${id}`), null) const data = await requestGet<IArticle>(createApiUrl(`/api/articles/${id}`), null)
if (!data) { if (!data) {
return null return null
} }
const image = get(data, 'preview.artifacts.fb', {}) const meta = (new MetaBuilder())
.setImage(data.preview)
.setTitle(data.title)
.build()
return { return {
props: { props: {
title: data.title,
data, data,
meta: meta({ meta,
title: data.title,
image: image.src,
imageWidth: image.width,
imageHeight: image.height,
}),
} }
} }
} }
export const unstable_getStaticPaths = async () => { export const unstable_getStaticPaths = async () => {
console.log('call article unstable_getStaticPaths')
const urls = await requestGet<IResponseItems<string>>(createApiUrl(`/api/articles/urls`), null) const urls = await requestGet<IResponseItems<string>>(createApiUrl(`/api/articles/urls`), null)
if (!urls) { if (!urls) {
return null return null
+11 -15
View File
@@ -2,17 +2,18 @@ import Head from 'next/head'
import { range } from 'lodash' import { range } from 'lodash'
import { App } from 'src/components/App' import { App } from 'src/components/App'
import { ArticleGrid } from 'src/components/ArticleGrid' import { ArticleGrid } from 'src/components/ArticleGrid'
import { meta } from 'src/lib/meta' import { MetaBuilder } from 'src/lib/meta'
import { Meta } from 'src/components/Meta' import { Meta } from 'src/components/Meta'
import { createApiUrl, requestGet, IResponseItems } from 'src/next-lib' import { createApiUrl, requestGet, IResponseItems } from 'src/next-lib'
import { NextPage } from 'next' import { NextPage } from 'next'
import { IArticle } from 'src/types'
const pageSize = Number(process.env.APP_ARTICLES_PAGE_SIZE) const pageSize = Number(process.env.APP_ARTICLES_PAGE_SIZE)
type Props = { type Props = {
meta: any meta: any
title: string title: string
data: any //(list of article) data: IArticle[]
nextPage: number nextPage: number
prevPage: number prevPage: number
} }
@@ -42,20 +43,19 @@ const Page: NextPage<Props> = props => {
} }
export const unstable_getStaticProps = async (ctx: any) => { export const unstable_getStaticProps = async (ctx: any) => {
// const page = parseInt(ctx.query.page)
const page = parseInt(ctx.params.slug) const page = parseInt(ctx.params.slug)
const res = await requestGet<IResponseItems<any[]>>( const res = await requestGet<IResponseItems<IArticle>>(createApiUrl(`/api/articles?page=${page}&pageSize=${pageSize}`), null)
createApiUrl(`/api/articles?page=${page}&pageSize=${pageSize}`),
null
)
if (!res) { if (!res) {
return null return null
} }
const data = res.items || [] const data = (res.items || [])
const nextPage = (res as any).nextPage const nextPage = res.nextPage
const prevPage = (res as any).prevPage const prevPage = res.prevPage
const title = 'События' const title = 'События'
const meta = (new MetaBuilder())
.setTitle(title)
.build()
return { return {
props: { props: {
@@ -63,16 +63,12 @@ export const unstable_getStaticProps = async (ctx: any) => {
nextPage, nextPage,
prevPage, prevPage,
title, title,
meta: meta({ meta,
title,
})
} }
} }
} }
export const unstable_getStaticPaths = async () => { export const unstable_getStaticPaths = async () => {
console.log('call articles unstable_getStaticPaths')
const urls = await requestGet<IResponseItems<string>>(createApiUrl(`/api/articles/urls`), null) const urls = await requestGet<IResponseItems<string>>(createApiUrl(`/api/articles/urls`), null)
if (!urls) { if (!urls) {
return null return null
+39 -24
View File
@@ -4,24 +4,27 @@ import { App } from 'src/components/App'
import { Meta } from 'src/components/Meta' import { Meta } from 'src/components/Meta'
import { CollectiveImage } from 'src/components/CollectiveImage' import { CollectiveImage } from 'src/components/CollectiveImage'
import { meta } from 'src/lib/meta' import { meta } from 'src/lib/meta'
import { IMeta, IImage } from 'src/types' import { IMeta, Person } from 'src/types'
import { createApiUrl, requestGet, IResponseItems } from 'src/next-lib' import { createApiUrl, requestGet, IResponseItems } from 'src/next-lib'
import { NextPage, NextPageContext } from 'next' import { NextPage, NextPageContext } from 'next'
import { CardGrid } from 'src/components/CardGrid' import { CardGrid } from 'src/components/CardGrid'
import { Card } from 'src/components/Card' import { Card } from 'src/components/Card'
import { Block } from 'src/components/Block'
interface IPerson { type CardData = {
url: string title: string
name: string caption?: string
position: string imageSrc: string
picture: IImage imageAlt: string
imageSrcSet: string
href: string
} }
type Props = { type Props = {
title: string title: string
image: string image: string
meta: IMeta meta: IMeta
data: IPerson[] data: CardData[]
} }
const Page: NextPage<Props> = props => { const Page: NextPage<Props> = props => {
@@ -52,24 +55,26 @@ const Page: NextPage<Props> = props => {
<CardGrid style={{ <CardGrid style={{
marginBottom: 'var(--size-xl)', marginBottom: 'var(--size-xl)',
}}> }}>
{props.data.map((item, index) => ( {props.data.map(item => (
<Card <Card
key={index} key={item.href}
layout={'featured'} layout={'featured'}
img={{ img={{
src: item.picture.src, src: item.imageSrc,
alt: item.name, alt: item.imageAlt,
srcSet: '',//item.name.sr, srcSet: item.imageSrcSet,
}} }}
href={item.url} href={item.href}
> >
<h2 style={{ <Block direction={'vertical'}>
margin: '0 0 var(--size-s)', <span>{item.title}</span>
fontSize: '14pt', <span style={{
}}> paddingTop: 'var(--size-s)',
{item.name[0]} {item.name[1]} {item.name[2]} fontSize: 'var(--font-size-second)',
</h2> }}>
{item.position} {item.caption}
</span>
</Block>
</Card> </Card>
))} ))}
</CardGrid> </CardGrid>
@@ -78,14 +83,24 @@ const Page: NextPage<Props> = props => {
} }
export const unstable_getStaticProps = async (ctx: NextPageContext) => { export const unstable_getStaticProps = async (ctx: NextPageContext) => {
// const pageUrl = ctx.req.url const res = await requestGet<IResponseItems<Person>>(createApiUrl('/api/persons'), null)
const res = await requestGet<IResponseItems<IPerson>>(createApiUrl('/api/persons'), null)
const data = res?.items || []
const title = 'Преподаватели Шлиссельбургской ДХШ' const title = 'Преподаватели Шлиссельбургской ДХШ'
const imageFile = 'Images/HudozkaCollective2017.jpg' const imageFile = 'Images/HudozkaCollective2017.jpg'
const resImage = await requestGet(createApiUrl(`/api/image?file=${imageFile}`), null) const resImage = await requestGet(createApiUrl(`/api/image?file=${imageFile}`), null)
const image = get(resImage, 'artifacts.large', null) const image = get(resImage, 'artifacts.large', null)
const data: CardData[] = (res?.items || [])
.map(x => {
const title = `${x.name[0]} ${x.name[1]} ${x.name[2]}`
return {
title,
caption: x.position,
href: x.url,
imageSrc: x.picture.src,
imageAlt: title,
imageSrcSet: '',
}
})
return { return {
props: { props: {
+8 -9
View File
@@ -3,7 +3,7 @@ import { App } from 'src/components/App'
import { Meta } from 'src/components/Meta' import { Meta } from 'src/components/Meta'
import { ArticleGrid } from 'src/components/ArticleGrid' import { ArticleGrid } from 'src/components/ArticleGrid'
import { HudozkaTitle } from 'src/components/HudozkaTitle' import { HudozkaTitle } from 'src/components/HudozkaTitle'
import { meta } from 'src/lib/meta' import { meta, MetaBuilder } from 'src/lib/meta'
import { createApiUrl, requestGet, IResponseItems } from 'src/next-lib' import { createApiUrl, requestGet, IResponseItems } from 'src/next-lib'
import { NextPage } from 'next' import { NextPage } from 'next'
import { IArticle } from 'src/types' import { IArticle } from 'src/types'
@@ -45,13 +45,15 @@ export const unstable_getStaticProps = async () => {
const pageSize = process.env.APP_ARTICLES_PAGE_SIZE const pageSize = process.env.APP_ARTICLES_PAGE_SIZE
const res = await requestGet<IResponseItems<IArticle>>(createApiUrl(`/api/articles?page=${page}&pageSize=${pageSize}`), null) const res = await requestGet<IResponseItems<IArticle>>(createApiUrl(`/api/articles?page=${page}&pageSize=${pageSize}`), null)
const articles = (res.items || []) const articles = (res.items || [])
.map(x => ({
...x,
featured: ['2019-kotiki', 'veloparking'].includes(x.id)
}))
const nextPage = res.nextPage const nextPage = res.nextPage
const prevPage = res.prevPage const prevPage = res.prevPage
const title = 'Шлиссельбургская ДХШ' const title = 'Шлиссельбургская ДХШ'
const meta = (new MetaBuilder())
.setTitle(title)
.setData({
url: '/',
})
.build()
return { return {
props: { props: {
@@ -59,10 +61,7 @@ export const unstable_getStaticProps = async () => {
nextPage, nextPage,
prevPage, prevPage,
title, title,
meta: meta({ meta,
title,
url: '/',
})
} }
} }
} }
+12 -22
View File
@@ -2,10 +2,10 @@ import Head from 'next/head'
import { App } from 'src/components/App' import { App } from 'src/components/App'
import { Article } from 'src/components/Article' import { Article } from 'src/components/Article'
import { Meta } from 'src/components/Meta' import { Meta } from 'src/components/Meta'
import { meta } from 'src/lib/meta' import { MetaBuilder } from 'src/lib/meta'
import { createApiUrl, requestGet, IResponseItems } from 'src/next-lib' import { createApiUrl, requestGet, IResponseItems } from 'src/next-lib'
import { NextPage } from 'next' import { NextPage } from 'next'
import { IMeta } from 'src/types' import { IMeta, Person } from 'src/types'
import { Html } from 'src/components/Html' import { Html } from 'src/components/Html'
interface IProps { interface IProps {
@@ -47,44 +47,34 @@ const Index: NextPage<IProps> = props => {
} }
export const unstable_getStaticProps = async (ctx: any) => { export const unstable_getStaticProps = async (ctx: any) => {
console.log('call unstable_getStaticProps', ctx) const id = ctx.params.person
// const id = ctx.query.person
// const id = ctx.params.person ?? 'va-sarzhin'
const id = ctx.params.person //?? 'mg-timasheva'
if (!id) { if (!id) {
throw new Error('sry') throw new Error('sry')
} }
const person = await requestGet<any>(createApiUrl(`/api/persons/${id}`), null) const person = await requestGet<Person>(createApiUrl(`/api/persons/${id}`), null)
const name = person.name || []
const title = name.join(' ')
const image = person.preview ? person.preview.artifacts.fb : {}
if (!person?.post) { if (!person?.post) {
throw new Error(`post kek ${id}`) throw new Error(`post kek ${id}`)
} }
const title = person.name.join(' ')
const meta = (new MetaBuilder())
.setImage(person.preview)
.setTitle(title)
.setDescription(person.position)
.build()
return { return {
props: { props: {
person, person,
title, title,
meta: meta({ meta,
title,
image: image.src,
imageWidth: image.width,
imageHeight: image.height,
})
} }
} }
} }
export const unstable_getStaticPaths = async () => { export const unstable_getStaticPaths = async () => {
console.log('call unstable_getStaticPaths')
const urls = await requestGet<IResponseItems<string>>(createApiUrl(`/api/persons/urls`), null) const urls = await requestGet<IResponseItems<string>>(createApiUrl(`/api/persons/urls`), null)
// const urls = {items: ['/teacher/va-sarzhin']}
return { return {
paths: urls.items paths: urls.items
+4 -2
View File
@@ -29,7 +29,9 @@ export const ArticleGrid: React.FC<ArticleGridProps> = ({ articles, nextPage, pr
{articles.map((article, i) => { {articles.map((article, i) => {
const gridColumn = article.featured ? 'span 2' : 'auto' const gridColumn = article.featured ? 'span 2' : 'auto'
const layout: CardLayout = article.featured ? 'featured' : 'simple' const layout: CardLayout = article.featured ? 'featured' : 'simple'
const srcSet = article.preview.set.map(({ url, density }) => `${url} ${density}x`).join(' ') const preview = article.preview.artifacts.medium
const src = preview.src
const srcSet = preview.set.map(({ url, density }) => `${url} ${density}x`).join(' ')
const content = !article.featured const content = !article.featured
? ( ? (
@@ -52,7 +54,7 @@ export const ArticleGrid: React.FC<ArticleGridProps> = ({ articles, nextPage, pr
href={article.url} href={article.url}
img={{ img={{
alt: article.title, alt: article.title,
src: article.preview.src, src,
srcSet, srcSet,
}} }}
layout={layout} layout={layout}
+3 -4
View File
@@ -1,11 +1,10 @@
import * as React from 'react' import { IMeta } from 'src/types'
import { IMeta } from '../../types'
export interface IMetaProps { export type MetaProps = {
meta: IMeta meta: IMeta
} }
export const Meta: React.FC<IMetaProps> = ({ meta }) => ( export const Meta: React.FC<MetaProps> = ({ meta }) => (
<> <>
{/* Search Engine */} {/* Search Engine */}
<meta name="description" content={meta.description} /> <meta name="description" content={meta.description} />
-23
View File
@@ -1,23 +0,0 @@
export function meta(props) {
const path = props.url || '/'
const url = `https://art.shlisselburg.org${path}`
return {
title: 'Шлиссельбургская ДХШ',
description: 'Сайт Шлиссельбургской художественной школы',
image: 'https://art.shlisselburg.org/entrance.jpg',
imageWidth: 1200,
imageHeight: 630,
siteName: 'Шлиссельбургская Детская Художественная Школа',
locale: 'ru_RU',
type: 'website',
domain: 'art.shlisselburg.org',
twitterCard: 'summary_large_image',
twitterSite: '@',
twitterCreator: '@tmshv',
...props,
url,
}
}
+76
View File
@@ -0,0 +1,76 @@
import { IMeta, ImageDefinition } from 'src/types'
export function meta(props: Partial<IMeta>): IMeta {
const path = props.url || '/'
const url = `https://art.shlisselburg.org${path}`
return {
title: 'Шлиссельбургская ДХШ',
description: 'Сайт Шлиссельбургской художественной школы',
image: 'https://art.shlisselburg.org/entrance.jpg',
imageWidth: 1200,
imageHeight: 630,
siteName: 'Шлиссельбургская Детская Художественная Школа',
locale: 'ru_RU',
type: 'website',
domain: 'art.shlisselburg.org',
twitterCard: 'summary_large_image',
twitterSite: '@',
twitterCreator: '@tmshv',
...props,
url,
}
}
export class MetaBuilder {
private image: ImageDefinition
private title: string
private description: string
private data: Partial<IMeta>
setData(param: Partial<IMeta>) {
this.data = param
return this
}
setTitle(param: string) {
this.title = param
return this
}
setDescription(param: string) {
this.description = param
return this
}
setImage(param: ImageDefinition) {
this.image = param
return this
}
build() {
const image = this.buildImage()
return meta({
...this.data,
...image,
title: this.title ?? undefined,
description: this.description ?? undefined,
})
}
private buildImage() {
if (!this.image) {
return null
}
const artifact = this.image.artifacts.fb
return {
image: artifact.src,
imageWidth: artifact.width,
imageHeight: artifact.height,
}
}
}
+42 -2
View File
@@ -13,7 +13,8 @@ export interface IPage {
title: string title: string
url: string url: string
data: string data: string
preview: any //IImage preview: ImageDefinition
description: string
tokens: any[] tokens: any[]
breadcrumb?: IBreadcumbsPart[] breadcrumb?: IBreadcumbsPart[]
} }
@@ -65,5 +66,44 @@ export interface IArticle {
featured: boolean featured: boolean
url: string url: string
title: string title: string
preview: IImage preview: ImageDefinition
}
export type Person = {
id: string
position: string
name: [string, string, string]
post: string
diploma: string
edu: string
file: string
hash: string
shortName: string
status: string
url: string
picture: ImageArtifact
preview: ImageDefinition
}
export type ImageArtifact = {
width: number
height: number
src: string
set: Array<{
density: number
url: string
}>
}
export type ImageDefinition = {
file: string
hash: string
artifacts: {
original: ImageArtifact
large?: ImageArtifact
big?: ImageArtifact
medium?: ImageArtifact
small?: ImageArtifact
fb?: ImageArtifact
}
} }