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

Pcc 1752 article url from content structure #332

Open
wants to merge 34 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
3461eb8
Renjith | Add content structure to article path
renjithvwarrier Jan 15, 2025
ebb868b
Renjith
renjithvwarrier Jan 15, 2025
d25c69e
Renjith | Fix tests and add another test to test the ability to map c…
renjithvwarrier Jan 15, 2025
6d753f7
Renjith
renjithvwarrier Jan 17, 2025
728fa37
Renjith | Add content strucutre path to nextjs-starter-approuter-ts s…
renjithvwarrier Jan 20, 2025
b776b42
Renjith | Update comments on articles url
renjithvwarrier Jan 20, 2025
f36000b
Renjith | Update tests in nextjs-starter-ts
renjithvwarrier Jan 20, 2025
ce7ae8d
Refactor site fetching in Next.js starter to remove environment varia…
renjithvwarrier Jan 20, 2025
54c4120
Renjith | Simplify return statement
renjithvwarrier Jan 20, 2025
96d9989
Renjith | Reformat utils and command.js
renjithvwarrier Jan 20, 2025
9dced14
Renjith | Export getPanthonAPIOptions using a seperate statement
renjithvwarrier Jan 20, 2025
b39c49c
Renjith | Disable codacy unnecessary blocks
renjithvwarrier Jan 20, 2025
ad577a2
Renjith | Add the codacy disable line before return
renjithvwarrier Jan 20, 2025
29ab0a1
Renjith | Add the codacy disable line before return
renjithvwarrier Jan 20, 2025
41ca572
Renjith | Add the codacy disable line before return
renjithvwarrier Jan 20, 2025
8d74ecf
Merge branch 'main' into PCC-1752-article-url-from-contentStructure
renjithvwarrier Jan 20, 2025
f2a6005
Refactor API options in Pantheon Cloud handler to remove unused type …
renjithvwarrier Jan 20, 2025
96b2b7d
Renjith | Update pnpm-lock.yal
renjithvwarrier Jan 20, 2025
e9e4c5d
Renjith | Override next to 14.2.23
renjithvwarrier Jan 20, 2025
34c6d99
Renjith | Unify babael core
renjithvwarrier Jan 20, 2025
54cd966
Renjith | Update pnpm-lock.yaml
renjithvwarrier Jan 20, 2025
d087a9c
Renjith | Update path-to-regexp
renjithvwarrier Jan 20, 2025
296165c
Renjith | Change revalidate to revalidateSeconds as per PR suggestion
renjithvwarrier Jan 21, 2025
748088c
Fix function name typo from 'doesCHildContainArticle' to 'doesChildCo…
renjithvwarrier Jan 21, 2025
fec742e
Renjith | Update the core-sdk to have the function to get article URLs
renjithvwarrier Jan 21, 2025
2c58906
Renjith | Expose the new article URL functionality functions from cor…
renjithvwarrier Jan 21, 2025
23d2759
Renjith | Change the nextjs-starter-approuter to use the new article …
renjithvwarrier Jan 21, 2025
a649bd1
Renjith | Update nextjs-starter-ts to use the new content structure u…
renjithvwarrier Jan 21, 2025
2dcda26
Renjith | Move nextjs-starter to the updated sdk utility functions
renjithvwarrier Jan 21, 2025
fd57e45
Renjith | Change revalidateSeconds to revalidate
renjithvwarrier Jan 21, 2025
a407141
Renjith | Changeset
renjithvwarrier Jan 21, 2025
767028c
Renjith | Add Changeset
renjithvwarrier Jan 21, 2025
b982134
Renjith | Force running Wix
renjithvwarrier Jan 28, 2025
8430e4e
Renjith | Force running Wix
renjithvwarrier Jan 28, 2025
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
14 changes: 14 additions & 0 deletions .changeset/dull-chicken-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
"@pantheon-systems/next-approuter-pcc-starter-ts": minor
"@pantheon-systems/pcc-react-sdk": minor
"@pantheon-systems/pcc-sdk-core": minor
---

- Added functionality in the pcc-sdk-core to compute the path of an article from
the site's content structure. This will be the path at which the article will
be visible.
- If someone tries to access the article without the full path, it will be
redirected to the full path.
- Developers can use the default functionality as is and also customise the path
generation to only include the id or slug and a configurable number of
parents.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@
"@pantheon-systems/pcc-react-sdk>yaml": ">=2.2.2",
"@pantheon-systems/pcc-react-sdk>prettier": "^3.0.0",
"webpack-dev-middleware": "^7.2.1",
"@pantheon-systems/pcc-vue-sdk>ufo": "1.5.3"
"@pantheon-systems/pcc-vue-sdk>ufo": "1.5.3",
"next": "14.2.23",
"@babel/core": "7.26.0",
"path-to-regexp": "0.1.12"
}
}
}
2 changes: 2 additions & 0 deletions packages/core/__tests__/core/pantheon-api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ const mockRequest = {
vi.mock("../../src/helpers/", () => ({
PCCConvenienceFunctions: {
buildPantheonClient: vi.fn(),
getSite: vi.fn(),
},
getArticleBySlugOrId: vi.fn(),
getArticleURLFromSite: vi.fn(),
}));

vi.mock("../../src/lib/jwt", () => ({
Expand Down
153 changes: 153 additions & 0 deletions packages/core/__tests__/helpers/article-url.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { getArticleURLFromSite } from "../../src/helpers";
import { Site } from "../../src/types";

describe("Article URL generation from Site content structure", () => {
it("should generate the correct URL for an article from a site which has no content structure", () => {
// Define a site without a content structure
const site: Site = {
id: "123",
name: "test",
url: "https://test.com",
domain: "test.com",
tags: [],
metadataFields: {},
contentStructure: {
active: [],
},
};

const article = {
id: "test-article",
slug: "my-article",
};

const articleURL = getArticleURLFromSite(article, site);

expect(articleURL).toBe("/articles/my-article");
});

it("should generate the correct URL for an article from a site which has a content structure", () => {
// Define a site with a content structure
const site: Site = {
id: "123",
name: "test",
url: "https://test.com",
domain: "test.com",
tags: [],
metadataFields: {},
contentStructure: {
active: [
{
id: "category-1",
name: "foo",
type: "category",
children: [
{
id: "nested-category-1",
name: "bar",
type: "category",
children: [
{ id: "test-article", name: "baz", type: "article" },
],
},
],
},
],
},
};

const article = {
id: "test-article",
slug: "my-article",
};

const articleURL = getArticleURLFromSite(article, site);

expect(articleURL).toBe("/articles/foo/bar/my-article");
});

it("should generate the correct URL for an article from a site which has a content structure with a base path", () => {
// Define a site with a content structure
const site: Site = {
id: "123",
name: "test",
url: "https://test.com",
domain: "test.com",
tags: [],
metadataFields: {},
contentStructure: {
active: [
{
id: "category-1",
name: "foo",
type: "category",
children: [
{
id: "nested-category-1",
name: "bar",
type: "category",
children: [
{ id: "test-article", name: "baz", type: "article" },
],
},
],
},
],
},
};

const article = {
id: "test-article",
slug: "my-article",
};

const basePath = "/test-articles";

const articleURL = getArticleURLFromSite(article, site, basePath);
expect(articleURL).toBe(`${basePath}/foo/bar/my-article`);
});

it("should generate URL with maxDepth", () => {
// Define a site with a content structure
const site: Site = {
id: "123",
name: "test",
url: "https://test.com",
domain: "test.com",
tags: [],
metadataFields: {},
contentStructure: {
active: [
{
id: "category-1",
name: "foo",
type: "category",
children: [
{
id: "nested-category-1",
name: "bar",
type: "category",
children: [
{ id: "test-article", name: "baz", type: "article" },
],
},
],
},
],
},
};

const article = {
id: "test-article",
slug: "my-article",
};

const basePath = "/test-articles";

const articleURL = getArticleURLFromSite(article, site, basePath, 0);
expect(articleURL).toBe(`${basePath}/my-article`);

const articleURL2 = getArticleURLFromSite(article, site, basePath, 1);
expect(articleURL2).toBe(`${basePath}/bar/my-article`);
});
});
24 changes: 16 additions & 8 deletions packages/core/src/core/pantheon-api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import queryString from "query-string";
import { getArticleBySlugOrId, PCCConvenienceFunctions } from "../helpers";
import {
getArticleBySlugOrId,
getArticleURLFromSite,
PCCConvenienceFunctions,
} from "../helpers";
import { parseJwt } from "../lib/jwt";
import { Article, MetadataGroup, SmartComponentMap } from "../types";
import { Article, MetadataGroup, Site, SmartComponentMap } from "../types";
import { PantheonClient, PantheonClientConfig } from "./pantheon-client";

export interface ApiRequest {
Expand Down Expand Up @@ -45,7 +49,7 @@ type HeaderValue = string | string[] | number | undefined;

export interface PantheonAPIOptions {
/**
* A function that takes a PCC article ID and returns the path on your site
* A function that takes a PCC article ID (or and the site) and returns the path on your site
* where the article is hosted.
*
* @example
Expand All @@ -55,8 +59,10 @@ export interface PantheonAPIOptions {
* @default (article) => `/articles/${article.id}` (if not provided)
*
*/
resolvePath?: (article: Partial<Article> & Pick<Article, "id">) => string;

resolvePath?: (
article: Partial<Article> & Pick<Article, "id">,
site: Site,
) => string;
/**
* A function which returns the PCC site id currently in use.
*/
Expand Down Expand Up @@ -98,8 +104,7 @@ const defaultOptions = {
isClientSide: false,
...props,
}),
resolvePath: (article: Partial<Article> & Pick<Article, "id">) =>
`/articles/${article.id}`,
resolvePath: getArticleURLFromSite,
// eslint-disable-next-line turbo/no-undeclared-env-vars
getSiteId: () => process.env.PCC_SITE_ID as string,
notFoundPath: "/404",
Expand Down Expand Up @@ -197,7 +202,10 @@ export const PantheonAPI = (givenOptions?: PantheonAPIOptions) => {
return res.redirect(302, options.notFoundPath);
}

const resolvedPath = options.resolvePath(article);
// Fetch the site
const site = await PCCConvenienceFunctions.getSite();
// Define the resolved path
const resolvedPath = options.resolvePath(article, site);

return await res.redirect(
302,
Expand Down
Loading
Loading