Reputation: 69
I want to create a slug for the url as soon as the user adds an event from the frontend. The slug is based on the name of the event. How to do that in V4 as the old method does not work now?
Slug creation link - old version
Upvotes: 2
Views: 4242
Reputation: 73
In your Strapi project, you can create a lifecycles.js file inside the api/collection-name/content-type/collection-name folder. In this file, you can define the lifecycle methods to be executed for the specified content type.
module.exports = {
async beforeCreate(event) {
// Generate slug using the 'plugin::content-manager.uid' service
const slug = await strapi.service('plugin::content-manager.uid').generateUIDField({
contentTypeUID: 'api::product.product'// Replace 'product' with your collection name,
field: 'slug', // Replace 'slug' with the desired field name
data: event.params.data
});
// Assign the generated slug to the 'slug' field
event.params.data.slug = slug;
// Assign the generated slug to the 'slug2' field (if needed)
event.params.data.slug2 = slug;
}
};
Explanation:
The beforeCreate method is a lifecycle hook that is triggered before creating a new entry in the specified collection.
The beforeCreate method is a lifecycle hook that is triggered before creating a new entry in the specified collection.
Inside the beforeCreate method, the generateUIDField method from the plugin::content-manager.uid service is used to generate a unique slug for the entry.
The generateUIDField method requires the contentTypeUID, field, and data parameters. Make sure to replace 'product' with your actual collection name and 'slug' with the desired field name.
The generated slug is assigned to the slug field of the event.params.data object, which represents the data for the new entry.
If you need to assign the same slug to another field (e.g., slug2), you can add a line to assign the slug value to that field as well.
Note: Please make sure that the file is named lifecycles.js and placed in the correct folder structure as mentioned above.
Feel free to adjust the code according to your specific requirements, such as field names and collection names.
Upvotes: 2
Reputation: 5687
This seem to work for me
Settings > Roles > Public > Slugify (checkbox findSlug) config/plugins.js
module.exports = ({ env }) => ({
slugify: {
enabled: true,
config: {
contentTypes: {
page: {
field: "slug",
references: "name",
},
post: {
field: "slug",
references: "name",
},
category: {
field: "slug",
references: "name",
},
},
},
},
});
graphql
const POSTS = gql`
query GetPosts {
posts {
... on PostEntityResponseCollection {
data {
__typename
id
attributes {
__typename
name
slug
content
featuredImage {
data {
__typename
id
attributes {
url
alternativeText
caption
}
}
}
createdAt
}
}
}
}
}
`;
const POST = gql`
query GetPost($slug: String!) {
findSlug(modelName: "post", slug: $slug, publicationState: "live") {
... on PostEntityResponse {
data {
__typename
id
attributes {
createdAt
name
slug
content
seo {
__typename
id
title
description
blockSearchIndexing
}
categories {
__typename
data {
__typename
id
attributes {
__typename
name
slug
}
}
}
}
}
}
}
}
`;
Upvotes: 3
Reputation: 126
By following the article, it seems that you are trying to add lifecycle events to a model. You would need to make the following modifications to the article to make it work for v4.
After the creation of the article model via the admin dashboard, instead of adding the following file:
./api/article/models/Article.js
add:
./src/api/article/content-types/article/lifecycles.js
With the following:
const slugify = require('slugify');
module.exports = {
async beforeCreate(event) {
if (event.params.data.title) {
event.params.data.slug = slugify(event.params.data.title, {lower: true});
}
},
async beforeUpdate(event) {
if (event.params.data.title) {
event.params.data.slug = slugify(event.params.data.title, {lower: true});
}
},
};
Also the api endpoint changed in v4 so you would need to use:
GET /api/articles?filters[slug]=my-article-slug
Upvotes: 6