How to edit @frontity/mars-theme to achieve categorized widgets in Homepage?

How to edit @frontity/mars-theme to achieve categorized widgets in Homepage?

Hello @kabeer.shefy , welcome to Frontity

Could you ellaborate a bit more what do you mean by “achieve categorized widgets in Homepage”?

Do you have any example that we could take a look at? If you are trying to replicate something from a live WordPress site it would be really helpful if you could share the link and explain how it works now :slight_smile:

Hello Pablo , thank you for your response. here, i am sharing news website link. I need to achieve that kind of categorized news listing in home instead of just an archive listing.
http://www.expresskerala.com/.

Hi @kabeer.shefy,
As you have in the frontity.source all the info provided from the WP REST API you can “play” with that data to organize it in any form you need

Here’s an example of a HomePage with blocks showing 5 articles per category → https://demo-custom-homepage-categories.now.sh/
And here’s the code → https://github.com/frontity-demos/demo-custom-homepage-categories

Hope this helps

1 Like

Thank You Juanma. you shed some Lights to my darkness! i am a newbie to web development especially react and that kind of stuff. anyway I will try to build a theme with frontity.

2 Likes

Do I understand correctly that if I go to the article not through the main page, but simply insert the url into the address bar, then all the pages that on the main page will be loaded into state


I’m just interested in optimizing such moments. we get by api the data that we don’t need right now.

Hello @prainua
you can use Conditional statetment to optimize state data in post page

beforeSSR: async ({ state, actions }) => {
        if (state.router.link === "/") {
          await Promise.all(
            Object.values(beforeSSRCategories).map((category) =>
              actions.source.fetch(`/category/${category.name}/`)
            )
          );
        }
      },
2 Likes

That’s right, thanks @mehul.

Please note that if you do so, you also need to take care of those fetches on the client. More information in this post:

@juanma @kabeer.shefy

There is sth I don’t like with this solution
Juanma’s solution works fine but orders the object keys DESC and you can’t control the order of categorized posts on the homepage.
So I modified the code as so.

:zap: Live Demo
https://newschin.mymakarim.vercel.app/

:star: Give me a star on GitHub:
https://github.com/mymakarim/frontity-codenawis

in index.js

      import {categoryWidgets} from './PATH_TO_homepageSections.js/homepageSections';


      beforeSSR: async ({ state, actions }) => {
        if (state.router.link === "/") {
          console.log(state.router.link)
          console.log('getting data from beforeSSR...')
          // await actions.source.fetch(`/category/featured/`);
          await Promise.all(
              categoryWidgets.map(categoryWidget=>{
                const category = categoryWidget.slug;
                return actions.source.fetch(`/category/${category}/`)
              })
          )
        }
      }

and for getPostsGroupedByCategory function which I have put inside functions.js


import {categoryWidgets} from '../PATH_TO_homepageSections.js/homepageSections'

// export const getCategoriesIds = categories => Object.keys(categories)
// export const getCategoriesValues = categories => Object.keys(categories)

export const getPostsGroupedByCategory = source =>  {

  return categoryWidgets.map(categoryWidget=>{
    const posts = getPostsFromCategory(source, categoryWidget.id).reverse().slice(0,3)
    const category = source.category[categoryWidget.id]
    return {order: categoryWidget.order, posts, category}
  });

}

export const getPostsFromCategory = ({ post }, categoryId) =>
  Object.keys(post)
    .map(postID => post[postID])
    .filter(({categories}) => categories.includes(+categoryId) )

and in list.js


import {getPostsGroupedByCategory} from '../PATH_TO_functions.js/functions';


const postsPerCategory = getPostsGroupedByCategory(state.source)


      {data.route === '/' 
          ? postsPerCategory.map((postsCategory, index) => {
              if(postsCategory.category){
                return <CardSection key={postsCategory.category.name} category={postsCategory.category} postsCategory={postsCategory} />
              }else{
                return <p key={index}></p>;
              }
          })
          :<Row>
            {data.items.map(({ type, id }) => {
              const item = state.source[type][id];
              // Render one Item component for each one.
              return <ListItem key={item.id} item={item} />
            })} 
          </Row>
          }