Skip to content

Commit 3145ba6

Browse files
fix: indexing for chinese (#370)
* fix: improve URL handling for determining Algolia index names, cleanup * chore: update README
1 parent 54f3644 commit 3145ba6

File tree

3 files changed

+49
-27
lines changed

3 files changed

+49
-27
lines changed

Diff for: README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ And here are the current Ghost events / webhooks and their endpoints:
1919
| Post unpublished | .../ghost/delete-record |
2020
| Post deleted | .../ghost/delete-record |
2121

22-
Finally, here are the currently configured Algolia indices for each publication:
22+
Finally, here are the currently configured Algolia indices for each publication, which are all production unless otherwise noted:
2323

2424
| Publication URL | CMS | Algolia index |
2525
| --------------------------------------------- | -------- | ------------- |
2626
| https://www.freecodecamp.org/news/ | Hashnode | news |
27-
| https://chinese.freecodecamp.org/news/ | Ghost | news-zh |
27+
| http://localhost:3030 | Ghost | news-es (dev) |
28+
| https://www.freecodecamp.org/chinese/news/ | Ghost | news-zh |
2829
| https://www.freecodecamp.org/espanol/news/ | Ghost | news-es |
2930
| https://www.freecodecamp.org/italian/news/ | Ghost | news-it |
3031
| https://www.freecodecamp.org/japanese/news/ | Ghost | news-ja |

Diff for: lib/utils/helpers.js

+33-19
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@ export const algoliaClient = algoliasearch(
66
process.env.ALGOLIA_ADMIN_KEY
77
);
88

9-
export const searchIndexNameMap = {
10-
'http://localhost:3030': 'news-es', // Dockerized Spanish Ghost instance for testing, which is mimicking the old English instance
11-
'https://chinese.freecodecamp.org/news/': 'news-zh',
9+
const searchIndexNameMap = {
10+
// Dockerized Spanish Ghost instance for testing
11+
'http://localhost:3030': 'news-es',
12+
// The Chinese publication is at https://chinese.freecodecamp.org/news/,
13+
// but this map and the getSearchIndexName function are used after formatting
14+
// the post for Algolia, which updates necessary URLs for the search record
15+
// to start with https://www.freecodecamp.org/chinese/news/
16+
'https://www.freecodecamp.org/chinese/news/': 'news-zh',
1217
'https://www.freecodecamp.org/espanol/news/': 'news-es',
1318
'https://www.freecodecamp.org/italian/news/': 'news-it',
1419
'https://www.freecodecamp.org/japanese/news/': 'news-ja',
@@ -96,6 +101,30 @@ export const formatHashnodePost = (post) => {
96101
};
97102
};
98103

104+
export const getBaseSiteURL = (url) => {
105+
const URLObj = new URL(url);
106+
const { host, pathname } = URLObj;
107+
const pathParts = pathname.split('/').filter(Boolean);
108+
let siteLang;
109+
if (host.startsWith('chinese')) {
110+
siteLang = 'chinese';
111+
} else if (pathParts.length === 3) {
112+
// Webhooks will only be triggered by posts, so the path will
113+
// always have 3 parts for our localized instances:
114+
// (/<lang>/news/<slug>/).
115+
// Or if it's coming from a Dockerized test instance / localhost,
116+
// it will only have 1 part: (/<slug>/).
117+
siteLang = pathParts[0];
118+
}
119+
const computedPath = siteLang ? `/${siteLang}/news/` : '/news/';
120+
121+
if (host.startsWith('localhost')) {
122+
return `http://${host}${computedPath}`;
123+
} else {
124+
return `https://www.freecodecamp.org${computedPath}`;
125+
}
126+
};
127+
99128
export const formatGhostPost = (post) => {
100129
const {
101130
id,
@@ -107,22 +136,7 @@ export const formatGhostPost = (post) => {
107136
feature_image,
108137
published_at
109138
} = post;
110-
const URLObj = new URL(url);
111-
const { href, origin, pathname } = URLObj;
112-
const pathParts = pathname.split('/').filter(Boolean);
113-
let siteLang;
114-
if (href.startsWith('https://chinese.freecodecamp.org/')) {
115-
siteLang = 'chinese';
116-
} else if (pathParts.length === 3) {
117-
// Webhooks will only be triggered by posts, so the path will
118-
// always have 3 parts for our localized instances:
119-
// (/<lang>/news/<slug>/).
120-
// Or if it's coming from a Dockerized test instance, it will
121-
// only have 1 part: (/<slug>/).
122-
siteLang = pathParts[0];
123-
}
124-
const siteURL = `${origin}/${siteLang ? `${siteLang}/` : ''}news/`;
125-
console.log({ siteURL, siteLang, href, origin, pathname, pathParts });
139+
const siteURL = getBaseSiteURL(url);
126140

127141
return {
128142
objectID: id,

Diff for: packages/ghost/delete-record/index.js

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
// The ../../../lib/utils directory is zipped in the same directory
22
// as the function during the build process
3-
import { algoliaClient, getSearchIndexName } from './utils/helpers.js';
3+
import {
4+
algoliaClient,
5+
getBaseSiteURL,
6+
getSearchIndexName
7+
} from './utils/helpers.js';
48

59
export const deleteRecord = async (req) => {
610
try {
@@ -15,13 +19,16 @@ export const deleteRecord = async (req) => {
1519
// Whether a published post is unpublished or deleted, the
1620
// status will be 'published' in the previous state
1721
if (prevState.status === 'published') {
18-
// Deleted posts don't include a url. But since every
19-
// post must include at least one author, set the index
20-
// based on the primary author page url instead
21-
const primaryAuthorUrl = prevState.authors
22+
// Deleted posts don't include a url or a primary author object.
23+
// But since every post returns an author array, we can use
24+
// the first author object to determine the search index name.
25+
// This helps since we're handling data from localhost,
26+
// chinese.freecodecamp.org, and www.freecodecamp.org.
27+
const primaryAuthorURL = prevState.authors
2228
? prevState.authors[0].url
2329
: currState.authors[0].url;
24-
const indexName = getSearchIndexName(primaryAuthorUrl);
30+
const siteURL = getBaseSiteURL(primaryAuthorURL);
31+
const indexName = getSearchIndexName(siteURL);
2532

2633
if (!indexName) {
2734
throw new Error('No matching index found for the current post');

0 commit comments

Comments
 (0)