Skip to content
This repository was archived by the owner on Sep 16, 2025. It is now read-only.

Commit 9ca09c7

Browse files
fix(slugification): do not update slug once generated (#68)
Attempting to update the slug on updates was causing issues with `slugifyWithCount` increasing the number when it should not. Once a slug is generated it should never be auto updated as it can cause unintended side effects.
1 parent 1b20016 commit 9ca09c7

File tree

5 files changed

+44
-12
lines changed

5 files changed

+44
-12
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Per [#35](https://github.com/ComfortablyCoding/strapi-plugin-slugify/issues/35)
7171
| contentTypes[modelName]field | The name of the field to add the slug | String | N/A | Yes |
7272
| contentTypes[modelName]references | The name(s) of the field(s) used to build the slug. If an array of fields is set it will result in a compound slug | String or Array | N/A | Yes |
7373
| slugifyWithCount | Duplicate strings will have their occurrence appended to the end of the slug | Boolean | false | No |
74+
| shouldUpdateSlug | Allow the slug to be updated after initial generation. | Boolean | false | No |
7475
| skipUndefinedReferences | Skip reference fields that have no data. Mostly applicable to compound slug | Boolean | false | No |
7576
| slugifyOptions | The options to pass the the slugify function. All options can be found in the [slugify docs](https://github.com/sindresorhus/slugify#api) | Object | {} | No |
7677

server/bootstrap.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ module.exports = ({ strapi }) => {
2020
};
2121

2222
SUPPORTED_LIFECYCLES.forEach((lifecycle) => {
23-
subscribe[lifecycle] = (ctx) => {
24-
getPluginService(strapi, 'slugService').slugify(ctx);
23+
subscribe[lifecycle] = async (ctx) => {
24+
await getPluginService(strapi, 'slugService').slugify(ctx);
2525
};
2626
});
2727

server/config/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module.exports = {
88
contentTypes: {},
99
slugifyOptions: {},
1010
slugifyWithCount: false,
11+
shouldUpdateSlug: false,
1112
skipUndefinedReferences: false,
1213
};
1314
},

server/config/schema.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const pluginConfigSchema = yup.object().shape({
1818
return yup.object().shape(shape);
1919
}),
2020
slugifyWithCount: yup.bool(),
21+
shouldUpdateSlug: yup.bool(),
2122
skipUndefinedReferences: yup.bool(),
2223
});
2324

server/services/slug-service.js

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,25 @@ const { getPluginService } = require('../utils/getPluginService');
55
const { toSlug, toSlugWithCount } = require('../utils/slugification');
66

77
module.exports = ({ strapi }) => ({
8-
slugify(ctx) {
8+
async slugify(ctx) {
9+
10+
const { params, model: entityModel } = ctx;
11+
12+
// Check to see if we have an existing reference and if it matches.
13+
let current = null;
14+
if (params.where && params.where.id) {
15+
current = await strapi.entityService.findOne(entityModel.uid, params.where.id)
16+
}
17+
this.update(ctx, current)
18+
},
19+
20+
update(ctx, current) {
21+
922
const settings = getPluginService(strapi, 'settingsService').get();
1023
const { params, model: entityModel } = ctx;
1124
const { data } = params;
1225

1326
const model = settings.models[entityModel.uid];
14-
1527
if (!data) {
1628
return;
1729
}
@@ -23,18 +35,35 @@ module.exports = ({ strapi }) => ({
2335
.filter((r) => typeof data[r] !== 'undefined' && data[r].length)
2436
.map((r) => data[r]);
2537

26-
const hasUndefinedFields = referenceFieldValues.length < references.length;
27-
if ((!settings.skipUndefinedReferences && hasUndefinedFields) || !referenceFieldValues.length) {
28-
return;
38+
39+
let shouldUpdate = true
40+
if (current) {
41+
let currentReferenceFieldValues = references
42+
.filter((r) => typeof current[r] !== 'undefined' && current[r].length)
43+
.map((r) => current[r]);
44+
45+
if (JSON.stringify(referenceFieldValues) == JSON.stringify(currentReferenceFieldValues)) {
46+
shouldUpdate = false
47+
}
2948
}
3049

31-
referenceFieldValues = referenceFieldValues.join(' ');
32-
if (settings.slugifyWithCount) {
33-
data[field] = toSlugWithCount(referenceFieldValues, settings.slugifyOptions);
34-
return;
50+
// Reference the updateSlugs settings to determine if user wants slugs to be updated.
51+
// If there isn't a current reference then proceed.
52+
if ((shouldUpdate && settings.shouldUpdateSlug) || !current || !data[field]) {
53+
const hasUndefinedFields = referenceFieldValues.length < references.length;
54+
if ((!settings.skipUndefinedReferences && hasUndefinedFields) || !referenceFieldValues.length) {
55+
return;
56+
}
57+
58+
referenceFieldValues = referenceFieldValues.join(' ');
59+
if (settings.slugifyWithCount) {
60+
data[field] = toSlugWithCount(referenceFieldValues, settings.slugifyOptions);
61+
return
62+
}
63+
64+
data[field] = toSlug(referenceFieldValues, settings.slugifyOptions);
3565
}
3666

37-
data[field] = toSlug(referenceFieldValues, settings.slugifyOptions);
3867
},
3968

4069
async findOne(uid, query) {

0 commit comments

Comments
 (0)