Skip to content

Commit

Permalink
Merge pull request #176 from Tyki/master
Browse files Browse the repository at this point in the history
feat(sitemap): Add a new configuration to discard invalid patterns from sitemap and avoid duplicate content
  • Loading branch information
boazpoolman authored Aug 3, 2024
2 parents a22fd57 + fa1ab10 commit e5a3c04
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 2 deletions.
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

2 comments on commit e5a3c04

@SalahAdDin
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this, wasn't this plugin deprecated?

@boazpoolman
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is.
Read my explanation about it here:
#176 (comment)

Please sign in to comment.