Skip to content

Commit

Permalink
feat(byline): add links in baking
Browse files Browse the repository at this point in the history
  • Loading branch information
mlbrgl committed May 22, 2024
1 parent 3b3a7c6 commit f4de93e
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 45 deletions.
34 changes: 27 additions & 7 deletions baker/SiteBaker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
excludeUndefined,
grabMetadataForGdocLinkedIndicator,
GrapherTabOption,
DbEnrichedAuthor,
} from "@ourworldindata/utils"

import { execWrapper } from "../db/execWrapper.js"
Expand Down Expand Up @@ -103,10 +104,11 @@ import {
getAllMinimalGdocBaseObjects,
} from "../db/model/Gdoc/GdocFactory.js"
import { getBakePath } from "@ourworldindata/components"
import { GdocAuthor } from "../db/model/Gdoc/GdocAuthor.js"
import { GdocAuthor, getMinimalAuthors } from "../db/model/Gdoc/GdocAuthor.js"
import { DATA_INSIGHTS_ATOM_FEED_NAME } from "../site/gdocs/utils.js"

type PrefetchedAttachments = {
linkedAuthors: DbEnrichedAuthor[]
linkedDocuments: Record<string, OwidGdocMinimalPostInterface>
imageMetadata: Record<string, ImageMetadata>
linkedCharts: {
Expand Down Expand Up @@ -169,7 +171,7 @@ function getProgressBarTotal(bakeSteps: BakeStepConfig): number {
bakeSteps.has("dataInsights") ||
bakeSteps.has("authors")
) {
total += 6
total += 7
}
return total
}
Expand Down Expand Up @@ -305,14 +307,14 @@ export class SiteBaker {
return without(existingSlugs, ...postSlugsFromDb)
}

// Prefetches all linkedDocuments, imageMetadata, linkedCharts, and linkedIndicators instead of having to fetch them
// for each individual gdoc. Optionally takes a tuple of string arrays to pick from the prefetched
// dictionaries.
// TODO:
// Prefetches all linkedAuthors, linkedDocuments, imageMetadata,
// linkedCharts, and linkedIndicators instead of having to fetch them for
// each individual gdoc. Optionally takes a tuple of string arrays to pick
// from the prefetched dictionaries.
_prefetchedAttachmentsCache: PrefetchedAttachments | undefined = undefined
private async getPrefetchedGdocAttachments(
knex: db.KnexReadonlyTransaction,
picks?: [string[], string[], string[], string[]]
picks?: [string[], string[], string[], string[], string[]]
): Promise<PrefetchedAttachments> {
if (!this._prefetchedAttachmentsCache) {
console.log("Prefetching attachments...")
Expand Down Expand Up @@ -401,7 +403,14 @@ export class SiteBaker {
})
const datapageIndicatorsById = keyBy(datapageIndicators, "id")

const publishedAuthors = await getMinimalAuthors(knex)

this.progressBar.tick({
name: `✅ Prefetched ${publishedAuthors.length} authors`,
})

const prefetchedAttachments = {
linkedAuthors: publishedAuthors,
linkedDocuments: publishedGdocsDictionary,
imageMetadata: imageMetadataDictionary,
linkedCharts: {
Expand All @@ -415,6 +424,7 @@ export class SiteBaker {
}
if (picks) {
const [
authorNames,
linkedDocumentIds,
imageFilenames,
linkedGrapherSlugs,
Expand Down Expand Up @@ -462,6 +472,10 @@ export class SiteBaker {
this._prefetchedAttachmentsCache.linkedIndicators,
linkedIndicatorIds
),
linkedAuthors:
this._prefetchedAttachmentsCache.linkedAuthors.filter(
(author) => authorNames.includes(author.title)
),
}
}
return this._prefetchedAttachmentsCache
Expand Down Expand Up @@ -544,11 +558,13 @@ export class SiteBaker {

for (const publishedGdoc of gdocsToBake) {
const attachments = await this.getPrefetchedGdocAttachments(knex, [
publishedGdoc.content.authors,
publishedGdoc.linkedDocumentIds,
publishedGdoc.linkedImageFilenames,
publishedGdoc.linkedChartSlugs.grapher,
publishedGdoc.linkedChartSlugs.explorer,
])
publishedGdoc.linkedAuthors = attachments.linkedAuthors
publishedGdoc.linkedDocuments = attachments.linkedDocuments
publishedGdoc.imageMetadata = attachments.imageMetadata
publishedGdoc.linkedCharts = {
Expand Down Expand Up @@ -756,11 +772,13 @@ export class SiteBaker {

for (const dataInsight of publishedDataInsights) {
const attachments = await this.getPrefetchedGdocAttachments(knex, [
dataInsight.content.authors,
dataInsight.linkedDocumentIds,
dataInsight.linkedImageFilenames,
dataInsight.linkedChartSlugs.grapher,
dataInsight.linkedChartSlugs.explorer,
])
dataInsight.linkedAuthors = attachments.linkedAuthors
dataInsight.linkedDocuments = attachments.linkedDocuments
dataInsight.imageMetadata = attachments.imageMetadata
dataInsight.linkedCharts = {
Expand Down Expand Up @@ -824,6 +842,7 @@ export class SiteBaker {

for (const publishedAuthor of publishedAuthors) {
const attachments = await this.getPrefetchedGdocAttachments(knex, [
publishedAuthor.content.authors,
publishedAuthor.linkedDocumentIds,
publishedAuthor.linkedImageFilenames,
publishedAuthor.linkedChartSlugs.grapher,
Expand All @@ -837,6 +856,7 @@ export class SiteBaker {
// ...attachments.linkedCharts.graphers,
// ...attachments.linkedCharts.explorers,
// }
// publishedAuthor.linkedAuthors = attachments.linkedAuthors

// Attach documents metadata linked to in the "featured work" section
publishedAuthor.linkedDocuments = attachments.linkedDocuments
Expand Down
18 changes: 18 additions & 0 deletions db/model/Gdoc/GdocAuthor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
DEFAULT_GDOC_FEATURED_IMAGE,
OwidGdocBaseInterface,
excludeNullish,
DbRawAuthor,
} from "@ourworldindata/utils"
import { GdocBase } from "./GdocBase.js"
import { htmlToEnrichedTextBlock } from "./htmlToEnriched.js"
Expand Down Expand Up @@ -159,3 +160,20 @@ export class GdocAuthor extends GdocBase implements OwidGdocAuthorInterface {
return loadPublishedGdocAuthors(knex)
}
}

export async function getMinimalAuthors(
knex: db.KnexReadonlyTransaction
): Promise<DbRawAuthor[]> {
const rows = await db.knexRaw<DbRawAuthor>(
knex,
`-- sql
SELECT
slug,
content ->> '$.title' as title
FROM posts_gdocs
WHERE type = 'author'
AND published = 1`
)

return rows
}
24 changes: 10 additions & 14 deletions db/model/Gdoc/GdocBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ import { KnexReadonlyTransaction } from "../../db"
export class GdocBase implements OwidGdocBaseInterface {
id!: string
slug: string = ""
authors: DbEnrichedAuthor[] = []
content!: OwidGdocContent
published: boolean = false
createdAt: Date = new Date()
Expand All @@ -76,6 +75,7 @@ export class GdocBase implements OwidGdocBaseInterface {
tags: DbPlainTag[] | null = null
errors: OwidGdocErrorMessage[] = []
imageMetadata: Record<string, ImageMetadata> = {}
linkedAuthors: DbEnrichedAuthor[] = []
linkedCharts: Record<string, LinkedChart> = {}
linkedIndicators: Record<number, LinkedIndicator> = {}
linkedDocuments: Record<string, OwidGdocMinimalPostInterface> = {}
Expand Down Expand Up @@ -185,8 +185,11 @@ export class GdocBase implements OwidGdocBaseInterface {
return [...details]
}

async loadAuthors(knex: db.KnexReadonlyTransaction): Promise<void> {
this.authors = await getMinimalAuthorByNames(knex, this.content.authors)
async loadLinkedAuthors(knex: db.KnexReadonlyTransaction): Promise<void> {
this.linkedAuthors = await getMinimalAuthorsByNames(
knex,
this.content.authors
)
}

get links(): DbInsertPostGdocLink[] {
Expand Down Expand Up @@ -803,7 +806,7 @@ export class GdocBase implements OwidGdocBaseInterface {
}

async loadState(knex: db.KnexReadonlyTransaction): Promise<void> {
await this.loadAuthors(knex)
await this.loadLinkedAuthors(knex)
await this.loadLinkedDocuments(knex)
await this.loadImageMetadataFromDB(knex)
await this.loadLinkedCharts(knex)
Expand Down Expand Up @@ -881,10 +884,10 @@ export async function getMinimalGdocPostsByIds(
})
}

export async function getMinimalAuthorByNames(
export async function getMinimalAuthorsByNames(
knex: KnexReadonlyTransaction,
names: string[]
): Promise<DbEnrichedAuthor[]> {
): Promise<DbRawAuthor[]> {
if (names.length === 0) return []
const rows = await db.knexRaw<DbRawAuthor>(
knex,
Expand All @@ -898,12 +901,5 @@ export async function getMinimalAuthorByNames(
AND published = 1`,
{ names }
)

return names.map((name) => {
const row = rows.find((row) => row.title === name)
return {
slug: row?.slug || null,
title: name,
}
})
return rows
}
2 changes: 1 addition & 1 deletion packages/@ourworldindata/types/src/gdocTypes/Gdoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ export interface OwidGdocBaseInterface {
id: string
slug: string
// TODO: should we type this as a union of the possible content types instead?
authors?: DbEnrichedAuthor[]
content: OwidGdocContent
published: boolean
createdAt: Date
Expand All @@ -71,6 +70,7 @@ export interface OwidGdocBaseInterface {
revisionId: string | null
publicationContext: OwidGdocPublicationContext
breadcrumbs: BreadcrumbItem[] | null
linkedAuthors?: DbEnrichedAuthor[]
linkedDocuments?: Record<string, OwidGdocMinimalPostInterface>
linkedCharts?: Record<string, LinkedChart>
linkedIndicators?: Record<number, LinkedIndicator>
Expand Down
6 changes: 3 additions & 3 deletions site/gdocs/OwidGdoc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { Homepage } from "./pages/Homepage.js"
import { Author } from "./pages/Author.js"

export const AttachmentsContext = createContext<{
authors: DbEnrichedAuthor[]
linkedAuthors: DbEnrichedAuthor[]
linkedCharts: Record<string, LinkedChart>
linkedIndicators: Record<number, LinkedIndicator>
linkedDocuments: Record<string, OwidGdocMinimalPostInterface>
Expand All @@ -33,7 +33,7 @@ export const AttachmentsContext = createContext<{
homepageMetadata?: OwidGdocHomepageMetadata
latestWorkLinks?: DbEnrichedLatestWork[]
}>({
authors: [],
linkedAuthors: [],
linkedDocuments: {},
imageMetadata: {},
linkedCharts: {},
Expand Down Expand Up @@ -114,7 +114,7 @@ export function OwidGdoc({
return (
<AttachmentsContext.Provider
value={{
authors: get(props, "authors", []),
linkedAuthors: get(props, "linkedAuthors", []),
linkedDocuments: get(props, "linkedDocuments", {}),
imageMetadata: get(props, "imageMetadata", {}),
linkedCharts: get(props, "linkedCharts", {}),
Expand Down
20 changes: 11 additions & 9 deletions site/gdocs/components/Byline.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
import { getCanonicalUrl } from "@ourworldindata/components"
import { DbEnrichedAuthor, OwidGdocType } from "@ourworldindata/types"
import { OwidGdocType } from "@ourworldindata/types"
import React from "react"
import { useLinkedAuthor } from "../utils.js"

export const Byline = ({ authors }: { authors: DbEnrichedAuthor[] }) => {
export const Byline = ({ names }: { names: string[] }) => {
return (
<>
By:{" "}
{authors.map((author, idx) => (
<>
<LinkedAuthor key={author.title} author={author} />
{idx === authors.length - 1
{names.map((name, idx) => (
<React.Fragment key={name}>
<LinkedAuthor name={name} />
{idx === names.length - 1
? ""
: idx === authors.length - 2
: idx === names.length - 2
? " and "
: ", "}
</>
</React.Fragment>
))}
</>
)
}

const LinkedAuthor = ({ author }: { author: DbEnrichedAuthor }) => {
const LinkedAuthor = ({ name }: { name: string }) => {
const author = useLinkedAuthor(name)
if (!author.slug) return <>{author.title}</>

const path = getCanonicalUrl("", {
Expand Down
18 changes: 7 additions & 11 deletions site/gdocs/components/OwidGdocHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useContext } from "react"
import React from "react"
import cx from "classnames"
import {
BreadcrumbItem,
Expand All @@ -13,7 +13,6 @@ import Image from "./Image.js"
import { Breadcrumbs } from "../../Breadcrumb/Breadcrumb.js"
import { breadcrumbColorForCoverColor } from "../utils.js"
import { Byline } from "./Byline.js"
import { AttachmentsContext } from "../OwidGdoc.js"

function OwidArticleHeader({
content,
Expand All @@ -29,7 +28,6 @@ function OwidArticleHeader({
: undefined

const breadcrumbColor = breadcrumbColorForCoverColor(content["cover-color"])
const { authors } = useContext(AttachmentsContext)

return (
<>
Expand Down Expand Up @@ -78,9 +76,9 @@ function OwidArticleHeader({
) : null}
<div className="centered-article-header__meta-container col-start-2 span-cols-6 span-md-cols-10 col-md-start-2 grid grid-cols-2 ">
<div className="span-cols-1 span-sm-cols-2">
{authors.length > 0 && (
{content.authors.length > 0 && (
<div className="centered-article-header__byline">
<Byline authors={authors} />
<Byline names={content.authors} />
</div>
)}
<div className="centered-article-header__dateline body-3-medium-italic">
Expand Down Expand Up @@ -114,7 +112,6 @@ function OwidArticleHeader({
}

function OwidTopicPageHeader({ content }: { content: OwidGdocPostContent }) {
const { authors } = useContext(AttachmentsContext)
return (
<header className="topic-page-header grid span-cols-14 grid-cols-12-full-width">
<h1 className="display-1-semibold col-start-2 span-cols-8">
Expand All @@ -123,9 +120,9 @@ function OwidTopicPageHeader({ content }: { content: OwidGdocPostContent }) {
<p className="topic-page-header__subtitle body-1-regular col-start-2 span-cols-8">
{content.subtitle}
</p>
{authors.length > 0 && (
{content.authors.length > 0 && (
<p className="topic-page-header__byline col-start-2 span-cols-8 col-sm-start-2 span-sm-cols-12">
<Byline authors={authors} />
<Byline names={content.authors} />
</p>
)}
</header>
Expand All @@ -137,7 +134,6 @@ function OwidLinearTopicPageHeader({
}: {
content: OwidGdocPostContent
}) {
const { authors } = useContext(AttachmentsContext)
return (
<header className="topic-page-header grid span-cols-14 grid-cols-12-full-width">
<h1 className="display-1-semibold col-start-5 span-cols-6 col-md-start-3 span-md-cols-10 span-sm-cols-12 col-sm-start-2">
Expand All @@ -146,9 +142,9 @@ function OwidLinearTopicPageHeader({
<p className="topic-page-header__subtitle body-1-regular col-start-5 span-cols-6 col-md-start-3 span-md-cols-10 span-sm-cols-12 col-sm-start-2">
{content.subtitle}
</p>
{authors.length > 0 && (
{content.authors.length > 0 && (
<p className="topic-page-header__byline col-start-5 span-cols-6 col-md-start-3 span-md-cols-10 span-sm-cols-12 col-sm-start-2">
<Byline authors={authors} />
<Byline names={content.authors} />
</p>
)}
<p className="topic-page-header__dateline body-3-medium-italic col-start-5 span-cols-6 col-md-start-3 span-md-cols-10 span-sm-cols-12 col-sm-start-2">
Expand Down
8 changes: 8 additions & 0 deletions site/gdocs/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
OwidGdocMinimalPostInterface,
OwidGdocType,
LinkedIndicator,
DbEnrichedAuthor,
} from "@ourworldindata/types"
import { formatAuthors, Url } from "@ourworldindata/utils"
import { match } from "ts-pattern"
Expand Down Expand Up @@ -44,6 +45,13 @@ export const breadcrumbColorForCoverColor = (
}
}

export const useLinkedAuthor = (name: string): DbEnrichedAuthor => {
const { linkedAuthors } = useContext(AttachmentsContext)
const author = linkedAuthors.find((author) => author.title === name)
if (!author) return { title: name, slug: null }
return author
}

export const useLinkedDocument = (
url: string
): { linkedDocument?: OwidGdocMinimalPostInterface; errorMessage?: string } => {
Expand Down

0 comments on commit f4de93e

Please sign in to comment.