create account

Category Groups in TokenBB by eonwarped

View this thread on: hive.blogpeakd.comecency.com
· @eonwarped ·
$65.95
Category Groups in TokenBB
### 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.

![](https://cdn.steemitimages.com/DQmTpVyFGTZzybwEoFEtNwU1P88EDLZUQ6g5esUBYozvm6i/image.png)

This is how it looks on tokenbb.io.

![](https://cdn.steemitimages.com/DQmXaGLjWn7FDQzipkqecJNoL15iDjEGD6eBUDThsRfPBug/image.png)

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.

![](https://cdn.steemitimages.com/DQmZBcgBDM9bw54w4YYPQh1Zmp1nor1ozhF5FpngZX8APWm/image.png)

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

### Implementation Details

Main Pull Requests:
* https://github.com/BuildTeamDev/tokenbb-web-client/pull/61
* https://github.com/BuildTeamDev/tokenbb-web-client/pull/63 
* https://github.com/BuildTeamDev/tokenbb-web-client/pull/68

#### 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](https://github.com/BuildTeamDev/tokenbb-web-client/pull/61/files#diff-92daadc76cd34bbb2c85cf30af625a91) 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](https://github.com/BuildTeamDev/tokenbb-web-client/pull/61/files#diff-eeb7ea8bdee78bd74630b56c8514e1e0):

In order to access the category ordering structure, we set up a [vuex getter](https://vuex.vuejs.org/guide/getters.html) so we can access the Forum store from the Category store, where we are constructing this denormalized structure.

![](https://cdn.steemitimages.com/DQmZ1YzKDa4aMBoeZAPGHFp4nZfryVH9Ri3iB8fmNh5wRaR/image.png)

Next, the function for traversing the category ordering structure:

![](https://cdn.steemitimages.com/DQmQb3AZzvm1HsHqiKtuATvo7SSxVv12UuWzinCpz2buGKM/image.png)

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.

![](https://cdn.steemitimages.com/DQmbM3UWLXRTDvZN32PkD3qnCT7i5SVjifWWHNoR52nbttY/image.png)

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](https://github.com/BuildTeamDev/tokenbb-web-client/pull/68/files#diff-eeb7ea8bdee78bd74630b56c8514e1e0), and the other involves [replacing the homeCategory](https://github.com/BuildTeamDev/tokenbb-web-client/pull/63/files#diff-eeb7ea8bdee78bd74630b56c8514e1e0) 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](https://github.com/BuildTeamDev/tokenbb-web-client/pull/61/files?file-filters%5B%5D=.ico&file-filters%5B%5D=.js&file-filters%5B%5D=.json&file-filters%5B%5D=.png&file-filters%5B%5D=.svg&file-filters%5B%5D=.vue#diff-75949d7749a5bc73be34d44729e7280f). 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](https://buefy.org/documentation/collapse/) 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](https://github.com/BuildTeamDev/tokenbb-web-client/pull/63/files#diff-75949d7749a5bc73be34d44729e7280f) 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](https://github.com/BuildTeamDev/tokenbb-web-client/blob/2197e8a56382d5044f0db2e8e5cda36ffe545b35/src/views/Home.vue), 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](https://github.com/BuildTeamDev/tokenbb-web-client/pull/61/files?file-filters%5B%5D=.ico&file-filters%5B%5D=.js&file-filters%5B%5D=.json&file-filters%5B%5D=.png&file-filters%5B%5D=.svg&file-filters%5B%5D=.vue#diff-38a7b049ed91e7f0d1f2587b085d0311) 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
👍  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and 936 others
properties (23)
authoreonwarped
permlinkcategory-groups-in-tokenbb
categoryutopian-io
json_metadata{"tags":["utopian-io","development","tokenbb","steemdev"],"users":["reggaemuffin","cryptoctopus"],"image":["https://cdn.steemitimages.com/DQmTpVyFGTZzybwEoFEtNwU1P88EDLZUQ6g5esUBYozvm6i/image.png","https://cdn.steemitimages.com/DQmXaGLjWn7FDQzipkqecJNoL15iDjEGD6eBUDThsRfPBug/image.png","https://cdn.steemitimages.com/DQmZBcgBDM9bw54w4YYPQh1Zmp1nor1ozhF5FpngZX8APWm/image.png","https://cdn.steemitimages.com/DQmZ1YzKDa4aMBoeZAPGHFp4nZfryVH9Ri3iB8fmNh5wRaR/image.png","https://cdn.steemitimages.com/DQmQb3AZzvm1HsHqiKtuATvo7SSxVv12UuWzinCpz2buGKM/image.png","https://cdn.steemitimages.com/DQmbM3UWLXRTDvZN32PkD3qnCT7i5SVjifWWHNoR52nbttY/image.png"],"links":["https://github.com/BuildTeamDev/tokenbb-web-client","https://github.com/BuildTeamDev/tokenbb-web-client/pull/61","https://github.com/BuildTeamDev/tokenbb-web-client/pull/63","https://github.com/BuildTeamDev/tokenbb-web-client/pull/68","https://github.com/BuildTeamDev/tokenbb-web-client/pull/61/files#diff-92daadc76cd34bbb2c85cf30af625a91","https://github.com/BuildTeamDev/tokenbb-web-client/pull/61/files#diff-eeb7ea8bdee78bd74630b56c8514e1e0","https://vuex.vuejs.org/guide/getters.html","https://github.com/BuildTeamDev/tokenbb-web-client/pull/68/files#diff-eeb7ea8bdee78bd74630b56c8514e1e0","https://github.com/BuildTeamDev/tokenbb-web-client/pull/63/files#diff-eeb7ea8bdee78bd74630b56c8514e1e0","https://github.com/BuildTeamDev/tokenbb-web-client/pull/61/files?file-filters%5B%5D=.ico&file-filters%5B%5D=.js&file-filters%5B%5D=.json&file-filters%5B%5D=.png&file-filters%5B%5D=.svg&file-filters%5B%5D=.vue#diff-75949d7749a5bc73be34d44729e7280f","https://buefy.org/documentation/collapse/","https://github.com/BuildTeamDev/tokenbb-web-client/pull/63/files#diff-75949d7749a5bc73be34d44729e7280f","https://github.com/BuildTeamDev/tokenbb-web-client/blob/2197e8a56382d5044f0db2e8e5cda36ffe545b35/src/views/Home.vue","https://github.com/BuildTeamDev/tokenbb-web-client/pull/61/files?file-filters%5B%5D=.ico&file-filters%5B%5D=.js&file-filters%5B%5D=.json&file-filters%5B%5D=.png&file-filters%5B%5D=.svg&file-filters%5B%5D=.vue#diff-38a7b049ed91e7f0d1f2587b085d0311","https://github.com/eonwarped"],"app":"steemit/0.1","format":"markdown"}
created2019-03-26 12:25:30
last_update2019-03-26 12:25:30
depth0
children7
last_payout2019-04-02 12:25:30
cashout_time1969-12-31 23:59:59
total_payout_value50.324 HBD
curator_payout_value15.622 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length9,764
author_reputation88,102,208,706,615
root_title"Category Groups in TokenBB"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id81,982,343
net_rshares101,185,766,981,465
author_curate_reward""
vote details (1000)
@helo ·
$14.04
- 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?
![](https://cdn.steemitimages.com/DQmRzzRBcJWAwmomz9zSbtcF2xwYuTWWRzhgc1iuSebV1Cu/image.png)

Your contribution has been evaluated according to [Utopian policies and guidelines](https://join.utopian.io/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](https://review.utopian.io/result/3/1-2-1-1-1-1-3-).

---- 
Need help? Chat with us on [Discord](https://discord.gg/uTyJkNm).

[[utopian-moderator]](https://join.utopian.io/)
👍  , , , , , , , , , , , , , , , , , , ,
properties (23)
authorhelo
permlinkre-eonwarped-category-groups-in-tokenbb-20190326t144939414z
categoryutopian-io
json_metadata{"tags":["utopian-io"],"image":["https://cdn.steemitimages.com/DQmRzzRBcJWAwmomz9zSbtcF2xwYuTWWRzhgc1iuSebV1Cu/image.png"],"links":["https://join.utopian.io/guidelines","https://review.utopian.io/result/3/1-2-1-1-1-1-3-","https://discord.gg/uTyJkNm","https://join.utopian.io/"],"app":"steemit/0.1"}
created2019-03-26 14:49:39
last_update2019-03-26 14:49:39
depth1
children2
last_payout2019-04-02 14:49:39
cashout_time1969-12-31 23:59:59
total_payout_value10.658 HBD
curator_payout_value3.378 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length759
author_reputation121,547,934,535,311
root_title"Category Groups in TokenBB"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id81,988,551
net_rshares21,522,755,208,388
author_curate_reward""
vote details (20)
@eonwarped ·
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.
properties (22)
authoreonwarped
permlinkre-helo-re-eonwarped-category-groups-in-tokenbb-20190326t145356466z
categoryutopian-io
json_metadata{"tags":["utopian-io"],"users":["reggaemuffin","cryptoctopus"],"app":"steemit/0.1"}
created2019-03-26 14:53:57
last_update2019-03-26 14:53:57
depth2
children0
last_payout2019-04-02 14:53:57
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length329
author_reputation88,102,208,706,615
root_title"Category Groups in TokenBB"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id81,988,779
net_rshares0
@utopian-io ·
Thank you for your review, @helo! Keep up the good work!
properties (22)
authorutopian-io
permlinkre-re-eonwarped-category-groups-in-tokenbb-20190326t144939414z-20190328t211633z
categoryutopian-io
json_metadata"{"app": "beem/0.20.17"}"
created2019-03-28 21:16:36
last_update2019-03-28 21:16:36
depth2
children0
last_payout2019-04-04 21:16:36
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length56
author_reputation152,955,367,999,756
root_title"Category Groups in TokenBB"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id82,119,436
net_rshares0
@partiko ·
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!
properties (22)
authorpartiko
permlinkre-category-groups-in-tokenbb-20190326t133022
categoryutopian-io
json_metadata"{"app": "partiko"}"
created2019-03-26 13:30:24
last_update2019-03-26 13:30:24
depth1
children0
last_payout2019-04-02 13:30:24
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length213
author_reputation39,207,160,334,751
root_title"Category Groups in TokenBB"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id81,985,074
net_rshares0
@steem-ua ·
#### 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](https://discord.gg/KpBNYGz)**
properties (22)
authorsteem-ua
permlinkre-category-groups-in-tokenbb-20190326t150446z
categoryutopian-io
json_metadata"{"app": "beem/0.20.19"}"
created2019-03-26 15:04:48
last_update2019-03-26 15:04:48
depth1
children0
last_payout2019-04-02 15:04:48
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length288
author_reputation23,214,230,978,060
root_title"Category Groups in TokenBB"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id81,989,502
net_rshares0
@tarazkp ·
Nice work Eon.
properties (22)
authortarazkp
permlinkre-eonwarped-category-groups-in-tokenbb-20190326t141431303z
categoryutopian-io
json_metadata{"tags":["utopian-io"],"app":"steemit/0.1"}
created2019-03-26 14:14:30
last_update2019-03-26 14:14:30
depth1
children0
last_payout2019-04-02 14:14:30
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length14
author_reputation5,885,530,214,969,667
root_title"Category Groups in TokenBB"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id81,986,719
net_rshares0
@utopian-io ·
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](https://chrome.google.com/webstore/detail/steemplus/mjbkjgcplmaneajhcbegoffkedeankaj?hl=en) or [Steeditor](https://steeditor.app)).

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

<a href='https://steemconnect.com/sign/account-witness-vote?witness=utopian-io&approve=1'>Vote for Utopian Witness!</a>
properties (22)
authorutopian-io
permlinkre-category-groups-in-tokenbb-20190327t014445z
categoryutopian-io
json_metadata"{"app": "beem/0.20.17"}"
created2019-03-27 01:44:48
last_update2019-03-27 01:44:48
depth1
children0
last_payout2019-04-03 01:44:48
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length591
author_reputation152,955,367,999,756
root_title"Category Groups in TokenBB"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id82,014,974
net_rshares0