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 Me gusta

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 Me gusta

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 Me gusta

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 me gusta

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 Me gusta

@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 me gusta

Este tipo de agrupación ahora es compatible en el núcleo de Discourse:

Elija “Subcategorías con temas destacados” como el ‘estilo de página de categoría de escritorio’:

Y entonces su página de categorías se verá algo así:

5 Me gusta

¿Es posible hacerlo con RTL? Lo intenté pero fallé :broken_heart:

Tiene sentido. Las hojas de estilo principales de Discourse se invierten para crear una versión RTL aquí: discourse/lib/stylesheet/compiler.rb at main · discourse/discourse · GitHub. No creo que los archivos CSS que se agregan con temas se compilen para crear una versión RTL. Si eso es correcto, eso explicaría los problemas que has encontrado con los temas cuando se usa un diseño RTL.

Podrías confirmar esto agregando algunas reglas CSS que contengan una dirección al tema de tu sitio, luego visita el sitio con una configuración regional RTL y mira si la dirección se ha invertido. No creo que se invierta.

Por ejemplo, si agregas esto a tu tema:

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

No creo que se convierta en esto:

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

Estoy de acuerdo contigo, todavía estoy confundido al usar el código anterior :confused:

¿Alguna sugerencia?

¿Conoces algún ejemplo de tema que no funcione con RTL? Si es así, publica un enlace al tema aquí y probaré mi teoría y explicaré qué está saliendo mal después de probarlo.

Editar: Aquí hay una explicación del problema:

Para los archivos CSS que se encuentran en la base de código principal de Discourse, el CSS RTL se crea “invirtiendo” la mayoría de las reglas CSS que dependen de la dirección del diseño del sitio. Por ejemplo, padding-left se invierte a padding-right. Esto se hace con la gema RTLcss: GitHub - discourse/rtlcss: A wrapper around the rtlcss npm package to flip CSS direction in Ruby.

El problema es que las reglas CSS de los temas de Discourse no se invierten. Eso significa que si un tema tiene reglas CSS que especifican una dirección, la dirección será la misma cuando se use un idioma RTL que cuando se use un idioma LTR. Aquí hay un pequeño ejemplo de eso:

Cuando se usa el tema con una interfaz RTL, padding-left: 8px; no se invierte a padding-right: 8px;. Esto causa un problema menor con la alineación. Estoy seguro de que hay ejemplos de problemas mayores que ocurren cuando los temas se usan con un idioma RTL.

Lo mismo ocurre con cualquier CSS que agregues a un tema predeterminado de Discourse en el editor de temas. Aquí hay un ejemplo que usa el código de este tema: Can it be done with CSS? Grouping categories on category page - #4 by cosdesign.

Aquí hay una regla de ese CSS que establece una dirección:

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

Con una configuración regional RTL, este es el problema:

Si esa regla estuviera en un archivo CSS principal de Discourse, left: 0; se convertiría automáticamente en right: 0; cuando se seleccionara un idioma RTL. Debido a que el CSS se agrega a un tema, debe editarlo manualmente de la siguiente manera:

body [data-category-id="2"]::before,body [data-category-id="4"]::before {
    position: absolute;
    top: -35px;
    right: 0; // cambiado a la posición correcta para diseños RTL
    font-weight: bold;
    font-size: 15px;
    text-transform: uppercase;
    color: var(--primary-medium);
}

Discourse agrega una clase rtl a la etiqueta html cuando se usa un diseño RTL. Los desarrolladores de temas podrían usar esta clase para hacer que sus temas funcionen tanto para diseños LTR como RTL. Esto funciona, y creo que es correcto, pero posiblemente la declaración left: auto no necesite estar allí.

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);
}
/* Corrige el posicionamiento para diseños rtl */
.rtl body [data-category-id="2"]::before,.rtl body [data-category-id="4"]::before {
    right: 0;
    left: auto;
}

No estoy seguro de si los desarrolladores deberían adoptar este enfoque con sus temas. Consume tiempo y podría generar errores y problemas de mantenimiento. Quizás Discourse podría compilar algunos temas y considerar proporcionar una versión RTL. Podría valer la pena probar este enfoque con algunos de ellos:

require "rtlcss"

Rtlcss.flip_css("theme_css")

Se suponía que esta sería una respuesta corta :slight_smile: Si lo que he escrito es correcto y no se ha abordado en otro tema, tal vez debería trasladarse a un nuevo tema.

Estos Theme component pueden hacer lo que buscas. O ser una buena base para mirar el código y obtener ideas.

“Modern Category + Group boxes” como se usa en el Air Theme funciona bien.