This example is roughly equivalent to the config file example.
This example is roughly equivalent to the config example above – the parameters of the `groupby.add_watcher` function correspond to the same config parameters.
The parameters of the `@groupby.watch` function (`root`, `attribute`, `slug`, `template`) correspond to the same config parameters described above.
Additionally, you can set other types in `set_fields` (all strings are evaluated in jinja context!).
There is a new `flatten` parameter:
- Flatten determines how Flow elements are processed.
`@watcher.grouping` sets the callback to generate group keys.
It has one optional flatten parameter:
-`flatten` determines how Flow elements are processed.
If `False`, the callback function is called once per Flow element.
If `False`, the callback function is called once per Flow element.
If `True` (default), the callback is called for all Flow-Blocks of the Flow individually.
If `True` (default), the callback is called for all Flow-Blocks of the Flow individually.
The attribute `testB` can be attached to either the Flow or a Flow-Block regardless.
The attribute `testB` can be attached to either the Flow or a Flow-Block regardless.
The `args` parameter of the `convert_simple_example()` function is a named tuple, it has three attributes:
The `args` parameter of the `convert_simple_example()` function is a named tuple, it has three attributes:
1. The `record` points to the `Page`source which contains the tag.
1. The `record` points to the `Page`record that contains the tag.
2. The `key` tuple `(field-key, flow-index, flow-key)` tells which field is processed.
2. The `key` tuple `(field-key, flow-index, flow-key)` tells which field is processed.
For Flow types, `flow-index` and `flow-key` are set, otherwise they are `None`.
For Flow types, `flow-index` and `flow-key` are set, otherwise they are `None`.
3. The `field` value is the content of the processed field.
3. The `field` value is the content of the processed field.
The field value is reoughly equivalent to the following:
One **important** thing to notice is, we use `on_groupby_before_build_all` to register our callback function.
Notice, `add_watcher` accepts a config file as parameter which keeps also track of dependencies and rebuilds pages when you edit the config file.
This is required because we would like to modify the source **before** it is written to disk.
Further, the `yield` call returns the slugified group-key.
If you look back to the [simple example](#simple-example), we used `on_groupby_after_build_all` because we did not care when it is executed.
First, you do not need to slugify it yourself and second, potential replacements from `key_map` are already handled.
Generally, it makes little difference which one you use (`on-after` is likely less busy).
Just know that you can process the source before or after it is build.
For Markdown fields, we can modify the `source` attribute directly.
For Markdown fields, we can modify the `source` attribute directly.
All other field typed need to be accessed via `args.record` key indirection.
All other field types need to be accessed via `args.record` key indirection (see [simple example](#simple-example)).
```ini
```ini
[testC]
root=/
slug="advanced/{}/".format(this.key)
template=example-advanced.html
[testC.pattern]
match={{([^}]{1,32})}}
match={{([^}]{1,32})}}
```
```
Lastly, the config file contains a regular expression which matches `{{` + any string less than 32 characters + `}}`.
The config file takes the same parameters as the [config example](#quick-config).
Notice, the parenthesis (`()`) will match the inner part but the replace function (`re.sub`) will remove the `{{}}` too.
As you can see, `slug` is evaluated in jinja context.
If the user changes the regex pattern in the config file, we need to rebuild all tags.
We introduced a new config option `testC.pattern.match`.
For this purpose we need to track changes to the config file.
This regular expression matches `{{` + any string less than 32 characters + `}}`.
This is done by calling:
Notice, the parenthesis (`()`) will match only the inner part but the replace function (`re.sub`) will remove the `{{}}`.
```python
@groupby.depends_on(file1,file2,...)
## Misc
It was shortly mentioned above that slugs can be `None` (only if manually set to `slug = None`).
This is useful if you do not want to create subpages but rather an index page containing all groups.
This can be done in combination with the next use-case:
```jinja2
{%- for x in this|vgroups('TestA', 'TestB', recursive=True)|unique|sort %}
<a href="{{ x|url }}">({{ x.group }})</a>
{%- endfor %}
```
```
You can query the groups of any parent node (including those without slug).
The keys (`'TestA', 'TestB'`) can be omitted which will return all groups of all attributes (you can still filter them with `x.config.key == 'TestC'`).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.