Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a way of marking articles as deprecated #3912

Merged
merged 6 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions adminSiteClient/gdocsDeploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export const checkIsLightningUpdate = (
"atom-excerpt": false, // requires updating the atom feed / blog roll
"atom-title": false, // requires updating the atom feed / blog roll
"featured-image": false, // requires updating references to this article
"deprecation-notice": false, // requires updating references to this article
authors: false, // requires updating references to this article
excerpt: false, // requires updating references to this article
faqs: false, // requires updating datapages
Expand Down
17 changes: 17 additions & 0 deletions adminSiteClient/gdocsValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ function validateContentType(gdoc: OwidGdoc, errors: OwidGdocErrorMessage[]) {
}
}

function validateDeprecationNotice(
gdoc: OwidGdoc,
errors: OwidGdocErrorMessage[]
) {
if (
"deprecation-notice" in gdoc.content &&
gdoc.content.type !== OwidGdocType.Article
) {
errors.push({
property: "deprecation-notice",
type: OwidGdocErrorMessageType.Error,
message: "Deprecation notice is only supported in articles.",
})
}
}

function validateBody(gdoc: OwidGdoc, errors: OwidGdocErrorMessage[]) {
if (!gdoc.content.body) {
errors.push(getMissingContentPropertyError("body"))
Expand Down Expand Up @@ -236,6 +252,7 @@ export const getErrors = (gdoc: OwidGdoc): OwidGdocErrorMessage[] => {
validateBody(gdoc, errors)
validatePublishedAt(gdoc, errors)
validateContentType(gdoc, errors)
validateDeprecationNotice(gdoc, errors)

if (checkIsGdocPost(gdoc)) {
validateRefs(gdoc, errors)
Expand Down
3 changes: 2 additions & 1 deletion baker/SiteBaker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
excludeUndefined,
grabMetadataForGdocLinkedIndicator,
GrapherTabOption,
DEFAULT_THUMBNAIL_FILENAME,
} from "@ourworldindata/utils"

import { execWrapper } from "../db/execWrapper.js"
Expand Down Expand Up @@ -344,7 +345,7 @@ export class SiteBaker {
title: cur.title || "",
thumbnail:
cur.thumbnail ||
`${BAKED_BASE_URL}/default-thumbnail.jpg`,
`${BAKED_BASE_URL}/${DEFAULT_THUMBNAIL_FILENAME}`,
tags: [],
}))
)
Expand Down
22 changes: 16 additions & 6 deletions baker/algolia/algoliaUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import {
DbPlainTag,
OwidGdocPostInterface,
getThumbnailPath,
ARCHVED_THUMBNAIL_FILENAME,
DEFAULT_GDOC_FEATURED_IMAGE,
DEFAULT_THUMBNAIL_FILENAME,
} from "@ourworldindata/utils"
import { formatPost } from "../formatWordpressPost.js"
import ReactDOMServer from "react-dom/server.js"
Expand Down Expand Up @@ -65,7 +68,7 @@ function generateCountryRecords(
content: `All available indicators for ${country.name}.`,
views_7d: pageviews[`/country/${country.slug}`]?.views_7d ?? 0,
documentType: "country-page" as const,
thumbnailUrl: "/default-thumbnail.jpg",
thumbnailUrl: `/${DEFAULT_THUMBNAIL_FILENAME}`,
}
const score = computeScore(record)
return { ...record, score }
Expand Down Expand Up @@ -144,7 +147,7 @@ async function generateWordpressRecords(
content: c,
tags: tags.map((t) => t.name),
thumbnailUrl: formatUrls(
post.thumbnailUrl ?? "/default-thumbnail.jpg"
post.thumbnailUrl ?? `/${DEFAULT_THUMBNAIL_FILENAME}`
),
views_7d: pageviews[`/${post.path}`]?.views_7d ?? 0,
documentType: "wordpress" as const,
Expand All @@ -157,6 +160,16 @@ async function generateWordpressRecords(
return records
}

function getGdocThumbnailUrl(gdoc: OwidGdocPostInterface): string {
if (gdoc.content["deprecation-notice"]) {
return `/${ARCHVED_THUMBNAIL_FILENAME}`
}
if (gdoc.content["featured-image"]) {
return getThumbnailPath(gdoc.content["featured-image"])
}
return `/${DEFAULT_GDOC_FEATURED_IMAGE}`
}

function generateGdocRecords(
gdocs: OwidGdocPostInterface[],
pageviews: Record<string, RawPageview>
Expand Down Expand Up @@ -199,10 +212,7 @@ function generateGdocRecords(
const chunks = generateChunksFromHtmlText(renderedPostContent)
const postTypeAndImportance = getPostTypeAndImportance(gdoc)
let i = 0

const thumbnailUrl = gdoc.content["featured-image"]
? getThumbnailPath(gdoc.content["featured-image"])
: "/default-thumbnail.jpg"
const thumbnailUrl = getGdocThumbnailUrl(gdoc)

for (const chunk of chunks) {
const record = {
Expand Down
3 changes: 2 additions & 1 deletion baker/siteRenderers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
} from "@ourworldindata/utils"
import { extractFormattingOptions } from "../serverUtils/wordpressUtils.js"
import {
DEFAULT_THUMBNAIL_FILENAME,
DbPlainChart,
DbRawChartConfig,
FormattingOptions,
Expand Down Expand Up @@ -882,6 +883,6 @@ const renderGrapherThumbnailByResolvedChartSlug = (

const renderExplorerDefaultThumbnail = (): string => {
return ReactDOMServer.renderToStaticMarkup(
<img src={`${BAKED_BASE_URL}/default-thumbnail.jpg`} />
<img src={`${BAKED_BASE_URL}/${DEFAULT_THUMBNAIL_FILENAME}`} />
)
}
9 changes: 7 additions & 2 deletions db/model/Gdoc/GdocBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ import {
} from "../Variable.js"
import { createLinkFromUrl } from "../Link.js"
import {
ARCHVED_THUMBNAIL_FILENAME,
DEFAULT_THUMBNAIL_FILENAME,
LatestDataInsight,
LinkedAuthor,
OwidGdoc,
Expand Down Expand Up @@ -623,7 +625,7 @@ export class GdocBase implements OwidGdocBaseInterface {
title: explorer?.title ?? "",
subtitle: explorer?.subtitle ?? "",
resolvedUrl: `${BAKED_BASE_URL}/${EXPLORERS_ROUTE_FOLDER}/${originalSlug}`,
thumbnail: `${BAKED_BASE_URL}/default-thumbnail.jpg`,
thumbnail: `${BAKED_BASE_URL}/${DEFAULT_THUMBNAIL_FILENAME}`,
tags: explorer.tags,
}
return linkedChart
Expand Down Expand Up @@ -879,7 +881,10 @@ export async function getMinimalGdocPostsByIds(
content ->> '$.subtitle' as subtitle,
content ->> '$.excerpt' as excerpt,
type,
content ->> '$."featured-image"' as "featured-image"
CASE
WHEN content ->> '$."deprecation-notice"' IS NOT NULL THEN '${ARCHVED_THUMBNAIL_FILENAME}'
ELSE content ->> '$."featured-image"'
END as "featured-image"
FROM posts_gdocs
WHERE id in (:ids)`,
{ ids }
Expand Down
6 changes: 5 additions & 1 deletion db/model/Gdoc/GdocFactory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { get, groupBy } from "lodash"
import { match, P } from "ts-pattern"
import {
ARCHVED_THUMBNAIL_FILENAME,
DATA_INSIGHTS_INDEX_PAGE_SIZE,
DbEnrichedPostGdoc,
DbInsertPostGdocLink,
Expand Down Expand Up @@ -210,7 +211,10 @@ export async function getAllMinimalGdocBaseObjects(
content ->> '$.subtitle' as subtitle,
content ->> '$.excerpt' as excerpt,
type,
content ->> '$."featured-image"' as "featured-image"
CASE
WHEN content ->> '$."deprecation-notice"' IS NOT NULL THEN '${ARCHVED_THUMBNAIL_FILENAME}'
ELSE content ->> '$."featured-image"'
END as "featured-image"
FROM posts_gdocs
WHERE published = 1
AND publishedAt <= NOW()`,
Expand Down
5 changes: 5 additions & 0 deletions db/model/Gdoc/GdocPost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ export class GdocPost extends GdocBase implements OwidGdocPostInterface {
enrichedBlocks.push(...refBlocks)
}

const deprecationNotice = gdoc.content["deprecation-notice"]
if (deprecationNotice) {
enrichedBlocks.push(...deprecationNotice)
}

return enrichedBlocks
}

Expand Down
10 changes: 9 additions & 1 deletion db/model/Gdoc/archieToEnriched.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ import {
isEmpty,
} from "@ourworldindata/utils"
import { convertHeadingTextToId } from "@ourworldindata/components"
import { parseRawBlocksToEnrichedBlocks, parseRefs } from "./rawToEnriched.js"
import {
parseRawBlocksToEnrichedBlocks,
parseRefs,
parseText,
} from "./rawToEnriched.js"
import urlSlug from "url-slug"
import { extractUrl, parseAuthors, spansToSimpleString } from "./gdocUtils.js"
import { htmlToSimpleTextBlock } from "./htmlToEnriched.js"
Expand Down Expand Up @@ -316,6 +320,10 @@ export const archieToEnriched = (

// Parse elements of the ArchieML into enrichedBlocks
parsed.body = compact(parsed.body.map(parseRawBlocksToEnrichedBlocks))
const deprecationNotice = parsed["deprecation-notice"]
if (deprecationNotice) {
parsed["deprecation-notice"] = compact(deprecationNotice.map(parseText))
rakyi marked this conversation as resolved.
Show resolved Hide resolved
}

const parsedRefs = parseRefs({
refs: [...(parsed.refs ?? []), ...rawInlineRefs],
Expand Down
29 changes: 22 additions & 7 deletions db/model/Post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import {
DbEnrichedLatestWork,
parseLatestWork,
DbPlainTag,
DEFAULT_THUMBNAIL_FILENAME,
ARCHVED_THUMBNAIL_FILENAME,
} from "@ourworldindata/types"
import { uniqBy, sortBy, memoize, orderBy } from "@ourworldindata/utils"
import { Knex } from "knex"
Expand Down Expand Up @@ -263,10 +265,12 @@ export const getFullPost = async (
content: excludeContent ? "" : postApi.content.rendered,
excerpt: decodeHTML(postApi.excerpt.rendered),
imageUrl: `${BAKED_BASE_URL}${
postApi.featured_media_paths.medium_large ?? "/default-thumbnail.jpg"
postApi.featured_media_paths.medium_large ??
`/${DEFAULT_THUMBNAIL_FILENAME}`
}`,
thumbnailUrl: `${BAKED_BASE_URL}${
postApi.featured_media_paths?.thumbnail ?? "/default-thumbnail.jpg"
postApi.featured_media_paths?.thumbnail ??
`/${DEFAULT_THUMBNAIL_FILENAME}`
}`,
imageId: postApi.featured_media,
relatedCharts:
Expand Down Expand Up @@ -308,6 +312,16 @@ export const getBlogIndex = memoize(
}
)

function getGdocThumbnail(gdoc: OwidGdocPostInterface): string {
let thumbnailPath = `/${DEFAULT_THUMBNAIL_FILENAME}`
if (gdoc.content["deprecation-notice"]) {
thumbnailPath = `/${ARCHVED_THUMBNAIL_FILENAME}`
} else if (gdoc.content["featured-image"]) {
thumbnailPath = `${IMAGES_DIRECTORY}${gdoc.content["featured-image"]}`
}
return `${BAKED_BASE_URL}${thumbnailPath}`
}

export const mapGdocsToWordpressPosts = (
gdocs: OwidGdocPostInterface[]
): IndexPost[] => {
Expand All @@ -319,9 +333,7 @@ export const mapGdocsToWordpressPosts = (
modifiedDate: gdoc.updatedAt as Date,
authors: gdoc.content.authors,
excerpt: gdoc.content["atom-excerpt"] || gdoc.content.excerpt,
imageUrl: gdoc.content["featured-image"]
? `${BAKED_BASE_URL}${IMAGES_DIRECTORY}${gdoc.content["featured-image"]}`
: `${BAKED_BASE_URL}/default-thumbnail.jpg`,
imageUrl: getGdocThumbnail(gdoc),
}))
}

Expand Down Expand Up @@ -614,7 +626,7 @@ export const getLatestWorkByAuthor = async (
knex: Knex<any, any[]>,
author: string
): Promise<DbEnrichedLatestWork[]> => {
const rawLatestWorkLinks: DbRawLatestWork[] = await db.knexRaw(
const rawLatestWorkLinks = await db.knexRaw<DbRawLatestWork>(
knex,
`-- sql
SELECT
Expand All @@ -623,7 +635,10 @@ export const getLatestWorkByAuthor = async (
pg.content->>'$.title' AS title,
pg.content->>'$.subtitle' AS subtitle,
pg.content->>'$.authors' AS authors,
pg.content->>'$."featured-image"' AS "featured-image",
CASE
WHEN content ->> '$."deprecation-notice"' IS NOT NULL THEN '${ARCHVED_THUMBNAIL_FILENAME}'
ELSE content ->> '$."featured-image"'
END as "featured-image"
pg.publishedAt
FROM
posts_gdocs pg
Expand Down
3 changes: 2 additions & 1 deletion functions/donation/_utils/checkout.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Stripe from "stripe"
import {
DEFAULT_THUMBNAIL_FILENAME,
DonationRequest,
getErrorMessageDonation,
JsonError,
Expand Down Expand Up @@ -92,7 +93,7 @@ export async function createCheckoutSession(
product_data: {
name: "Monthly donation",
images: [
"https://ourworldindata.org/default-thumbnail.jpg",
`https://ourworldindata.org/${DEFAULT_THUMBNAIL_FILENAME}`,
],
},
recurring: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ $xxlg: 1536px;
*/

$zindex-input: 1;
$zindex-deprecation-notice: 10;
$zindex-global-entity-select: 11;
$zindex-footnote: 15;
$zindex-sidebar: 20;
Expand Down
1 change: 1 addition & 0 deletions packages/@ourworldindata/types/src/gdocTypes/Gdoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ export interface OwidGdocPostContent {
excerpt?: string
refs?: { definitions: RefDictionary; errors: OwidGdocErrorMessage[] }
summary?: EnrichedBlockText[]
"deprecation-notice"?: EnrichedBlockText[]
"hide-citation"?: boolean
toc?: TocHeadingWithTitleSupertitle[]
"cover-image"?: string
Expand Down
6 changes: 6 additions & 0 deletions packages/@ourworldindata/types/src/gdocTypes/GdocConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,10 @@ export const gdocUrlRegex =

export const gdocIdRegex = /^[0-9A-Za-z\-_]{44}$/

// This file is saved in Drive in the Unattributed Images folder
// Somewhat fragile, should be fixed as part of https://github.com/owid/owid-grapher/issues/2485
export const DEFAULT_GDOC_FEATURED_IMAGE = "default-featured-image.png"

export const DEFAULT_THUMBNAIL_FILENAME = "default-thumbnail.jpg"

export const ARCHVED_THUMBNAIL_FILENAME = "archived-thumbnail.jpg"
2 changes: 2 additions & 0 deletions packages/@ourworldindata/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@ export {
gdocUrlRegex,
gdocIdRegex,
DEFAULT_GDOC_FEATURED_IMAGE,
DEFAULT_THUMBNAIL_FILENAME,
ARCHVED_THUMBNAIL_FILENAME,
} from "./gdocTypes/GdocConstants.js"
export {
type OwidVariableWithSource,
Expand Down
6 changes: 2 additions & 4 deletions packages/@ourworldindata/utils/src/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,13 @@ export function getFeaturedImageFilename(gdoc: OwidGdoc): string | undefined {
content: {
type: P.union(
OwidGdocType.Fragment,
// undefined so that we use default-thumbnail.jpg as defined in Head.tsx
OwidGdocType.Homepage,
undefined
),
},
},
() => {
return undefined
}
// This will fallback to DEFAULT_THUMBNAIL_FILENAME in Head.tsx
() => undefined
)
.exhaustive()
}
Binary file added public/archived-thumbnail.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion site/DataPageV2Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
GrapherInterface,
joinTitleFragments,
ImageMetadata,
DEFAULT_THUMBNAIL_FILENAME,
} from "@ourworldindata/utils"
import { AttachmentsContext, DocumentContext } from "./gdocs/OwidGdoc.js"
import StickyNav from "./blocks/StickyNav.js"
Expand All @@ -40,7 +41,7 @@ const DatapageResearchThumbnail = ({
urlOrFilename: string | undefined | null
}) => {
if (!urlOrFilename) {
urlOrFilename = `${BAKED_BASE_URL}/default-thumbnail.jpg`
urlOrFilename = `${BAKED_BASE_URL}/${DEFAULT_THUMBNAIL_FILENAME}`
}
if (urlOrFilename.startsWith("http")) {
return (
Expand Down
Loading