Can it be done with CSS? Grouping categories on category page

What I’d like to do (as I know there’s no baked in setting or feature set) is use CSS to group categories on the home page.

I’m not looking to nest categories, but just group some together and possibly put a header on them. I know the individual categories can be “separated” with padding, and I know each category can be targeted by category ID or category name. So what I’m hoping is to be able to replicate something that looks like this:

image

I realize for simplicity, the categories would have to be in their sorted order, and each category targeted by catediry_id, but I’m thinking that there’s possibly some CSS that can throw padding after one category or before another.

The big question is there the ability to insert some text in the padding to create a header?

The propose of this is to first break up the long category list view, but separate: example

  • category 1-2 under “staff” header

  • Category 3-4 under “community resources)

  • categories 5,8,11,12,13 “under general discussion categories”

I don’t want to make these sub categories, I like the structure and category system just as it is. All I want to do is display the categories a little differently on the categories view page. Ideally this is just a visual layout, NOTHING to change with the library structure of the platform.

Any idea how to make this happen?

This would be kind of a game changer for my work collaboration site’s layout.

Sam, codinghorror, do you think there would be a way to create a grouping step in the category reorganization menu that could do this natively, say as an option (grouping on/off).just put the categories in order within main page grouping and it could automatically separare them. In core, plugin or a theme component?

3 个赞

anyone? buehler.

feedback appreciated

This kind of stuff is possible in a theme component but extremely complicated. I think you would need to override templates which makes this also pretty fragile.

4 个赞

A bit late :smile: but maybe someone else needs it. I must mention that:

  • Not all the CSS code is required, especially the borders and the background colors for table rows, so feel free to adjust them as you like.
  • I had to change the layout from the regular table into flex cause you can’t have negative margins on table rows and other layout issues, and well…is more flexible :smile:
  • Replace Category Group 1 and Category Group 2 with your desired category group names
  • In my example I’ve used the category ID’s 2 and 4, so using chrome dev tools to inspect ( see pic below), find the right category id and replace [data-category-id="2"] and [data-category-id="4"] in my example with your id(s).

Paste this inside the Common tab:

.category-list{
    display: flex;
    flex-direction: column;
}
.category-list thead tr{
    display: flex;
}
.category-list .topics {
    width: 95px;
    margin-left: auto;
    min-width: 95px;
    white-space: nowrap;
}
.category-list tbody tr {
    background-color: var(--primary-very-low);
    box-sizing: border-box;
    display: flex;
}
body .category-list [data-category-id="2"],body .category-list [data-category-id="4"] {
    position: relative;
    margin-top: 50px;
}
body [data-category-id="2"]::before {
    content: "Category Group 1";
}
body [data-category-id="4"]::before {
    content: "Category Group 2";
}
body [data-category-id="2"]::before,body [data-category-id="4"]::before {
    position: absolute;
    top: -35px;
    left: 0;
    font-weight: bold;
    font-size: 15px;
    text-transform: uppercase;
    color: var(--primary-medium);
}

Paste this inside the Desktop tab:

.category-list tbody tr {
    margin-bottom: 15px;
    border: 1px solid var(--primary-low);
}

And this inside the Mobile tab:

body .category-list-item.category .posts {
    width: auto;
    margin-left: auto;
}
body .category-list-item>footer,body .subcategory-list-item>footer{
    background-color: var(--primary-very-low);
}
.categories-list .category-list th {
    padding: 0;
}
.category-list-item>footer .category-stat, .subcategory-list-item>footer .category-stat {
    float: right;
}
.category-list-item>footer .category-stat:first-child, .subcategory-list-item>footer .category-stat:first-child{
    margin-right: 0;
}
body .category-list-item.category tr:first-of-type{
    padding: 10px 0;
    border-bottom: 1px solid var(--primary-low);
}
body tr.category-topic-link:last-of-type{
    border-bottom: 1px solid var(--primary-low);
}
body .categories-list .category-list th {
    padding: 0;
}
body .category-list-item {
    border-top: none;
    margin-bottom: 10px;
}
body .category-list-item {
    padding: 0;
    border: 1px solid var(--primary-low)!important;
}
.category-list-item>footer, .subcategory-list-item>footer {
    border-top: none;
}

And this is how it looks on desktop and mobile resolutions:

10 个赞

Hi Cos
]very interesting; thank you for sharing. in the same spirit (that of obtaining a better presentation, we are trying to put, in front of discourse, a wordpress page with a specific presentation and we would like to "send on this page, category names, for example those which have received a response , those chosen by the user, or then a determinate category; do you think this is possible and if so how?

1 个赞

I’m afraid you can’t do that just by CSS. Maybe the WordPress Discourse plugin is what you need. In addition to this, the wp discourse shortcodes is also a must.
We are already using it on our WordPress website and it works great so far. This is how the plugin looks in the sidebar widget:

2 个赞

@sam, @cosdesign’s response works. is there any way to bake this into core’s menus so users can leave it off by default, but then set the headers in the admin panel for group header titles, and in each category’s attributes page, select from a dropdown of the enabled section headers from the admin panel so the category just falls under the header.

This shouldn’t be terribly difficult to add to the platform and would really improve large multi user role and group, multi category installations

1 个赞

Discourse 核心现在支持此类分组:

选择“带有精选主题的子类别”作为“桌面类别页面样式”:

然后您的类别页面将如下所示:

5 个赞

是否可以用 RTL 实现?我试过了但失败了 :broken_heart:

这说得通。核心 Discourse 样式表被翻转以在此处创建 RTL 版本:discourse/lib/stylesheet/compiler.rb at main · discourse/discourse · GitHub CSS 文件会被编译以创建 RTL 版本。如果这是正确的,那就可以解释你在使用 RTL 布局时在使用主题时遇到的问题。

你可以通过向你的站点主题添加一些包含方向的 CSS 规则来确认这一点,然后使用 RTL 区域设置访问该站点,看看方向是否被翻转。我认为它不会被翻转。

例如,如果你将此添加到你的主题中:

.category-list-item footer .category-stat, .subcategory-list-item footer .category-stat {
    float: right;
}

我认为它不会被转换为:

.category-list-item footer .category-stat, .subcategory-list-item footer .category-stat {
    float: left;
}

我同意你的看法,恐怕我仍然不清楚如何使用上面的代码 :confused:

有什么建议吗?

您知道有不适用于 RTL 的主题示例吗?如果您知道,请在此处发布主题链接,我将测试我的理论,并在测试后解释问题所在。

编辑:这是对问题的解释:

对于位于 Discourse 主代码库中的 CSS 文件,RTL CSS 是通过“翻转”大多数依赖于站点布局方向的 CSS 规则来创建的。例如,padding-left 会被翻转为 padding-right。这是通过 RTLcss gem 完成的:https://github.com/discourse/rtlcss。

问题在于 Discourse 主题的 CSS 规则不会被翻转。这意味着,如果一个主题有指定方向的 CSS 规则,那么在使用 RTL 语言时,方向将与使用 LTR 语言时相同。这是一个小例子:

当主题与 RTL 界面一起使用时,padding-left: 8px; 不会被翻转为 padding-right: 8px;。这会导致轻微的对齐问题。我相信在使用 RTL 语言时会出现更严重问题的示例。

对于您添加到主题编辑器中默认 Discourse 主题的任何 CSS,情况也是如此。这是一个使用本主题代码的示例:Can it be done with CSS? Grouping categories on category page - #4 by cosdesign

这是该 CSS 中设置方向的一条规则:

body [data-category-id="2"]::before,body [data-category-id="4"]::before {
    position: absolute;
    top: -35px;
    left: 0; // This needs to be changed
    font-weight: bold;
    font-size: 15px;
    text-transform: uppercase;
    color: var(--primary-medium);
}

在使用 RTL 语言时,这是问题所在:

如果该规则位于核心 Discourse CSS 文件中,当选择 RTL 语言时,left: 0; 将自动转换为 right: 0;。由于 CSS 添加到主题中,您需要手动将其编辑为:

body [data-category-id="2"]::before,body [data-category-id="4"]::before {
    position: absolute;
    top: -35px;
    right: 0; // Changed to the proper position for RTL layouts
    font-weight: bold;
    font-size: 15px;
    text-transform: uppercase;
    color: var(--primary-medium);
}

Discourse 在使用 RTL 布局时会向 html 标签添加一个 rtl 类。主题开发者可以使用此类别使他们的主题同时适用于 LTR 和 RTL 布局。这有效,而且我认为它是正确的,但可能不需要 left: auto 声明。

body [data-category-id="2"]::before,body [data-category-id="4"]::before {
    position: absolute;
    top: -35px;
    left: 0;
    font-weight: bold;
    font-size: 15px;
    text-transform: uppercase;
    color: var(--primary-medium);
}
/* Fix positioning for rtl layouts */
.rtl body [data-category-id="2"]::before,.rtl body [data-category-id="4"]::before {
    right: 0;
    left: auto;
}

我不确定开发者是否应该采用这种方法来开发他们的主题。这很耗时,并且可能导致错误和维护问题。也许 Discourse 可以编译一些主题,并考虑提供 RTL 版本。也许值得用其中一些来测试这种方法:

require "rtlcss"

Rtlcss.flip_css("theme_css")

这本应是一个简短的回答 :slight_smile: 如果我写的内容是正确的,并且没有在其他主题中处理过,也许应该将其移到一个新主题中。

这些 Theme component 也许能满足您的需求。或者可以作为参考代码,获取一些灵感。

“现代分类 + 分组框” 如 Air 主题中所使用的效果很好。