diff --git a/docs/5.x/reference/element-types/categories.md b/docs/5.x/reference/element-types/categories.md
index c3e491d7e..9a1480042 100644
--- a/docs/5.x/reference/element-types/categories.md
+++ b/docs/5.x/reference/element-types/categories.md
@@ -35,17 +35,17 @@ Read more about this [transition](https://craftcms.com/blog/entrification) on ou
Every category belongs to a _category group_, which defines…
- …a name;
-- …a handle (used when referencing the group in queries and templates);
+- …a handle (used when referencing the group in [queries](#querying-categories) and templates);
- …the maximum number of levels categories can be nested, within the group;
-- …the format of category URIs;
-- …which template should be rendered when a category’s URL is accessed;
+- …the format of category URIs used for [routing](#routing-and-templates);
+- …which [template](#routing-and-templates) should be rendered when a category’s URL is accessed;
- …which [fields](../../system/fields.md) categories in the group should have;
-To create a new category group, go to **Settings** → **Categories** and click **New Category Group**.
+To create a new category group, go to and click **New Category Group**.
## Category Field Layout
-Each category group has its own _field layout_, which allows you to customize the data that’s associated with each category in the group. By default, every category will have a **Title** field (the category name). Any available field type can be added to a category group’s field layout.
+Each category group has its own _field layout_, which allows you to customize the data that’s associated with each category in the group. By default, categories only have a **Title** and **Slug**, but you can add as many other [custom fields](../../system/fields.md) as necessary to satisfy your content architecture.
@@ -74,18 +74,36 @@ When you create a category, you have the following options:
- Fill out the category fields (if you didn’t define any, the only field available will be **Title**)
- Edit the slug (it’s automatically populated based on the title).
-- Choose a Parent category. The new category will have a hierarchical relationship with its parent. This is helpful for creating taxonomies with multiple levels. You also have the option of creating a new category while assigning the Parent.
+- Choose a **Parent** category. The new category will have a hierarchical relationship with its parent. This is helpful for creating taxonomies with multiple levels. You also have the option of creating a new category while assigning the Parent.
::: tip
-You can only nest categories up to the level specified in the **Max Level** field Category Group settings. If it’s empty, the nesting level is unlimited.
+You can only nest categories up to the level specified in the **Max Level** field Category Group settings. By default, there is no limit to how deeply-nested categories can be.
:::
## Assigning Categories
-To assign categories to things (entries, assets, users, etc.), you must first create a [Categories field](../field-types/categories.md).
+To assign categories to things (entries, assets, users, etc.), you must first create a [categories field](../field-types/categories.md).
Each Categories field is connected to a single category group. Whatever you attach the field to will store [relations](../../system/relations.md) to categories selected from that group.
+## Routing and Templates
+
+Category groups’ **URI Format** setting is equivalent to that of [entries](entries.md), so any of the [object template](../../system/object-templates.md) strategies discussed in [this section](entries.md#entry-uri-formats) apply to categories, as well.
+
+When a category’s URL is requested, Craft renders the template defined by its group, and makes a special `category` variable available. Supposing a _Flavors_ category group had a **URI Format** of `flavors/{slug}` and was configured to use `_categories/flavors.twig` as its **Template**:
+
+```twig
+{{ category.title }}
+{# -> "Sour Aromatics" #}
+
+{{ category.ancestors.collect()
+ .select('title')
+ .join(' / ') }}
+{# -> "Sour & Fermented / Sour" #}
+```
+
+Custom fields attached to the group’s field layout are also available via the `category` variable.
+
## Querying Categories
You can fetch categories in your templates or PHP code using **category queries**.
@@ -107,17 +125,17 @@ Once you’ve created a category query, you can set [parameters](#parameters) on
### Example
-We can display a navigation for all the categories in a category group called “Topics” by doing the following:
+We can display a navigation for all the categories in a _Flavors_ category group by doing the following:
1. Create a category query with `craft.categories()`.
-2. Set the [group](#group) parameter on it.
+2. Set the [group](#group) parameter on it using its handle.
3. Fetch the categories with `.all()`.
4. Loop through the categories using a [nav](../twig/tags.md#nav) tag to create the navigation HTML.
```twig
{# Create a category query with the 'group' parameter #}
{% set myCategoryQuery = craft.categories()
- .group('topics') %}
+ .group('flavors') %}
{# Fetch the categories #}
{% set categories = myCategoryQuery.all() %}
@@ -137,11 +155,13 @@ We can display a navigation for all the categories in a category group called
```
+Keep in mind that this only holds value for category groups with multiple hierarchical levels. If you were working with a “flat” taxonomy, the template above can use a `{% for %}` tag in lieu of Craft’s `{% nav %}` tag.
+
::: tip
To maintain the exact order you see in the control panel, add `orderBy('lft ASC')` to your query:
```twig
{% set myCategoryQuery = craft.categories()
- .group('topics')
+ .group('flavors')
.orderBy('lft ASC') %}
```
:::
@@ -150,19 +170,33 @@ To maintain the exact order you see in the control panel, add `orderBy('lft ASC'
When you’ve attached a [categories field](../field-types/categories.md) to another type of element, you can query for those elements when you have a reference to a category.
-For example, if we were building a blog with dedicated “Topic” (category) pages, we might build a query like this to look up posts:
+For example, if we were building a “Tasting Notes” database with dedicated _Flavor_ (category) pages, we might build a query like this to look up records:
```twig
-{% set posts = craft.entries()
+{% set records = craft.entries()
.relatedTo({
targetElement: category,
- field: 'topics',
+ field: 'flavors',
})
.all() %}
```
+::: tip
+Here, `flavors` also happens to be the handle of the relational field. _You do not need to follow any kind of convention when naming relational fields_; the groups available for selection in a given categories field are explicitly defined on that field.
+:::
+
+You can also use the field’s query method to set up the relational constraint, automatically:
+
+```twig
+{% set records = craft.entries()
+ .flavors(category)
+ .all() %}
+```
+
+In both cases, we’re assuming the `category` variable comes from Craft, when loading an individual category’s [template](#routing-and-templates).
+
### Parameters
Category queries support the following parameters:
diff --git a/docs/5.x/reference/element-types/entries.md b/docs/5.x/reference/element-types/entries.md
index 656e1d950..9c8ef0373 100644
--- a/docs/5.x/reference/element-types/entries.md
+++ b/docs/5.x/reference/element-types/entries.md
@@ -156,12 +156,32 @@ You can supplement the automatic [sources](../../system/elements.md#sources) pre
### Entry URI Formats
-Channel and structure sections can choose whether their entries should be assigned URLs in the system by filling in the **Entry URI Format** setting. Singles have a “URI” setting, but it is typically defined statically or omitted (if it doesn’t need its own URL).
+Channel and structure sections can choose whether their entries should be given URLs in the system by filling in the **Entry URI Format** setting. Singles also have this setting, but it is typically a static path or omitted (if it doesn’t need its own URL, like a [global set](globals.md)).
The entry URI format is an [object template](../../system/object-templates.md), which gets evaluated each time an entry in the section is saved. The result is saved as the entry’s **URI** in the system, and is used to generate URLs (i.e. via `entry.url`) and when Craft is determining how to [route](../../system/routing.md) a request.
When Craft matches a request to an entry, its section’s designated **Template** is rendered. That template is automatically provided an `entry` variable, set to the resolved object, and ready to output any of its attributes or custom field data.
+#### URI Recipes
+
+Consider these tips for creating special URIs:
+
+- A URI that evaluates to `__home__` (and nothing more) will be available at your site’s base path;
+- An empty URI means the entry does not get a route and will not have a public URL—unless you define one manually via `routes.php`;
+- Any Twig statement can be used to output values in a URI template—including ones that query for other elements, e.g. `{{ craft.entries().section('mySingle').one().slug }}/news` (see note below);
+- [Aliases](../../configure.md#aliases-and-environment-variables) can be evaluated with the [`alias()` function](../twig/functions.md#alias): `{{ alias('@basePressUri') }}/news`, `{{ alias('@mySectionUri') }}`.
+- The [null-coalescing operator](https://twig.symfony.com/doc/3.x/templates.html#other-operators) (`??`) can silently swallow undefined variable errors (like `parent.uri`, above);
+
+::: warning
+Elements accessed via the current `object` (like authors or relational fields) will be loaded in the appropriate site, but _new_ element queries (like the example above that uses `craft.entries()`), must explicitly use `.site()` to avoid loading elements in the default site:
+
+```
+{craft.entries().section('mySingle').site(object.siteId).one().slug}
+```
+
+The current element’s site ID can always be accessed via `object.siteId`.
+:::
+
#### Hierarchical URIs
Structure sections may benefit from nested paths, for child entries:
@@ -186,21 +206,15 @@ The above template could also be expressed with this syntax:
With the above Entry URI Format, a top-level entry’s URI would be `earth/south-america`, with a nested entry having `earth/south-america/chile`.
-::: tip
-Consider these tips for creating special URIs:
-
-- A URI that evaluates to `__home__` (and nothing more) will be available at your site’s base path;
-- An empty URI means the entry does not get a route and will not have a public URL—unless you define one manually via `routes.php`;
-- Any Twig statement can be used to output values in a URI template—including ones that query for other elements, e.g. `{{ craft.entries().section('mySingle').one().slug }}/news`;
-- [Aliases](../../configure.md#aliases-and-environment-variables) can be evaluated with the [`alias()` function](../twig/functions.md#alias): `{{ alias('@basePressUri') }}/news`, `{{ alias('@mySectionUri') }}`.
-- The [null-coalescing operator](https://twig.symfony.com/doc/3.x/templates.html#other-operators) (`??`) can silently swallow undefined variable errors (like `parent.uri`, above);
-:::
-
#### Nested Entry URLs
-[Nested entries](#nested-entries) in Matrix fields can also be configured to have URLs—but the settings are part of the field, not a section.
+[Nested entries](#nested-entries) in [Matrix fields](../field-types/matrix.md) can also be configured to have URLs—but the settings are part of the field, not a section. As a result, entries of a given [type](#entry-types) may have URLs in some contexts, and not in others!
-A single entry type may have URLs in some contexts, and not in others!
+In a nested entry’s URI format, you can access the _owner_’s attributes using `{owner.someAttribute}`:
+
+```
+{owner.uri}/steps/{slug}
+```
### Preview Targets Team Pro