From 59096c4df19f906ae99c2d7b0e5fce455508c43a Mon Sep 17 00:00:00 2001 From: krckyboy Date: Mon, 18 Mar 2024 17:56:25 +0100 Subject: [PATCH] #13 Added the rest of the config + some comments. --- cms-ts/package-lock.json | 9 ++ cms-ts/package.json | 8 +- .../api/post/content-types/post/lifecycles.ts | 18 ++++ cms-ts/types/generated/contentTypes.d.ts | 96 +++++++++---------- .../[slug]/(blog-content)/BlogContent.tsx | 1 + 5 files changed, 80 insertions(+), 52 deletions(-) create mode 100644 cms-ts/src/api/post/content-types/post/lifecycles.ts diff --git a/cms-ts/package-lock.json b/cms-ts/package-lock.json index 49233de..df82b48 100644 --- a/cms-ts/package-lock.json +++ b/cms-ts/package-lock.json @@ -17,6 +17,7 @@ "react": "^18.0.0", "react-dom": "^18.0.0", "react-router-dom": "5.3.4", + "slugify": "^1.6.6", "styled-components": "5.3.3" }, "devDependencies": {}, @@ -13932,6 +13933,14 @@ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.0.6.tgz", "integrity": "sha512-FOyLWWVjG+aC0UqG76V53yAWdXfH8bO6FNmyZOuUrzDzK8DI3/JRY25UD7+g49JWM1LXwymsKERB+DzI0dTEQA==" }, + "node_modules/slugify": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz", + "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/snake-case": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz", diff --git a/cms-ts/package.json b/cms-ts/package.json index fe10f25..b162f1e 100644 --- a/cms-ts/package.json +++ b/cms-ts/package.json @@ -9,16 +9,16 @@ "build": "strapi build", "strapi": "strapi" }, - "devDependencies": {}, "dependencies": { - "@strapi/strapi": "4.20.5", - "@strapi/plugin-users-permissions": "4.20.5", - "@strapi/plugin-i18n": "4.20.5", "@strapi/plugin-cloud": "4.20.5", + "@strapi/plugin-i18n": "4.20.5", + "@strapi/plugin-users-permissions": "4.20.5", + "@strapi/strapi": "4.20.5", "pg": "8.8.0", "react": "^18.0.0", "react-dom": "^18.0.0", "react-router-dom": "5.3.4", + "slugify": "^1.6.6", "styled-components": "5.3.3" }, "author": { diff --git a/cms-ts/src/api/post/content-types/post/lifecycles.ts b/cms-ts/src/api/post/content-types/post/lifecycles.ts new file mode 100644 index 0000000..95b442c --- /dev/null +++ b/cms-ts/src/api/post/content-types/post/lifecycles.ts @@ -0,0 +1,18 @@ +const slugify = require('slugify'); + +module.exports = { + beforeCreate(event) { + const { data } = event.params; + + if (data.title) { + data.slug = slugify(data.title, { lower: true }); + } + }, + beforeUpdate(event) { + const { data } = event.params; + + if (data.title) { + data.slug = slugify(data.title, { lower: true }); + } + } +}; diff --git a/cms-ts/types/generated/contentTypes.d.ts b/cms-ts/types/generated/contentTypes.d.ts index e789134..838a1b3 100644 --- a/cms-ts/types/generated/contentTypes.d.ts +++ b/cms-ts/types/generated/contentTypes.d.ts @@ -590,6 +590,53 @@ export interface PluginContentReleasesReleaseAction }; } +export interface PluginI18NLocale extends Schema.CollectionType { + collectionName: 'i18n_locale'; + info: { + singularName: 'locale'; + pluralName: 'locales'; + collectionName: 'locales'; + displayName: 'Locale'; + description: ''; + }; + options: { + draftAndPublish: false; + }; + pluginOptions: { + 'content-manager': { + visible: false; + }; + 'content-type-builder': { + visible: false; + }; + }; + attributes: { + name: Attribute.String & + Attribute.SetMinMax< + { + min: 1; + max: 50; + }, + number + >; + code: Attribute.String & Attribute.Unique; + createdAt: Attribute.DateTime; + updatedAt: Attribute.DateTime; + createdBy: Attribute.Relation< + 'plugin::i18n.locale', + 'oneToOne', + 'admin::user' + > & + Attribute.Private; + updatedBy: Attribute.Relation< + 'plugin::i18n.locale', + 'oneToOne', + 'admin::user' + > & + Attribute.Private; + }; +} + export interface PluginUsersPermissionsPermission extends Schema.CollectionType { collectionName: 'up_permissions'; @@ -741,53 +788,6 @@ export interface PluginUsersPermissionsUser extends Schema.CollectionType { }; } -export interface PluginI18NLocale extends Schema.CollectionType { - collectionName: 'i18n_locale'; - info: { - singularName: 'locale'; - pluralName: 'locales'; - collectionName: 'locales'; - displayName: 'Locale'; - description: ''; - }; - options: { - draftAndPublish: false; - }; - pluginOptions: { - 'content-manager': { - visible: false; - }; - 'content-type-builder': { - visible: false; - }; - }; - attributes: { - name: Attribute.String & - Attribute.SetMinMax< - { - min: 1; - max: 50; - }, - number - >; - code: Attribute.String & Attribute.Unique; - createdAt: Attribute.DateTime; - updatedAt: Attribute.DateTime; - createdBy: Attribute.Relation< - 'plugin::i18n.locale', - 'oneToOne', - 'admin::user' - > & - Attribute.Private; - updatedBy: Attribute.Relation< - 'plugin::i18n.locale', - 'oneToOne', - 'admin::user' - > & - Attribute.Private; - }; -} - export interface ApiCategoryCategory extends Schema.CollectionType { collectionName: 'categories'; info: { @@ -889,10 +889,10 @@ declare module '@strapi/types' { 'plugin::upload.folder': PluginUploadFolder; 'plugin::content-releases.release': PluginContentReleasesRelease; 'plugin::content-releases.release-action': PluginContentReleasesReleaseAction; + 'plugin::i18n.locale': PluginI18NLocale; 'plugin::users-permissions.permission': PluginUsersPermissionsPermission; 'plugin::users-permissions.role': PluginUsersPermissionsRole; 'plugin::users-permissions.user': PluginUsersPermissionsUser; - 'plugin::i18n.locale': PluginI18NLocale; 'api::category.category': ApiCategoryCategory; 'api::post.post': ApiPostPost; } diff --git a/frontend/src/app/blog/[slug]/(blog-content)/BlogContent.tsx b/frontend/src/app/blog/[slug]/(blog-content)/BlogContent.tsx index 332fc16..9e5b803 100644 --- a/frontend/src/app/blog/[slug]/(blog-content)/BlogContent.tsx +++ b/frontend/src/app/blog/[slug]/(blog-content)/BlogContent.tsx @@ -11,6 +11,7 @@ interface Props { markdown: string; } +// Note: You can add a title to a part of code in MD like this: ```tsx:index.ts and this way you cover both the extension and file name. const BlogContent: FunctionComponent = async ({ markdown }) => { return (