Skip to content

Commit

Permalink
Merge branch 'develop' into feature/polylang-hreflang-integration
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholasio committed Mar 4, 2024
2 parents 5244b95 + 95d6eb9 commit ea1b3e9
Show file tree
Hide file tree
Showing 11 changed files with 435 additions and 64 deletions.
6 changes: 6 additions & 0 deletions .changeset/lucky-doors-applaud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@headstartwp/core": patch
"@headstartwp/next": patch
---

fix: make convertUrl and removeSourceUrl respect the original link's trailingslash
5 changes: 5 additions & 0 deletions .changeset/tiny-avocados-unite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@headstartwp/headstartwp": patch
---

Fix redirect loop for invalid sitemap paths
30 changes: 30 additions & 0 deletions packages/core/src/utils/__tests__/removeSourceUrl.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
import { removeSourceUrl } from '..';

describe('removeSourceUrl', () => {
it('returns empty string without nonEmptyLink', () => {
expect(
removeSourceUrl({
link: 'https://test.com/test',
backendUrl: 'https://test.com/test',
nonEmptyLink: false,
}),
).toBe('');
});
it('removes source url', () => {
expect(
removeSourceUrl({
link: 'https://test.com/test',
backendUrl: 'https://test.com/test',
}),
).toBe('/');

expect(
removeSourceUrl({
link: 'http://backendurl.com',
backendUrl: 'https://backendurl.com',
}),
).toBe('/');

expect(
removeSourceUrl({
link: 'http://backendurl.com/',
Expand Down Expand Up @@ -44,6 +67,13 @@ describe('removeSourceUrl', () => {
}),
).toBe('/post-name-1?a=1&b=3&d=3');

expect(
removeSourceUrl({
link: 'http://backendurl.com/post-name-1?a=1&b=3&d=3/',
backendUrl: 'https://backendurl.com/',
}),
).toBe('/post-name-1?a=1&b=3&d=3/');

expect(
removeSourceUrl({
link: 'http://backendurl.com/post-name-1#id',
Expand Down
43 changes: 36 additions & 7 deletions packages/core/src/utils/removeSourceUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ export type removeSourceUrlType = {
* The public url. Defaults to '/'.
*/
publicUrl?: string;

/**
* If the removal of source url from link leads to a empty string,
* this setting control whether a '/' should be returned or the empty string
*/
nonEmptyLink?: boolean;
};

/**
Expand All @@ -25,39 +31,62 @@ export type removeSourceUrlType = {
*
* @see https://github.com/frontity/frontity/blob/dev/packages/components/link/utils.ts
*
* @param props.link The link that might contain the sourceUrl
* @param props.backendUrl The source url
* @param props.publicUrl The public url
* @param props.nonEmptyLinks If the removal of source url from link leads to a empty string,
* this setting control whether a '/' should be returned or the empty string
*
* @returns The URL without the Source URL.
*/
export function removeSourceUrl({ link, backendUrl, publicUrl = '/' }: removeSourceUrlType) {
if (typeof link === 'undefined') {
export function removeSourceUrl({
link: originalLink,
backendUrl,
publicUrl = '/',
nonEmptyLink = true,
}: removeSourceUrlType) {
if (typeof originalLink === 'undefined') {
warn('link is undefined, double check if you are passing a valid value');
return '';
}

if (typeof backendUrl === 'undefined') {
warn('backendUrl is undefined, double check if you are passing a valid value');
return link;
return originalLink;
}

// Ensure `sourceUrl` and `publicUrl` always include a trailing slash. All
// the logic below is based on those variables fulfilling that condition.
const sourceUrl = backendUrl.replace(/\/?$/, '/');
const appUrl = publicUrl.replace(/\/?$/, '/');

if (sourceUrl === '/' || link.startsWith('#')) {
return link;
if (sourceUrl === '/' || originalLink.startsWith('#')) {
return originalLink;
}

const { host: sourceHost, pathname: sourcePath } = new URL(sourceUrl);
const { pathname: appPath } = new URL(appUrl, sourceUrl);

// we need to know if the original link has trailing slash or not
const hasTrailingSlash = /\/$/.test(originalLink);
const link = !hasTrailingSlash ? `${originalLink}/` : originalLink;
const linkUrl = new URL(link, sourceUrl);

// Compare just the host and the pathname. This way we ignore the protocol if
// it doesn't match.
if (linkUrl.host === sourceHost && linkUrl.pathname.startsWith(sourcePath)) {
return linkUrl.pathname.replace(sourcePath, appPath) + linkUrl.search + linkUrl.hash;
let transformedLink =
linkUrl.pathname.replace(sourcePath, appPath) + linkUrl.search + linkUrl.hash;

transformedLink = hasTrailingSlash ? transformedLink : transformedLink.replace(/\/?$/, '');

if (nonEmptyLink && transformedLink === '') {
return '/';
}

return transformedLink;
}

// Do not change the link for other cases.
return link;
return originalLink;
}
4 changes: 3 additions & 1 deletion packages/next/src/components/Yoast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ export function convertUrl(url: string, hostUrl: string, sourceUrl: string) {
}

return `${hostUrl}${removeSourceUrl({
link: url.replace(/\/?$/, '/'),
link: url,
publicUrl: hostUrl,
backendUrl: sourceUrl,
nonEmptyLink: false,
})}`;
}

Expand Down
54 changes: 49 additions & 5 deletions packages/next/src/components/__tests__/Yoast.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,60 @@
import { convertUrl } from '../Yoast';

describe('convertUrl', () => {
it('root works without trailing slash', () => {
it('works without trainling slash', () => {
expect(
convertUrl('https://test.com/test', 'https://test.test.com', 'https://test.com/test'),
).toBe('https://test.test.com/');
convertUrl(
'https://backendurl.com/test',
'https://publicurl.com',
'https://backendurl.com/test',
),
).toBe('https://publicurl.com');

// a subsite on test.com/site1
expect(
convertUrl(
'https://backendurl.com/site1/post-name-1',
'https://publicurl.com',
'https://backendurl.com/site1',
),
).toBe('https://publicurl.com/post-name-1');

// front-end with subdomain
expect(
convertUrl(
'https://backendurl.com/site1/post-name-1',
'https://site1.publicurl.com',
'https://backendurl.com/site1',
),
).toBe('https://site1.publicurl.com/post-name-1');
});

it('root works with trailing slash', () => {
expect(
convertUrl('https://test.com/test/', 'https://test.test.com', 'https://test.com/test'),
).toBe('https://test.test.com/');
convertUrl(
'https://backendurl.com/test/',
'https://publicurl.com',
'https://backendurl.com/test',
),
).toBe('https://publicurl.com/');

// a subsite on test.com/site1
expect(
convertUrl(
'https://backendurl.com/site1/post-name-1/',
'https://publicurl.com',
'https://backendurl.com/site1',
),
).toBe('https://publicurl.com/post-name-1/');

// front-end with subdomain
expect(
convertUrl(
'https://backendurl.com/site1/post-name-1/',
'https://site1.publicurl.com',
'https://backendurl.com/site1',
),
).toBe('https://site1.publicurl.com/post-name-1/');
});

it('external url returns external url', () => {
Expand Down
11 changes: 9 additions & 2 deletions wp/headless-wp/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
}
],
"require": {
"php": ">=8"
"php": ">=8",
"yoast/wordpress-seo": "^22.1"
},
"repositories": [
{
Expand Down Expand Up @@ -52,7 +53,13 @@
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
"dealerdirect/phpcodesniffer-composer-installer": true,
"composer/installers": true
}
},
"extra": {
"installer-paths": {
"vendor/{$name}/": ["type:wordpress-plugin"]
}
}
}
Loading

0 comments on commit ea1b3e9

Please sign in to comment.