Womble Tristes
Womble Tristes

Reputation: 443

Let Strapi CMS create pages based on html template file

So probably my explanation is awful, but i really don’t know how to express my problem or what to search for.

I got a site (www.example.com/blog.html) showing all blog post entries created in a headless cms (Strapi). The site receives the posts by making an url request and parsing the resulting JSON data. This data also contains an unique url slug for each post serving as an identifier.

I want to create one page for each blog post created in the headless cms based on a „template“ html.

What I tried is passing the urlslug as a url parameter (www.example.com/blog/article.html?id=*URLSLUG*) and then using this url parameter to fetch the corresponding post data from the cms. I followed this guide: https://strapi.io/blog/build-an-editorial-website-with-vanilla-java-script-and-strapi

It works, but I don’t want to rely on url parameters for seo reasons. Instead I want something like www.example.com/blog/*URLSLUG*. In other words: I want to have one page for each blog post entry in my headless cms based on a „template“ html.

Any suggestions?

Code can be added if necessary

Upvotes: 0

Views: 1117

Answers (1)

antokhio
antokhio

Reputation: 2004

well there is few options here:

The first one is most reliable, and easy but seems not that fancy as you want: https://market.strapi.io/plugins/strapi-plugin-slugify

The main reason to use this solution is that it handles slug creation when you create post via REST api. The uuid field needs extra work when post created not from admin panel.

So second option is do it yourself style: /api/article/controller/article.js

module.exports = createCoreController('api::article.article', ({strapi}) => ({
   findOne(ctx){
      const { slug } = ctx.params;
      return strapi.db.query('api::article.article').findOne({where: {slug});
   }
});

then in the routes create routes.js file /api/article/routes/routes.js

module.exports = {
  routes: [
     {
       method: 'GET',
       path: '/articles/:slug'
       handler: 'article.findOne'
     }
  ]
}

then if you want to create articles for outside of admin, create lifecycles.js in /api/article/content-types/article/lifecycles.js

module.exports = {
  async beforeCreate(event) {
     // here you have to do something like
     let slug = slugify(event.result.name);
     let isNotFree = await strapi.db.query("api::article.article").findOne({where: {slug}});

     if (Boolean(!isNotFree)) // < not sure prolly need an empty object check 
       for (let i = 1; i < 9999 ; i++) {
       slug = `${slug}-${i}`;
       isNotFree = await strapi.db.query("api::article.article").findOne({where: {slug}});
       if (Boolean(!isNotFree))
           break;
     }
     event.result.slug = slug
  }
}

pleas note the lifecycle code is just a first thing came to my mind, should be tested and optimized prolly

the implementation gives you the findOne controller, you gonna need to do it for each other update, delete, etc...

Upvotes: 0

Related Questions