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

feat(sitemap): Add a new configuration to discard invalid patterns from sitemap and avoid duplicate content #176

Merged
merged 4 commits into from
Aug 3, 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
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,16 @@ To see all the types you can choose from, run `strapi content-types:list`.

> `required:` NO | `type:` array

### Exclude invalid relations relational objects
This setting allow you to exclude invalid entries when the pattern is not valid for the entry

Example : You have added a `slug` property to the configuration entry `allowedFields`.
If a content doesn't have the field `slug` filled, no entry in the sitemap will be generated for this content (to avoid duplicate content)

###### Key: `discardInvalidRelations `

> `required:` NO | `type:` boolean

## 🤝 Contributing

Feel free to fork and make a pull request of this plugin. All the input is welcome!
Expand Down
1 change: 1 addition & 0 deletions server/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = {
autoGenerate: false,
caching: true,
allowedFields: ['id', 'uid'],
discardInvalidRelations: false,
excludedTypes: [
'admin::permission',
'admin::role',
Expand Down
36 changes: 36 additions & 0 deletions server/services/__tests__/pattern.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@

const patternService = require('../pattern');

const get = function baseGet(object, path) {
let index = 0;
path = path.split('.');
const length = path.length;

while (object != null && index < length) {
const newKey = path[index++];
object = object[newKey];
}
return (index && index === length) ? object : undefined;
};

global.strapi = {
contentTypes: {
'another-test-relation:target:api': {
Expand All @@ -28,6 +40,14 @@ global.strapi = {
},
},
},
config: {
plugin: {
sitemap: {
discardInvalidRelations: false
}
},
get: ((key) => get(global.strapi.config, key)),
}
};

describe('Pattern service', () => {
Expand Down Expand Up @@ -151,6 +171,22 @@ describe('Pattern service', () => {

expect(result).toMatch('/en/my-page-slug');
});

test('Resolve pattern with missing relation', async () => {
const pattern = '/en/[slug]';
const entity = {
title: "my-page-title",
};

global.strapi.config.plugin.sitemap.discardInvalidRelations = true;

const result = await patternService().resolvePattern(pattern, entity);

expect(result).toBe(null);

// Restore
global.strapi.config.plugin.sitemap.discardInvalidRelations = false;
});
});
describe('Validate pattern', () => {
test('Should return { valid: true } for a valid pattern', async () => {
Expand Down
2 changes: 2 additions & 0 deletions server/services/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ const getLanguageLinks = async (config, page, contentType, defaultURL) => {

const { pattern } = config.contentTypes[contentType]['languages'][locale];
const translationUrl = await strapi.plugins.sitemap.services.pattern.resolvePattern(pattern, translation);
if (!translationUrl) return null;
let hostnameOverride = config.hostname_overrides[translation.locale] || '';
hostnameOverride = hostnameOverride.replace(/\/+$/, '');
links.push({
Expand Down Expand Up @@ -112,6 +113,7 @@ const getSitemapPageData = async (config, page, contentType) => {

const { pattern } = config.contentTypes[contentType]['languages'][locale];
const path = await strapi.plugins.sitemap.services.pattern.resolvePattern(pattern, page);
if (!path) return null;
let hostnameOverride = config.hostname_overrides[page.locale] || '';
hostnameOverride = hostnameOverride.replace(/\/+$/, '');
const url = `${hostnameOverride}${path}`;
Expand Down
18 changes: 16 additions & 2 deletions server/services/pattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,19 +124,33 @@ const getRelationsFromPattern = (pattern) => {

const resolvePattern = async (pattern, entity) => {
const fields = getFieldsFromPattern(pattern);
let errorInPattern = false;

fields.map((field) => {
const relationalField = field.split('.').length > 1 ? field.split('.') : null;

if (!relationalField) {
pattern = pattern.replace(`[${field}]`, entity[field] || '');
const replacement = entity[field] || '';
if (strapi.config.get('plugin.sitemap.discardInvalidRelations') && !replacement) {
errorInPattern = true;
return;
}
pattern = pattern.replace(`[${field}]`, replacement);
} else if (Array.isArray(entity[relationalField[0]])) {
strapi.log.error(logMessage('Something went wrong whilst resolving the pattern.'));
} else if (typeof entity[relationalField[0]] === 'object') {
pattern = pattern.replace(`[${field}]`, entity[relationalField[0]] && entity[relationalField[0]][relationalField[1]] ? entity[relationalField[0]][relationalField[1]] : '');
const replacement = entity[relationalField[0]] && entity[relationalField[0]][relationalField[1]] ? entity[relationalField[0]][relationalField[1]] : '';
if (strapi.config.get('plugin.sitemap.discardInvalidRelations') && !replacement) {
errorInPattern = true;
return;
}

pattern = pattern.replace(`[${field}]`, replacement);
}
});

if (errorInPattern) return null; // Return null if there was an error in the pattern due to invalid relation and avoid duplicate content

pattern = pattern.replace(/\/+/g, '/'); // Remove duplicate forward slashes.
pattern = pattern.startsWith('/') ? pattern : `/${pattern}`; // Make sure we only have on forward slash.
return pattern;
Expand Down
Loading