Category Groups in TokenBB

in #utopian-io5 years ago

Repository

https://github.com/BuildTeamDev/tokenbb-web-client

Category Group View

As a relatively high priority feature request, we wanted to implement a main page view that has a category summary, as well as groupings of categories into an organized, customizable format.

This is how it looks on tokenbb.io.

If you click on the 'Feedback' heading, you can drilling down into the hierarchy. As you navigate, the breadcrumb will show where you are, and each part of the breadcrumb can be clicked to go back up.

Clicking into the 'Bug' category, gets you to the topic list page, also with the breadcrumb intact.

Implementation Details

Main Pull Requests:

Entity Structure of Groups

@reggaemuffin set up a setting on the Forum entity, called categoryOrdering, which is a JSON string with a sample structure like the following:

{
  "name":"Home",
  "slug":"/",
  "categories": ["topcat"], 
  "groups": [
     {
       "name":"General",
        "slug":"general",
        "categories": ["bug-report", "feedback", "tech-support"],
        "groups":[]},
     {
       "name":"Group2",
       "slug":"group2",
       "categories":[], 
       "groups":[
         {
           "name":"extra",
           "slug":"extra",
           "categories":["more-cats","really-great-cat"],
           "groups":[]
         },
         {
           "name":"None abc -äge",
           "slug":"none",
           "categories":["shop-talk","tech-support"],
           "groups":[
             {
               "name":"Empty",
               "slug":"empty",
               "categories":[],
               "groups":[]
             }
           ]
         }
       ]
     }
   ]
 }

We also allowed this setting to just contain an array of category groups, in which case we automatically create a root entity with the given groups.

More formally, the format of category ordering is either

  • A Category group, with the fields:
    • name - Display name
    • slug - Internal URL-compatible string for navigation.
    • categories - List of category slugs within this category group.
    • groups - Array of Category groups.
  • An array of Category groups.

This structure allows for multi-level hierarchies, as well as allowing categories and category groups to be specified at any level, as well as allowing customization of the order that the categories show up.

Note that fully specifying category / category group structure is two steps:

  1. Setting up the desired categories, without groupings (Done now in Settings page of the Forum).
  2. Setting up this category ordering structure. (Right now can only be done by an admin until we have a UI component for settings)

Forum and Category Stores

First we set up a Forum store here which handles calls to the BuildTeam API that stores the Forum entity, and in particular, the category ordering.

In the Vue store code for category fetch, we have a step that denormalizes the Category data, which comes as a flat list, into the category ordering structure above. This you can follow here:

In order to access the category ordering structure, we set up a vuex getter so we can access the Forum store from the Category store, where we are constructing this denormalized structure.

Next, the function for traversing the category ordering structure:

This function takes in a 'Category Group', as described in the previous section. Essentially, for each category in this Category Group, which is a slug, we look up the corresponding category from the list and put that into the structure. We recursively process every group as well.

Note we are also keeping tabs of which categories were uncategorized at the end of the procedure, which we will throw into the top-level category after processing.

This is how we set up the top-level category and call the category order processor. There's a strange quirk with the getter when it isn't quite ready, and possibly there's something a little strange with our access pattern of the Forum store's data, and that's why the weird comment and check if is an object as opposed to a function. At the same time, we are tracking a breadcrumb string in the nav object.

There are two other problems from this PR that were addressed in hte latter PR's. One involves passing the homeCategory object directly into the processor, and the other involves replacing the homeCategory with the result of processing the categoryOrdering instead of pushing it into the homeCategory as a subgroup.

The result is that state.categoriesByBreadcrumb will store this full structure, including the categories, as well as some helpers for tracking the navigation string that will be used in breadcrumb code. This section was joint work shared by @reggaemuffin as well.

CategoryList component

For displaying the categories, we used a recursive component in CategoryList. This probably could have been named better, but inside the component you can assign a name (in this case CategoryGroup) which can then be used to recursively render an inner CategoryGroup.

This component introduces a collapsible card from Buefy which can be used to show/hide a grouping. Styling for the categories themselves was done by @cryptoctopus, which I believe is also mixed into the PR.

The later PR also restructures the file so that the top-level doesn't put an extra box around everything. This is accomplished by moving the collapse card into the category group b-table instead of at the top of the component.

Home view

In the Home view, we set up the ability to navigate the hierarchy via the nav query parameter.

For example, with a structure like Home / General, the query param nav=home, gives top level, nav=home/general gives the next level, and so on.

There's some code to take the state.categoriesByBreadcrumb structure computed in the store earlier, and dive into the structure based on the nav parameter, and it's what you would expect: Split the nav by the delimeter (/), and find the group with the slug corresponding to each part of the nav.

Once that is done, we show a Breadcrumb component (see below) and the CategoryList component corresponding to the current level.

Breadcrumb component

The Breadcrumb is a relatively simple component, where you give the component an array of objects, specifying display name, path, and query for each part of the breadcrumb. This relies on the calling component to compute everything.

There's a slight bit of duplication among the various views that use it: Category Group view, Topic List for a given Category, and the Topic view, though each one is slightly different in terms of the last part of the breadcrumb.

Recall that in the store above we compute a nav parameter for each group, as well as each Category. This is then split and the individual links in the breadcrumb are computed from this.

For example, in the case where the current view's nav parameter is home/general/support, where support is a category, we would compute

  1. name: Home, path: '/', query: { nav: 'home' }
  2. name: General, path: '/', query: { nav: 'home/general' }
  3. name: Support, path: '/topic-list', query: { category: 'support' } (different structure for topic list view)

Other Changes

The rest of the changes are mostly wiring. Before this change, the Home view was the full list of topics in all categories. That was now moved to a new route (topic-list), which also can show all categories, or topics filtered by a specific category, all driven by query parameters.

The way to implement setting the category ordering will be fun to implement as well, but that has not been worked out yet. I was thinking along the lines of a nice drag-and-drop type interface.

GitHub Account

https://github.com/eonwarped

Sort:  
  • Great article with lots of images, code samples and explanations.
  • Great commit messages and separation of concerns.
  • The code could use more comments throughout.
  • I see code for themes, how do I choose a theme?

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Chat with us on Discord.

[utopian-moderator]

Thanks!

Yeah, comments is something I can work on for sure.

Also the map you see there defines it on a per-forum basis. Basically for a forum owner to set up a theme they need to provide style files and it is committed into code in that map. @reggaemuffin and @cryptoctopus can clarify further details about the theme as well.

Thank you for your review, @helo! Keep up the good work!

Thank you so much for participating in the Partiko Delegation Plan Round 1! We really appreciate your support! As part of the delegation benefits, we just gave you a 3.00% upvote! Together, let’s change the world!

Nice work Eon.

Hi @eonwarped!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Hey, @eonwarped!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Coin Marketplace

STEEM 0.17
TRX 0.15
JST 0.027
BTC 60654.57
ETH 2343.25
USDT 1.00
SBD 2.48