> ## Documentation Index
> Fetch the complete documentation index at: https://dokumentation.websale.de/llms.txt
> Use this file to discover all available pages before exploring further.

# $wsCategories - Categories

> Load and display category data in the frontend: properties, subcategories, paths, and products for navigation, lists, and category pages.

With the `$wsCategories` module, you load category data and display it in the frontend - individual categories, their subcategories, the category path (breadcrumb), and the products they contain.

This page is about loading and displaying category data. Product details are described in the product reference; the setup of category navigation takes place in the admin interface (see [Template](#template)).

***

## Basic concept

`$wsCategories` is a loader modul**e**: It only provides methods for loading categories and does not itself have a "current category". A call like `$wsCategories.id` therefore does not exist.

Instead, you always work with a Category map, i.e. an object with the [properties of a category](#properties-of-a-category). You obtain this map in two ways:

* **From the current page context** - on a category page, the current category is available under `$wsViews.current.info.category`:
  ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
  {{ var $category = $wsViews.current.info.category }}
  ```
* **From a loader method** - e.g. a specific category by its ID or the subcategories of a category:
  ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
  {{ var $category = $wsCategories.loadCategory("100-12345") }}
  ```

In both cases, you assign the map to a variable and then access its properties (e.g. `$category.name`). The variable name is freely chosen; on this page it is consistently called `$category`.

***

## Module overview

**Example / excerpt of** `$wsCategories`

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsCategories | json }}
```

**JSON output**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
  "loadCategory": "ƒ()",
  "loadCategoryMembershipPaths": "ƒ()",
  "loadCategoryMemberships": "ƒ()",
  "loadChildren": "ƒ()",
  "loadPath": "ƒ()",
  "loadProducts": "ƒ()"
}
```

Note: `"ƒ()"` denotes a function.

**Methods overview**

| **Method**                      | **Return type** | **Description**                                                     |
| ------------------------------- | --------------- | ------------------------------------------------------------------- |
| `loadCategory()`                | map             | Loads a single category by its ID.                                  |
| `loadChildren()`                | array           | Loads the direct subcategories of a category.                       |
| `loadPath()`                    | array           | Loads the category path (breadcrumb) from the root to the category. |
| `loadProducts()`                | array           | Loads the products of a category.                                   |
| `loadCategoryMemberships()`     | array           | Loads all categories in which a product is contained.               |
| `loadCategoryMembershipPaths()` | array           | Loads the complete category paths for all categories of a product.  |

The properties that every loaded category provides are described under [Properties of a category](#properties-of-a-category).

***

## Template

By default, the display of categories is done via the template `category.htm` (in the directory tree under `templates/views/category.htm`).

However, category data can also be used flexibly elsewhere, for example in blog posts or in the basket. To do this, the respective template must already have been created in the `views` directory.

***

## Properties of a category

The following properties are available in every Category map, regardless of whether you obtained it from the page context or with the help of a loader method.

| **Property**            | **Return type** | **Description**                                                                                     |
| ----------------------- | --------------- | --------------------------------------------------------------------------------------------------- |
| `id`                    | string          | Unique ID of the category assigned by the shop.                                                     |
| `name`                  | string          | Name of the category.                                                                               |
| `descr`                 | string          | Description of the category.                                                                        |
| `active`                | string          | Visibility status: `"always"` (always visible), `"test"` (test mode only), `"never"` (not visible). |
| `hidden`                | bool            | Whether the category is hidden (e.g. not displayed in the navigation).                              |
| `productsCount`         | int             | Number of products in the category.                                                                 |
| `custom`                | map             | User-defined (free) fields of the category, e.g. images or SEO texts.                               |
| `timestampCreatedAt`    | datetime        | Creation time of the category.                                                                      |
| `timestampUpdatedAt`    | datetime        | Time of the last change.                                                                            |
| `productAssignmentType` | string          | Type of product assignment, e.g. `"manual"` (manual assignment).                                    |
| `productRules`          | string          | Rules for automatic product assignment; empty for manual assignment.                                |

### name and descr

Name and description are the most common display values. More on the configuration of these fields [in the category configuration](/en/konfiguration/content-katalog-kategorien-produkte#2-content-categoryfield-standard-kategoriefelder).

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $category = $wsViews.current.info.category }}
Category name: {{= $category.name }}
Description: {{= $category.descr }}
```

### active

Evaluate `active` to display only visible categories, for example in a navigation.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $category.active == "always" }}
  <!-- Category is visible -->
{{ /if }}
```

### hidden

`hidden` specifically hides a category from the navigation without deactivating it. Check it before generating a navigation entry.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if !$category.hidden }}
  <li>{{= $category.name }}</li>
{{ /if }}
```

### custom

`custom` contains the free fields of the category. Unlike with the product, the category image is located under `custom.image.category` (with the WebP variant `custom.image.categoryWebp`); a separate navigation image is located under `custom.imageNavigation.category`. Before output, check whether the desired field is present.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $category.custom.image.category }}
  <img src="{{= $category.custom.image.category }}" alt="{{= $category.name }}">
{{ /if }}
```

<Info>
  In addition to the images, `custom` also contains, among other things, SEO fields (`metaTitle`, `metaDescription`, `seoName`) and control fields (`robotsNoIndex`, `robotsNoFollow`, `alternativeTemplate`).
</Info>

### timestampCreatedAt and timestampUpdatedAt

Both return a timestamp as an ISO-8601 string (UTC, e.g. `2026-05-07T13:09:08.000Z`).

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Updated: {{= $category.timestampUpdatedAt }}
```

***

## Methods

### \$wsCategories.loadCategory()

Loads a single category by its ID. Use this method to display a specific category in a targeted way - even outside a category page, for example on the home page or in a blog post.

**Signature**\
`$wsCategories.loadCategory(categoryId)`

**Return value**\
`map` – Category map with all [category properties](#properties-of-a-category).

**Parameters**

| **Name**     | **Type** | **Required** | **Description**             |
| ------------ | -------- | ------------ | --------------------------- |
| `categoryId` | string   | yes          | ID of the category to load. |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $category = $wsCategories.loadCategory("100-12345") }}
{{= $category.name }}
```

### \$wsCategories.loadChildren()

Loads the direct subcategories of a category. Use this method to build a multi-level navigation.

**Signature**\
`$wsCategories.loadChildren(parentId)`

**Return value**\
`array` – List of Category maps.

**Parameters**

| **Name**   | **Type** | **Required** | **Description**            |
| ---------- | -------- | ------------ | -------------------------- |
| `parentId` | string   | no           | ID of the parent category. |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $child in $wsCategories.loadChildren("100-12345") }}
  {{= $child.name }}
{{ /foreach }}
```

<Note>
  Without specifying a `parentId`, the categories of the top level are returned. This is useful for building the main navigation without having to know a root ID.
</Note>

### \$wsCategories.loadPath()

Loads the category path (breadcrumb) from the root to the specified category. Use this method for a breadcrumb navigation that shows the customer where they are.

**Signature**\
`$wsCategories.loadPath(categoryId)`

**Return value**\
`array` – List of Category maps, from top (root) to bottom (target category).

**Parameters**

| **Name**     | **Type** | **Required** | **Description**            |
| ------------ | -------- | ------------ | -------------------------- |
| `categoryId` | string   | yes          | ID of the target category. |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $step in $wsCategories.loadPath($category.id) }}
  <a href="{{= $wsViews.url('Category', {id: $step.id}) }}">{{= $step.name }}</a> /
{{ /foreach }}
```

### \$wsCategories.loadProducts()

Loads the products contained in a category. Use this method to build a product list outside a category page (on the category page itself, the products are already available under `$wsViews.current.info.products`).

**Signature**\
`$wsCategories.loadProducts(categoryId)`

**Return value**\
`array` – List of product maps.

**Parameters**

| **Name**     | **Type** | **Required** | **Description**                                     |
| ------------ | -------- | ------------ | --------------------------------------------------- |
| `categoryId` | string   | yes          | ID of the category whose products are to be loaded. |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $products = $wsCategories.loadProducts("100-12345") }}
{{ foreach $product in $products }}
  {{= $product.name }}
{{ /foreach }}
```

### \$wsCategories.loadCategoryMemberships()

Loads all categories in which a specific product is contained. Useful for displaying on a product page which categories the product is assigned to.

**Signature**\
`$wsCategories.loadCategoryMemberships(productId)`

**Return value**\
`array` – List of Category maps.

**Parameters**

| **Name**    | **Type** | **Required** | **Description**                                        |
| ----------- | -------- | ------------ | ------------------------------------------------------ |
| `productId` | string   | yes          | ID of the product whose categories are to be searched. |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $category in $wsCategories.loadCategoryMemberships($product.id) }}
  <span>{{= $category.name }}</span>
{{ /foreach }}
```

### \$wsCategories.loadCategoryMembershipPaths()

Loads the complete category paths (breadcrumbs) for all categories in which a product is contained. Unlike `loadCategoryMemberships()`, you receive not only the target categories, but the complete path for each. Useful for displaying the full classification of a product.

**Signature**\
`$wsCategories.loadCategoryMembershipPaths(productId)`

**Return value**\
`array` – List of paths; each path is itself a list of Category maps.

**Parameters**

| **Name**    | **Type** | **Required** | **Description**                                            |
| ----------- | -------- | ------------ | ---------------------------------------------------------- |
| `productId` | string   | yes          | ID of the product whose category paths are to be searched. |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $path in $wsCategories.loadCategoryMembershipPaths($product.id) }}
  {{ foreach $step in $path }}
    {{= $step.name }} >
  {{ /foreach }}
{{ /foreach }}
```

***

## Actions

No actions are available for `$wsCategories`.

***

## Examples

The examples assume that the category to be displayed has previously been assigned to a variable, for example on a category page like this:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $category = $wsViews.current.info.category }}
```

### Display name and description

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Category name: {{= $category.name }}
Category description: {{= $category.descr }}
```

**Result** \
The name and description of the current category are output.

### Display category image

First check whether an image is present so that you do not generate an empty `img` tag.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $category.custom.image.category }}
  <img src="{{= $category.custom.image.category }}" alt="{{= $category.name }}">
{{ /if }}
```

**Result** \
If an overview image is stored, it is displayed with the category name as the alternative text.

### Display subcategories

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $child in $wsCategories.loadChildren($category.id) }}
  <p>{{= $child.name }} – {{= $child.descr }}</p>
{{ /foreach }}
```

**Result** \
All direct subcategories of the current category are listed.

### Display products of the current category

On a category page, the products of the category are already available in the page context.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $product in $wsViews.current.info.products }}
  Product name: {{= $product.name }}
{{ /foreach }}
```

**Result** \
The products of the current category are output.

### Breadcrumb of the current category

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $step in $wsCategories.loadPath($category.id) }}
  <a href="{{= $wsViews.url('Category', {id: $step.id}) }}">{{= $step.name }}</a> /
{{ /foreach }}
```

**Result** \
The path from the top category down to the current one is output as a sequence of linked names.

### Load a category on any page

With `loadCategory()`, you can also access category data outside a category page, for example on the home page, in a blog post, or in the basket.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $category = $wsCategories.loadCategory("101-12345") }}
Category name: {{= $category.name }}
Category description: {{= $category.descr }}
```

**Result** \
The specified category is loaded and its data is output.

<Note>
  The IDs used in the examples (`100-12345`, `101-12345`) are placeholders and must be replaced with real category IDs from your shop.
</Note>

***

## Further links

* [\$wsViews](/en/frontend/referenz/module/wsviews) – via `current.info.category` and `current.info.products` provides the data of the current category page, and with `url('Category', {id})` the category links.
* [Category configuration](/en/konfiguration/content-katalog-kategorien-produkte#2-content-categoryfield-standard-kategoriefelder) – defines the standard category fields (name, description, free fields).
