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>
          }

hey bro, but when you delete any category from the wordpress, it;s show ā€˜error reading undefined nameā€™ because itā€™s not able to loop through the deleted category. So how to handle this??

This is great. The one thing Iā€™m wondering though is how would we get the categories dynamically? I see they are hard coded in categoryWidgetsā€¦ is there some way to get the category names + IDs dynamically??