Skip to content

Commit

Permalink
Merge pull request #3487 from owid/index-post-images
Browse files Browse the repository at this point in the history
🎉 index wpPost, gdocPost, and country profile thumbnails to algolia
  • Loading branch information
ikesau authored May 7, 2024
2 parents 75ac0db + 4e25054 commit 3ff02d6
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 20 deletions.
11 changes: 11 additions & 0 deletions baker/algolia/algoliaUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
PostRestApi,
DbPlainTag,
OwidGdocPostInterface,
getThumbnailPath,
} from "@ourworldindata/utils"
import { formatPost } from "../formatWordpressPost.js"
import ReactDOMServer from "react-dom/server.js"
Expand All @@ -35,6 +36,7 @@ import { ObjectWithObjectID } from "@algolia/client-search"
import { SearchIndex } from "algoliasearch"
import { match, P } from "ts-pattern"
import { gdocFromJSON } from "../../db/model/Gdoc/GdocFactory.js"
import { formatUrls } from "../../site/formatting.js"

interface TypeAndImportance {
type: PageType
Expand Down Expand Up @@ -63,6 +65,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",
}
const score = computeScore(record)
return { ...record, score }
Expand Down Expand Up @@ -129,6 +132,9 @@ async function generateWordpressRecords(
modifiedDate: post.modifiedDate.toISOString(),
content: c,
tags: tags.map((t) => t.name),
thumbnailUrl: formatUrls(
post.thumbnailUrl ?? "/default-thumbnail.jpg"
),
views_7d: pageviews[`/${post.path}`]?.views_7d ?? 0,
documentType: "wordpress" as const,
}
Expand Down Expand Up @@ -183,6 +189,10 @@ function generateGdocRecords(
const postTypeAndImportance = getPostTypeAndImportance(gdoc)
let i = 0

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

for (const chunk of chunks) {
const record = {
objectID: `${gdoc.id}-c${i}`,
Expand All @@ -197,6 +207,7 @@ function generateGdocRecords(
tags: gdoc.tags?.map((t) => t.name),
documentType: "gdoc" as const,
authors: gdoc.content.authors,
thumbnailUrl,
}
const score = computeScore(record)
records.push({ ...record, score })
Expand Down
17 changes: 15 additions & 2 deletions packages/@ourworldindata/utils/src/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ import { traverseEnrichedBlock } from "./Util.js"
import { OwidGdoc, OwidGdocType, ImageMetadata } from "@ourworldindata/types"
import { match, P } from "ts-pattern"

export const THUMBNAIL_WIDTH = 100
export const LARGE_THUMBNAIL_WIDTH = 350

export function getSizes(
originalWidth: ImageMetadata["originalWidth"]
): number[] {
if (!originalWidth) return []
// ensure a thumbnail is generated
const widths = [100]
const widths = [THUMBNAIL_WIDTH]
// start at 350 and go up by 500 to a max of 1350 before we just show the original image
let width = 350
let width = LARGE_THUMBNAIL_WIDTH
while (width < originalWidth && width <= 1350) {
widths.push(width)
width += 500
Expand Down Expand Up @@ -52,6 +55,16 @@ export function getFilenameAsPng(filename: ImageMetadata["filename"]): string {
return `${getFilenameWithoutExtension(filename)}.png`
}

export function getFilenameAsThumbnail(
filename: ImageMetadata["filename"]
): string {
return `${getFilenameWithoutExtension(filename)}_${LARGE_THUMBNAIL_WIDTH}.png`
}

export function getThumbnailPath(filename: string): string {
return `/images/published/${getFilenameAsThumbnail(filename)}`
}

export function getFilenameMIMEType(filename: string): string | undefined {
const fileExtension = getFilenameExtension(filename)
const MIMEType = {
Expand Down
4 changes: 4 additions & 0 deletions packages/@ourworldindata/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,9 +369,13 @@ export { PromiseCache } from "./PromiseCache.js"
export { PromiseSwitcher } from "./PromiseSwitcher.js"

export {
THUMBNAIL_WIDTH,
LARGE_THUMBNAIL_WIDTH,
getSizes,
generateSrcSet,
getFilenameWithoutExtension,
getFilenameAsThumbnail,
getThumbnailPath,
getFilenameAsPng,
getFilenameExtension,
getFilenameMIMEType,
Expand Down
5 changes: 4 additions & 1 deletion site/gdocs/components/HomepageIntro.scss
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,10 @@
display: block;

@include sm-only {
height: 172px;
// All our new featured images are published at 1200px x 630px
// Older featured images aren't published at this size, so we need to
// crop them to the correct aspect ratio so that they're all flush
aspect-ratio: 1200 / 630;
width: 298px;
object-fit: cover;
}
Expand Down
6 changes: 5 additions & 1 deletion site/gdocs/components/HomepageIntro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ function FeaturedWorkTile({
})}
>
{thumbnailFilename && (
<Image shouldLightbox={false} filename={thumbnailFilename} />
<Image
shouldLightbox={false}
filename={thumbnailFilename}
containerType="thumbnail"
/>
)}
{kicker && (
<span className="h6-black-caps homepage-intro__featured-work-kicker">
Expand Down
17 changes: 16 additions & 1 deletion site/search/Search.scss
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,20 @@ $reset-button-margin: 16px;
}
}

.search-results__page-hit-container {
display: flex;
}

.search-results__page-hit-img-container {
margin-right: 16px;
@include sm-only {
display: none;
}
}
.search-results__page-hit-img {
width: 100px;
}

.search-results__page-hit-title {
display: inline;
color: $blue-90;
Expand All @@ -252,7 +266,8 @@ $reset-button-margin: 16px;
}

.search-results__page-hit-snippet {
margin: 4px 0;
margin: 0;
margin-bottom: 4px;
color: $blue-60;
display: block;
}
Expand Down
41 changes: 26 additions & 15 deletions site/search/SearchPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,33 @@ function PagesHit({ hit }: { hit: IPageHit }) {
data-algolia-index={getIndexName(SearchIndexName.Pages)}
data-algolia-object-id={hit.objectID}
data-algolia-position={hit.__position}
className="search-results__page-hit-container"
>
{/* TODO: index featured images */}
<header className="page-hit__header">
<h4 className="h3-bold search-results__page-hit-title">
{hit.title}
</h4>
<span className="body-3-medium search-results__page-hit-type">
{pageTypeDisplayNames[hit.type]}
</span>
</header>
<Snippet
className="body-3-medium search-results__page-hit-snippet"
attribute="excerpt"
highlightedTagName="strong"
hit={hit}
/>
{hit.thumbnail && (
<div className="search-results__page-hit-img-container">
<img
src={hit.thumbnailUrl}
role="presentation"
className="search-results__page-hit-img"
/>
</div>
)}
<div className="search-results__page-hit-text-container">
<header className="page-hit__header">
<h4 className="h3-bold search-results__page-hit-title">
{hit.title}
</h4>
<span className="body-3-medium search-results__page-hit-type">
{pageTypeDisplayNames[hit.type]}
</span>
</header>
<Snippet
className="body-3-medium search-results__page-hit-snippet"
attribute="excerpt"
highlightedTagName="strong"
hit={hit}
/>
</div>
</a>
)
}
Expand Down
4 changes: 4 additions & 0 deletions site/search/searchTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export interface PageRecord {
date?: string
modifiedDate?: string
tags?: string[]
// Either a URL (for WP posts) or a filepath (for GDocs)
// WP example: https://ourworldindata.org/wp-content/uploads/2021/03/Biodiversity-thumbnail.png
// GDoc example: /images/published/artificial-intelligence-featured-image_100.png
thumbnailUrl: string
documentType?: "wordpress" | "gdoc" | "country-page"
}

Expand Down

0 comments on commit 3ff02d6

Please sign in to comment.