Skip to content

Commit 88c5d12

Browse files
tistoericof
andauthored
Update Readme (#3)
* Update first part of README * Add who is this for section * features section overhaul * Add requirements section * Remove the control panel section from README * Update backend README * Update frontend README * Add screenshots to README * Sync README files * Polish READMEs and add news fragments - Fix broken markdown link in the frontend README caused by a missing blank line after the badge HTML block - Complete the frontend installation instructions with the required `addons` registration - Add a Usage section describing the keyword control panel - Add a License section covering both packages - Split Requirements into backend and frontend - Add the Cookieplone attribution to the root credits - Add documentation news fragments for all three towncrier scopes Refs #3 * Lint fixes --------- Co-authored-by: Érico Andrei <andrei@kitconcept.com> Co-authored-by: Érico Andrei <ericof@gmail.com>
1 parent a4d8574 commit 88c5d12

9 files changed

Lines changed: 252 additions & 60 deletions

File tree

README.md

Lines changed: 82 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,87 @@
1-
# kitconcept-keywordmanager 🚀
1+
<div align="center">
2+
3+
<h1 align="center">Keyword Manager for Plone</h1>
4+
5+
</div>
6+
7+
<div align="center">
28

39
[![Built with Cookieplone](https://img.shields.io/badge/built%20with-Cookieplone-0083be.svg?logo=cookiecutter)](https://github.com/plone/cookieplone-templates/)
4-
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
10+
11+
[![PyPI](https://img.shields.io/pypi/v/kitconcept.keywordmanager)](https://pypi.org/project/kitconcept.keywordmanager/)
12+
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/kitconcept.keywordmanager)](https://pypi.org/project/kitconcept.keywordmanager/)
13+
[![PyPI - Plone Versions](https://img.shields.io/pypi/frameworkversions/plone/kitconcept.keywordmanager)](https://pypi.org/project/kitconcept.keywordmanager/)
14+
15+
[![npm](https://img.shields.io/npm/v/@kitconcept/volto-keywordmanager)](https://www.npmjs.com/package/@kitconcept/volto-keywordmanager)
16+
[![](https://img.shields.io/badge/-Storybook-ff4785?logo=Storybook&logoColor=white&style=flat-square)](https://kitconcept.github.io/kitconcept-keywordmanager/)
17+
18+
19+
[![GitHub contributors](https://img.shields.io/github/contributors/kitconcept/kitconcept-keywordmanager)](https://github.com/kitconcept/kitconcept-keywordmanager)
20+
[![GitHub Repo stars](https://img.shields.io/github/stars/kitconcept/kitconcept-keywordmanager?style=social)](https://github.com/kitconcept/kitconcept-keywordmanager)
21+
522
[![CI](https://github.com/kitconcept/kitconcept-keywordmanager/actions/workflows/main.yml/badge.svg)](https://github.com/kitconcept/kitconcept-keywordmanager/actions/workflows/main.yml)
623

24+
</div>
25+
26+
The **Keyword Manager** is a Plone 6 add-on that lets content editors keep their site's keywords (also called subjects or tags) clean and consistent — without needing developer support. From a dedicated control panel, editors can rename, merge, and delete keywords, and every content item on the site is updated automatically.
27+
728
> [!WARNING]
8-
> This add-on is meant to be used in combination with the [volto-light-theme](https://github.com/kitconcept/volto-light-theme). If you plan to use this add-on with plain Volto you will have to write your own styles for it. You can use the existing ones via manual import like this `import "@kitconcept/volto-keywordmanager/theme/_main.scss"` or as reference. Read more about theming [here](https://6.docs.plone.org/volto/theming/theming-a-base-theme.html).
29+
> This add-on is designed to work with [volto-light-theme](https://github.com/kitconcept/volto-light-theme). If your site uses a different theme, you will need to provide your own styles or import the existing ones manually: `import "@kitconcept/volto-keywordmanager/theme/_main.scss"`. See the [Volto theming documentation](https://6.docs.plone.org/volto/theming/theming-a-base-theme.html) for details.
930
10-
Change, merge and delete keywords (subjects) in Plone 6.
31+
![Keyword Manager](./assets/Keyword_Manager.png)
1132

12-
![Keyword Manger](./assets/Keyword_Manager.png)
33+
## Who is this for?
34+
35+
- **Content editors** who manage tags and subjects on a Plone website and want a clean interface to keep keywords organised.
36+
- **Site administrators and technical staff** who need to install and configure the add-on for their institution's Plone instance.
1337

1438
## Features 🔥
1539

16-
- Control Panel (frontend)
17-
- Configurable (backend)
18-
- REST-API Services (backend)
19-
- Utility (backend)
40+
- **Browse all keywords** currently in use, sorted by name or by number of occurrences.
41+
- **Filter keywords** to quickly find a specific term in a long list.
42+
- **Rename a keyword** — the new name is applied to every content item that uses it automatically.
43+
- **Merge keywords** — combine synonyms, fix typos, or resolve ambiguities by merging multiple keywords into one canonical term; all affected content is updated in one step.
44+
- **Delete keywords** — remove terms that are no longer needed.
45+
- **Manage multiple keyword fields** — works with the standard `Subject` field and any other keyword-type index in the catalog.
46+
47+
## Requirements
48+
49+
### Backend
50+
51+
- Plone 6.1 or 6.2
52+
- Python 3.11, 3.12, or 3.13
53+
54+
### Frontend
55+
56+
- Volto 18 or later (Plone's React-based frontend)
57+
- Node.js 24
58+
- pnpm
59+
- [volto-light-theme](https://github.com/kitconcept/volto-light-theme) (recommended; see warning above)
2060

2161
## Installation 🔧
2262

2363
1. Frontend package:
2464

65+
Add the package to your Volto project.
66+
2567
```shell
2668
pnpm add @kitconcept/volto-keywordmanager
2769
```
2870

71+
Then register it as an add-on in your project's `package.json`.
72+
73+
```json
74+
"addons": [
75+
"@kitconcept/volto-keywordmanager"
76+
],
77+
"dependencies": {
78+
"@kitconcept/volto-keywordmanager": "*"
79+
}
80+
```
81+
82+
> [!IMPORTANT]
83+
> Installing the package without adding it to the `addons` array will not enable the control panel.
84+
2985
1. Backend package:
3086

3187
```shell
@@ -38,12 +94,13 @@ Change, merge and delete keywords (subjects) in Plone 6.
3894
pip install kitconcept.keywordmanager
3995
```
4096

41-
## Control Panel
97+
Then install the add-on in your Plone site from the **Add-ons** control panel.
4298

43-
> [!NOTE]
44-
> This section is a work in progress. Expect more information in the coming releases.
99+
## Usage
45100

46-
The Keyword Manager allows you to maintain the keywords used in your website. Start by selecting the keyword field you want to manage. You can then sort, filter, rename, merge, or delete individual keywords.
101+
Once installed, the Keyword Manager is available in the Plone site control panel.
102+
Start by selecting the keyword field you want to manage, then sort, filter, rename, merge, or delete individual keywords.
103+
Every content item using an affected keyword is updated automatically.
47104

48105
## Configuration
49106

@@ -89,7 +146,7 @@ config.ALWAYS_REINDEX = (
89146
)
90147
```
91148

92-
## REST-API Services
149+
## REST API
93150

94151
### GET `/@keywords` (or `/path/to/page/@keywords`)
95152

@@ -133,6 +190,15 @@ km = getUtility(IKeywordManager)
133190

134191
Contributions are welcome! Please read [CONTRIBUTING.md](./CONTRIBUTING.md).
135192

193+
## License
194+
195+
This repository contains two packages, each under its own license.
196+
197+
| Package | Location | License |
198+
| ------- | -------- | ------- |
199+
| `kitconcept.keywordmanager` | [backend/](./backend/) | GPL-2.0-only |
200+
| `@kitconcept/volto-keywordmanager` | [frontend/](./frontend/) | MIT |
201+
136202
## Credits and acknowledgements 🙏
137203

138204
This add-on is based on code from Products.PloneKeywordManager, adapted and extended for Plone 6 & Volto.
@@ -152,3 +218,5 @@ Building on that foundation, this package was created by the kitconcept GmbH to
152218
There is an ongoing effort to bring keyword-management functionality into Plone core itself, tracked as [PLIP: Keyword Manager](https://github.com/plone/volto/issues/5300). This add-on is intended as a step toward that goal, a working, up-to-date implementation that can inform (and hopefully eventually be folded into) that core integration. Getting there will require several steps: stabilizing the add-on for Plone 6, gathering community feedback, aligning with the Volto/core UI patterns, and going through the PLIP review process. Contributions and feedback toward that end are welcome.
153219

154220
Thanks to Maik Jablonski and everyone who has contributed to Products.PloneKeywordManager over the years for the original work this builds on.
221+
222+
Generated using [Cookieplone (2.0.0a3)](https://github.com/plone/cookieplone) and [cookieplone-templates (cda10db)](https://github.com/plone/cookieplone-templates/commit/cda10db886223a9aa9be1b1368484296418bb880) on 2026-05-29 11:44:37.855709. A special thanks to all contributors and supporters!

backend/README.md

Lines changed: 124 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,48 @@
1-
# kitconcept.keywordmanager
1+
<div align="center">
22

3-
Change, merge and delete keywords (subjects) in Plone.
3+
<h1 align="center">Keyword Manager for Plone</h1>
4+
<h2 align="center">kitconcept.keywordmanager</h2>
45

5-
## Features
6+
</div>
67

7-
TODO: List our awesome features
8+
<div align="center">
89

9-
## Installation
10+
[![PyPI](https://img.shields.io/pypi/v/kitconcept.keywordmanager)](https://pypi.org/project/kitconcept.keywordmanager/)
11+
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/kitconcept.keywordmanager)](https://pypi.org/project/kitconcept.keywordmanager/)
12+
[![PyPI - Wheel](https://img.shields.io/pypi/wheel/kitconcept.keywordmanager)](https://pypi.org/project/kitconcept.keywordmanager/)
13+
[![PyPI - License](https://img.shields.io/pypi/l/kitconcept.keywordmanager)](https://pypi.org/project/kitconcept.keywordmanager/)
14+
[![PyPI - Status](https://img.shields.io/pypi/status/kitconcept.keywordmanager)](https://pypi.org/project/kitconcept.keywordmanager/)
15+
16+
[![PyPI - Plone Versions](https://img.shields.io/pypi/frameworkversions/plone/kitconcept.keywordmanager)](https://pypi.org/project/kitconcept.keywordmanager/)
17+
18+
[![CI](https://github.com/kitconcept/kitconcept-keywordmanager/actions/workflows/main.yml/badge.svg)](https://github.com/kitconcept/kitconcept-keywordmanager/actions/workflows/main.yml)
19+
20+
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
21+
22+
[![GitHub contributors](https://img.shields.io/github/contributors/kitconcept/kitconcept-keywordmanager)](https://github.com/kitconcept/kitconcept-keywordmanager)
23+
[![GitHub Repo stars](https://img.shields.io/github/stars/kitconcept/kitconcept-keywordmanager?style=social)](https://github.com/kitconcept/kitconcept-keywordmanager)
24+
25+
</div>
26+
27+
The backend package for Keyword Manager for Plone — a Plone 6 add-on that lets content editors rename, merge, and delete keywords (subjects/tags) across a site, with all content updated automatically. See also the frontend package [@kitconcept/volto-keywordmanager](https://www.npmjs.com/package/@kitconcept/volto-keywordmanager).
28+
29+
![Keyword Manager](https://raw.githubusercontent.com/kitconcept/kitconcept-keywordmanager/main/assets/Keyword_Manager.png)
30+
31+
## Features 🔥
32+
33+
- **Browse all keywords** currently in use, sorted by name or by number of occurrences.
34+
- **Filter keywords** to quickly find a specific term in a long list.
35+
- **Rename a keyword** — the new name is applied to every content item that uses it automatically.
36+
- **Merge keywords** — combine synonyms, fix typos, or resolve ambiguities by merging multiple keywords into one canonical term; all affected content is updated in one step.
37+
- **Delete keywords** — remove terms that are no longer needed.
38+
- **Manage multiple keyword fields** — works with the standard `Subject` field and any other keyword-type index in the catalog.
39+
40+
## Requirements
41+
42+
- Plone 6.1 or 6.2
43+
- Python 3.11, 3.12, or 3.13
44+
45+
## Installation 🔧
1046

1147
Install kitconcept.keywordmanager with uv.
1248

@@ -20,7 +56,89 @@ Create the Plone site.
2056
make create-site
2157
```
2258

23-
## Contribute
59+
## Configuration
60+
61+
This package allows for some configuration.
62+
63+
To configure one of the following options, import the config module like so:
64+
65+
```py
66+
from kitconcept.keywordmanager import config
67+
```
68+
69+
### Options
70+
71+
The keywords permission allows you to set a custom permission who should be able to manage keywords.
72+
73+
```py
74+
config.MANAGE_KEYWORDS_PERMISSION = "kitconcept.keywordmanager: Manage Keywords"
75+
```
76+
77+
The meta type of the keyword indexes can be set. This is only useful if you're one of those crazy people that use custom indexes.
78+
79+
```py
80+
config.META_TYPE = "KeywordIndex"
81+
```
82+
83+
There are indexes of `META_TYPE` we know we don't want to manage because bad things will happen. You can exclude those using:
84+
85+
```py
86+
config.IGNORE_INDEXES = [
87+
"object_provides",
88+
"allowedRolesAndUsers",
89+
"getRawRelatedItems",
90+
"getEventType",
91+
"block_types",
92+
]
93+
```
94+
95+
You can set a list of indexes that should always be reindex when merging or deleting keywords on objects. Most people won't need this.
96+
97+
```py
98+
config.ALWAYS_REINDEX = ("SearchableText",)
99+
```
100+
101+
## REST API
102+
103+
### GET `/@keywords` (or `/path/to/page/@keywords`)
104+
105+
| Parameter | Source | Type / Values | Required | Default | Description |
106+
| ------------ | ------ | --------------------------- | -------- | --------- | --------------------------- |
107+
| `idx` | form | string | no | "Subject" | The keyword index to query. |
108+
| `sort_order` | form | "ascending" or "descending" | no || The sort order of results. |
109+
| `sort_on` | form | "keyword" or "occurrence" | no || The field to sort on. |
110+
111+
### PATCH `/@keywords` (or `/path/to/page/@keywords`)
112+
113+
| Parameter | Source | Type / Values | Required | Default | Description |
114+
| -------------- | ------ | ------------- | -------- | --------- | -------------------------------------- |
115+
| `idx` | form | string | no | "Subject" | The keyword index to query. |
116+
| `new_keyword` | body | string | yes || The name of the keyword to be created. |
117+
| `old_keywords` | body | list[string] | yes || The old keywords to be deleted. |
118+
119+
### DELETE `/@keywords` (or `/path/to/page/@keywords`)
120+
121+
| Parameter | Source | Type / Values | Required | Default | Description |
122+
| --------- | ------ | ------------- | -------- | --------- | --------------------------------------- |
123+
| `idx` | form | string | no | "Subject" | The keyword index to query. |
124+
| `items` | body | list | yes || The name of the keywords to be deleted. |
125+
126+
### GET `/@keywordIndex`
127+
128+
No parameters.
129+
130+
## Utility
131+
132+
Getting the utility.
133+
134+
```py
135+
from kitconcept.keywordmanager.interfaces import IKeywordManager
136+
from zope.component import getUtility
137+
138+
km = getUtility(IKeywordManager)
139+
```
140+
141+
## Contributing 🐛
24142

25143
- [Issue tracker](https://github.com/kitconcept/kitconcept-keywordmanager/issues)
26144
- [Source code](https://github.com/kitconcept/kitconcept-keywordmanager/)
@@ -48,36 +166,6 @@ make create-site
48166
make install
49167
```
50168

51-
52-
### Add features using `plonecli` or `bobtemplates.plone`
53-
54-
This package provides markers as strings (`<!-- extra stuff goes here -->`) that are compatible with [`plonecli`](https://github.com/plone/plonecli) and [`bobtemplates.plone`](https://github.com/plone/bobtemplates.plone).
55-
These markers act as hooks to add all kinds of features through subtemplates, including behaviors, control panels, upgrade steps, or other subtemplates from `bobtemplates.plone`.
56-
`plonecli` is a command line client for `bobtemplates.plone`, adding autocompletion and other features.
57-
58-
To add a feature as a subtemplate to your package, use the following command pattern.
59-
60-
```shell
61-
make add <template_name>
62-
```
63-
64-
For example, you can add a content type to your package with the following command.
65-
66-
```shell
67-
make add content_type
68-
```
69-
70-
You can add a behavior with the following command.
71-
72-
```shell
73-
make add behavior
74-
```
75-
76-
```{seealso}
77-
You can check the list of available subtemplates in the [`bobtemplates.plone` `README.md` file](https://github.com/plone/bobtemplates.plone/?tab=readme-ov-file#provided-subtemplates).
78-
See also the documentation of [Mockup and Patternslib](https://6.docs.plone.org/classic-ui/mockup.html) for how to build the UI toolkit for Classic UI.
79-
```
80-
81169
## License
82170

83171
The project is licensed under GPLv2.

backend/news/3.documentation

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Updated the backend README and synced it with the top-level README. @tisto

backend/src/kitconcept/keywordmanager/services/delete.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ def reply(self):
1717

1818
if not isinstance(keywords, list):
1919
raise BadRequest(
20-
f"Invalid request: 'items' must be of type 'list', but received '{type(keywords).__name__}'."
20+
f"Invalid request: 'items' must be of type 'list', "
21+
f"but received '{type(keywords).__name__}'."
2122
)
2223
if not keywords:
2324
raise BadRequest("Invalid request: missing required parameter 'items'.")

backend/src/kitconcept/keywordmanager/services/get.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ def reply(self):
1818
if sort_order := self.request.form.get("sort_order"):
1919
if sort_order not in ("ascending", "descending"):
2020
raise BadRequest(
21-
f"Invalid sort_order '{sort_order}'. Must be 'ascending' or 'descending'."
21+
f"Invalid sort_order '{sort_order}'. Must be 'ascending' "
22+
"or 'descending'."
2223
)
2324
reverse = sort_order == "descending"
2425

backend/src/kitconcept/keywordmanager/services/update.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@ def reply(self):
1818

1919
if not isinstance(new_keyword, str):
2020
raise BadRequest(
21-
f"Invalid request: 'new_keyword' must be of type 'str', but received '{type(new_keyword).__name__}'."
21+
f"Invalid request: 'new_keyword' must be of type 'str', "
22+
f"but received '{type(new_keyword).__name__}'."
2223
)
2324
if not new_keyword:
2425
raise BadRequest(
2526
"Invalid request: missing required parameter 'new_keyword'."
2627
)
2728
if not isinstance(old_keywords, list):
2829
raise BadRequest(
29-
f"Invalid request: 'old_keywords' must be of type 'list', but received '{type(old_keywords).__name__}'."
30+
f"Invalid request: 'old_keywords' must be of type 'list', "
31+
f"but received '{type(old_keywords).__name__}'."
3032
)
3133
if not old_keywords:
3234
raise BadRequest(

0 commit comments

Comments
 (0)