diff --git a/docs/customize/look-and-feel/img/communities-dashboard.png b/docs/customize/look-and-feel/img/communities-dashboard.png new file mode 100644 index 00000000..7e04b1c7 Binary files /dev/null and b/docs/customize/look-and-feel/img/communities-dashboard.png differ diff --git a/docs/customize/look-and-feel/img/settings-menu.png b/docs/customize/look-and-feel/img/settings-menu.png new file mode 100644 index 00000000..76a4950c Binary files /dev/null and b/docs/customize/look-and-feel/img/settings-menu.png differ diff --git a/docs/customize/look-and-feel/img/user-dashboard.png b/docs/customize/look-and-feel/img/user-dashboard.png new file mode 100644 index 00000000..68a2902a Binary files /dev/null and b/docs/customize/look-and-feel/img/user-dashboard.png differ diff --git a/docs/customize/look-and-feel/menus.md b/docs/customize/look-and-feel/menus.md new file mode 100644 index 00000000..75bf7569 --- /dev/null +++ b/docs/customize/look-and-feel/menus.md @@ -0,0 +1,150 @@ +# Change Menus/Tabs + +For navigation, InvenioRDM often uses menus or tabs. For example, one such menu is the user-dropdown menu: + +![User-settings menu with its 5 default entries](./img/settings-menu.png) + +And one such set of tabs is at the top of the user-dashboard: + +![User's personal dashboard with three tabs labeled (left-to-right) "Uploads", "Communities", and "Requests"](./img/user-dashboard.png) + +In the codebase, menus and sets of tabs like those are referred as *menus*, so we do so here for the remainder of this how-to as well. +Their options (e.g., "Uploads", "Profile") are referred as *submenus*. + +These *menus* can be configured in the following ways: + +- which submenus to show +- what title-text to show in those submenus +- which endpoint to request when clicking them +- how to dynamically show/hide them (e.g. depending on currently logged-in user) + +## Configurable Properties + +Properties of existing submenus can be overridden, +properties of newly added submenus can be freely chosen. +All submenus share the following properties: + +| Name | Example values | Notes | +|----------------|--------------------------------------|-----------------------------------------------------| +| `endpoint` | `"invenio_app_rdm_users.uploads"` | flask-endpoint requested when clicking this submenu | +| `order` | `1`, `2`, `10`, `-1`, `1.5` | lower ordered submenus are shown further left | +| `text` | `_("Uploads")`, `_("Communities")` | title-text shown on submenus | +| `visible_when` | `flask_menu.menu.CONDITION_TRUE` | when to show this submenu
- must be of type `callable[[], bool]`
- `CONDITION_TRUE` is just a named `lambda: True`
- use `CONDITION_FALSE` to hide a submenu | +| ... | ... | in addtion to the above properties, all arguments for `flask_menu.menu:MenuNode.register` are configurable | + +For example, consider the user-dashboard pictured above. +Its *Uploads* submenu has the following default configuration: +```python +{ + "endpoint": "invenio_app_rdm_users.uploads", + "order": 1, # small number as to show this submenu left-most + "text": _("Uploads"), + "visible_when": flask_menu.menu.CONDITION_TRUE, # always show this submenu + ..., # advanced configuration properties omitted for brevity +} +``` + +## Add new submenus to existing menu + +Existing menus can be extended by custom-configured submenus. +To add a new submenu to an existing menu: + +1. Get the name of the to-be-added-to menu from the [list of menus](#list-of-menus) + For example, the user-dashboard is named `"dashboard"` (most names of menus/submenus are straightforward). +2. Write a function that registers the new submenu + ```python + # ext.py # ext.py is commonly used, you may use another file though + + from flask_menu import current_menu + from invenio_i18n import lazy_gettext as _ # for translations + + def finalize_app(): + # get the user-dashboard menu via its name "dashboard": + user_dashboard_menu = current_menu.submenu("dashboard") + + # register a new submenu to the user-dashboard: + user_dashboard_menu.register( + "name-of-submenu", + endpoint="my_blueprint.my_endpoint", + order=4, # the three already existing submenus have `order` 1 through 3 + text=_("Title of new Submenu"), # could also use an untranslated bare string + # note: could add other properties here, otherwise their default is used + # note: `visible_when` defaults to always visible + ) + + ... # could .register more submenus here (or do so in another package) + ``` +3. Register your function with the `invenio_base.finalize_app` entrypoint. + This will make your function be called at the app-finalization build-step. + For example, when using setuptools' `setup.cfg` with your python package, add: + ```ini + # setup.cfg + + [options.entry_points] + invenio_base.finalize_app = + my_package_name = my_package_name.ext:finalize_app + ``` + +!!! info "For entrypoints to take effect" + For entrypoint changes to be picked up, you will need to reinstall the python package. + *This is necessary even if the package is installed editably!* + + After entrypoint changes are picked up, + you will further need to restart the server for changes to take effect: + ```shell + + invenio-cli run + ``` + +## Modify existing submenus + +The defaults of submenus' properties are selectively overridable via config-variables. +To modify an existing submenu's properties: + +1. Find the name of the corresponding override-variable in the [list of menus](#list-of-menus) + For example, the override-variable for the user-dashboard is named `USER_DASHBOARD_MENU_OVERRIDES`. +2. Find the name of the to-be-overridden submenu in that same [list of menus](#list-of-menus) + For example, the user-dashboard has a submenu for communities. + This submenu is named (obviously enough) `"communities"`. +3. Add to your `invenio.cfg`: + ```python + # invenio.cfg + + from flask_menu.menu import CONDITION_FALSE + + USER_DASHBOARD_MENU_OVERRIDES = { + "communities": { + "visible_when": CONDITION_FALSE, + # other properties will be left unchanged + } + # other submenus will be left unchanged + } + ``` + +The above example hides the *Communities* submenu from the user-dashboard menu +by overriding its `visible_when` property. +For other overridable properties see [configurable properties](#configurable-properties). + +!!! info "Have you tried to turn it off and on again?" + You will need to restart the server for changes to take effect: + ```shell + + invenio-cli run + ``` + +!!! warning "On overriding user-added submenus: DON'T" + Currently, (sub)menu-overrides are adopted at app-finalization. + Users adding their own submenus (as described above) is also done at app-finalization. + Hence attempting to override submenus added by (other) users depends on + loading order of app-finalization entrypoints and might break anytime. + +## List of menus + +The following list of menus is non-exhaustive. +Not all menus are overridable, but all menus can be extended by additional submenus. + +| Image | Description | Name of menu and its submenus | Name of override-variable | +|-------|-------------|-------------------------------|---------------------------| +| ![User's personal dashboard with three tabs labeled (left-to-right) "Uploads", "Communities", and "Requests"](./img/user-dashboard.png) | Dashboard on user's personal page | `"dashboard"`
├─`"uploads"`
├─`"communities"`
└─`"requests"` | `USER_DASHBOARD_MENU_OVERRIDES` | +| ![Communities dashboard with its 6 default tabs](./img/communities-dashboard.png) | Dashboard on communities page | `"communities"`
├─`"home"`
├─`"search"`
├─`"requests"`
├─`"submit"`
├─`"members"`
├─`"settings"`
├─`"curation_policy"`
└─`"about"` | No associated override-variable | +| ![User-settings menu with its 5 default entries](./img/settings-menu.png) | User settings menu | `"settings"`
├─`"profile"`
├─`"change_password"`
├─`"security"`
├─`"notifications"`
├─`"oauthclient"`
└─`"applications"` | No associated override-variable | diff --git a/mkdocs.yml b/mkdocs.yml index 1a61dce3..c8e4262b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -72,6 +72,7 @@ nav: - Change templates: "customize/look-and-feel/templates.md" - Change theme: "customize/look-and-feel/theme.md" - Change font: "customize/look-and-feel/font.md" + - Change menus: "customize/look-and-feel/menus.md" - Authentication: "customize/authentication.md" - Sending emails: "customize/emails.md" - Search: