mirror of
https://github.com/ComfortablyCoding/strapi-plugin-slugify.git
synced 2025-07-05 00:01:10 -04:00
Compare commits
2 Commits
ccb31f7389
...
2d53829e94
Author | SHA1 | Date | |
---|---|---|---|
|
2d53829e94 | ||
|
9c336ebb1d |
@ -47,7 +47,7 @@
|
||||
"kind": "plugin"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.x.x <=16.x.x",
|
||||
"node": ">=14.19.1 <=18.x.x",
|
||||
"npm": ">=6.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
|
@ -2,8 +2,15 @@
|
||||
|
||||
const { buildSettings } = require('./buildSettings');
|
||||
const { setupLifecycles } = require('./setupLifecycles');
|
||||
const { syncSlugCount } = require('./syncSlugCount');
|
||||
|
||||
module.exports = async () => {
|
||||
const settings = await buildSettings();
|
||||
|
||||
if (settings.slugifyWithCount) {
|
||||
// Ensure correct count used for old plugin versions and projects with existing slugs.
|
||||
await syncSlugCount(settings);
|
||||
}
|
||||
|
||||
module.exports = async ({ strapi }) => {
|
||||
const settings = await buildSettings(strapi);
|
||||
setupLifecycles(settings);
|
||||
};
|
||||
|
75
server/bootstrap/syncSlugCount.js
Normal file
75
server/bootstrap/syncSlugCount.js
Normal file
@ -0,0 +1,75 @@
|
||||
'use strict';
|
||||
|
||||
const syncSlugCount = async (settings) => {
|
||||
const entries = await strapi.entityService.findMany('plugin::slugify.slug', {
|
||||
filters: { createdAt: { $gt: 1 } },
|
||||
});
|
||||
|
||||
// if entries aready present we can skip sync
|
||||
if (entries && entries.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
strapi.log.info('[slugify] syncing slug count for registered content types');
|
||||
|
||||
const slugs = new Map();
|
||||
|
||||
// chec slugs in each reigistered model
|
||||
for (const uid in settings.modelsByUID) {
|
||||
if (!Object.hasOwnProperty.call(settings.modelsByUID, uid)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const model = settings.modelsByUID[uid];
|
||||
|
||||
// using db query to avoid the need to check if CT has draftAndPublish enabled
|
||||
const modelEntries = await strapi.db.query(model.uid).findMany({
|
||||
filters: { createdAt: { $gt: 1 } },
|
||||
});
|
||||
|
||||
strapi.log.info(`[slugify] syncing slug count for ${model.uid}`);
|
||||
for (const entry of modelEntries) {
|
||||
const slug = entry[model.field];
|
||||
if (!slug) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const record = slugs.get(getNonAppendedSlug(slug));
|
||||
if (!record) {
|
||||
slugs.set(slug, { slug, count: 1 });
|
||||
continue;
|
||||
}
|
||||
|
||||
slugs.set(record.slug, { slug: record.slug, count: record.count + 1 });
|
||||
}
|
||||
strapi.log.info(`[slugify] sync for ${model.uid} completed`);
|
||||
}
|
||||
|
||||
if (slugs.size) {
|
||||
// create all required records
|
||||
const createResponse = await strapi.db.query('plugin::slugify.slug').createMany({
|
||||
data: [...slugs.values()],
|
||||
});
|
||||
|
||||
strapi.log.info(
|
||||
`[slugify] ${createResponse.count} out of ${slugs.size} slugs synced successfully`
|
||||
);
|
||||
} else {
|
||||
strapi.log.info('[slugify] No syncable slugs found');
|
||||
}
|
||||
};
|
||||
|
||||
// removes any appended number from a slug/string if found
|
||||
const getNonAppendedSlug = (slug) => {
|
||||
const match = slug.match('[\\-]{1}[\\d]+$');
|
||||
|
||||
if (!match) {
|
||||
return slug;
|
||||
}
|
||||
|
||||
return slug.replace(match[0], '');
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
syncSlugCount,
|
||||
};
|
9
server/content-types/index.js
Normal file
9
server/content-types/index.js
Normal file
@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
const slugSchema = require('./slug/schema.json');
|
||||
|
||||
module.exports = {
|
||||
slug: {
|
||||
schema: slugSchema,
|
||||
},
|
||||
};
|
29
server/content-types/slug/schema.json
Normal file
29
server/content-types/slug/schema.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"kind": "collectionType",
|
||||
"collectionName": "slugs",
|
||||
"info": {
|
||||
"singularName": "slug",
|
||||
"pluralName": "slugs",
|
||||
"displayName": "slug"
|
||||
},
|
||||
"options": {
|
||||
"draftAndPublish": false,
|
||||
"comment": ""
|
||||
},
|
||||
"pluginOptions": {
|
||||
"content-manager": {
|
||||
"visible": false
|
||||
},
|
||||
"content-type-builder": {
|
||||
"visible": false
|
||||
}
|
||||
},
|
||||
"attributes": {
|
||||
"slug": {
|
||||
"type": "text"
|
||||
},
|
||||
"count": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
const bootstrap = require('./bootstrap');
|
||||
const config = require('./config');
|
||||
const contentTypes = require('./content-types');
|
||||
const controllers = require('./controllers');
|
||||
const register = require('./register');
|
||||
const routes = require('./routes');
|
||||
@ -10,6 +11,7 @@ const services = require('./services');
|
||||
module.exports = {
|
||||
bootstrap,
|
||||
config,
|
||||
contentTypes,
|
||||
controllers,
|
||||
register,
|
||||
routes,
|
||||
|
40
server/services/slug-service/buildSlug.js
Normal file
40
server/services/slug-service/buildSlug.js
Normal file
@ -0,0 +1,40 @@
|
||||
const slugify = require('@sindresorhus/slugify');
|
||||
|
||||
const buildSlug = async (string, settings) => {
|
||||
let slug = slugify(string, settings.slugifyOptions);
|
||||
|
||||
// slugify with count
|
||||
if (!settings.slugifyWithCount) {
|
||||
return slug;
|
||||
}
|
||||
|
||||
const slugEntry = await strapi.db.query('plugin::slugify.slug').findOne({
|
||||
select: ['id', 'count'],
|
||||
where: { slug },
|
||||
});
|
||||
|
||||
// if no result then count is 1 and base slug is returned
|
||||
if (!slugEntry) {
|
||||
await strapi.entityService.create('plugin::slugify.slug', {
|
||||
data: {
|
||||
slug,
|
||||
count: 1,
|
||||
},
|
||||
});
|
||||
|
||||
return slug;
|
||||
}
|
||||
|
||||
const count = slugEntry.count + 1;
|
||||
await strapi.entityService.update('plugin::slugify.slug', slugEntry.id, {
|
||||
data: {
|
||||
count,
|
||||
},
|
||||
});
|
||||
|
||||
return `${slug}-${count}`;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
buildSlug,
|
||||
};
|
@ -1,10 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const { toSlug } = require('../../utils/slugification');
|
||||
const { getPluginService } = require('../../utils/getPluginService');
|
||||
const { shouldUpdateSlug } = require('./shoudUpdateSlug');
|
||||
const { getReferenceFieldValues } = require('./getReferenceFieldValues');
|
||||
const { buildSlug } = require('./buildSlug');
|
||||
|
||||
module.exports = ({ strapi }) => ({
|
||||
async slugify(ctx) {
|
||||
@ -40,13 +40,10 @@ module.exports = ({ strapi }) => ({
|
||||
}
|
||||
|
||||
referenceFieldValues = referenceFieldValues.join(' ');
|
||||
const toSlugOptions = settings.slugifyOptions;
|
||||
if (settings.slugifyWithCount) {
|
||||
toSlugOptions.slugifyWithCount = settings.slugifyWithCount;
|
||||
}
|
||||
|
||||
// update slug field based on action type
|
||||
const slug = toSlug(referenceFieldValues, toSlugOptions);
|
||||
const slug = await buildSlug(referenceFieldValues, settings);
|
||||
|
||||
if (ctx.action === 'beforeCreate' || ctx.action === 'beforeUpdate') {
|
||||
data[field] = slug;
|
||||
} else if (ctx.action === 'afterCreate') {
|
||||
|
@ -1,18 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const slugify = require('@sindresorhus/slugify');
|
||||
const slugifyWithCount = slugify.counter();
|
||||
|
||||
const toSlug = (string, options) => {
|
||||
if (options.slugifyWithCount) {
|
||||
_.omit(options, 'slugifyWithCount');
|
||||
return slugifyWithCount(string, options);
|
||||
}
|
||||
|
||||
return slugify(string, options);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
toSlug,
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user