splent_feature_team
The team feature of a SPLENT product line.
A SPLENT feature is a Python package that a product composes with others:
its models, routes, services, templates and hooks are registered when the
product starts. What this feature provides and requires is listed in the
[tool.splent.contract] section of pyproject.toml, which
splent feature:contract --write keeps in sync with the source.
What it does
A directory of people. /team lists the published members grouped by
role, in the order of Role.order, and /team/<slug> shows one profile.
A member can hold several roles and then appears under each of them. A
member's bio is stored HTML, and the profile draws it through the
framework's rich_text filter, which keeps the formatting and drops
scripts, event handlers and javascript: links.
A member who is not published stays off both pages, and /team/<slug>
answers 404 for them. The panel's accounts still open the profile to check
it, with a notice that the public does not see it.
The panel manages it at /admin/team (members) and /admin/team/roles
(roles). Only the panel's accounts reach those screens.
The public pages extend shell('public') and the panel's screens
shell('app'), so a product that points a shell at another layout
(SPLENT_SHELL_PUBLIC, SPLENT_SHELL_APP) moves them with it.
Menus
team registers two entries in the framework's menu registry.
| Key | Section | Order | Icon | Opens | Shown to |
|---|---|---|---|---|---|
team |
site |
50 | users |
/team, and is current on a profile too |
Everyone |
team_admin |
admin |
70 | user-check |
/admin/team, current on every panel screen |
The panel's accounts |
team_admin names no roles: it takes the ones role_required asks for on
the panel's screens. A product hides or reorders either by key in its
[tool.splent.layout.menu].
For one minor the panel link is still drawn in
layout.authenticated_sidebar as well, for the shells that fill their
sidebar from hooks. A shell draws the registry or those slots, never both,
or the link shows twice.
Addresses
The member's photo, website and profile links and the role's logo and
website end up in a src or an href of the public pages, so the forms
check them before they store them.
| Address | Allowed |
|---|---|
| A member's photo, a role's logo | An http:// or https:// address, or a path on the site such as /static/uploads/logo.png |
| A member's website and profile links, a role's website | An http:// or https:// address |
A value that breaks a rule is refused with a message, nothing is saved, and the form comes back with what was typed. A photo, a logo or a website longer than its 512 character column is refused rather than cut, since a cut address points somewhere else. The member form has no website field, so saving it keeps the website a seeder set.
A seeder writes the columns directly and is not checked. Every template
draws a stored address through the framework's safe_url filter, so one
that is not http, https, mailto or a path on the site renders as an
empty href or src instead of running.
Roles that stand for an organisation
A role is a section of the page. When a product groups its people by organisation (a university, a company, a partner lab), each organisation is a role, and the role can carry three optional details.
| Column | What the public page shows |
|---|---|
description |
a paragraph under the section heading |
logo |
an image beside the heading, an image URL like TeamMember.photo |
link |
the website, linked from the logo and shown as an address |
A role without any of them renders as the bare heading it always was, so products that group by job (Faculty, Students, Staff) see no difference.
In the panel, the Details button of each role on /admin/team/roles opens
the full form, where the logo is picked from the media library.
The form checks the logo and the website as described in Addresses, and a role whose details are refused keeps what it had.
A product seeds its organisations with its own seeder, replacing this feature's sample data.
import os
from splent_framework.seeders.BaseSeeder import BaseSeeder
from splent_io.splent_feature_media.services import MediaService
from splent_io.splent_feature_team.models import Role, TeamMember
LOGOS = os.path.join(os.path.dirname(__file__), "static", "logos")
class MyTeamSeeder(BaseSeeder):
replaces = ("splent_io.splent_feature_team.seeders",)
def run(self):
logo = MediaService().import_from_file(
os.path.join(LOGOS, "somewhere.svg"), source_key="seed://my/somewhere"
)
[university] = self.seed(
[
Role(
name="University of Somewhere",
slug="university-of-somewhere",
order=1,
description="Develops and runs the platform.",
logo=logo.url,
link="https://www.somewhere.example",
)
]
)
person = TeamMember(name="Ada Lovelace", slug="ada-lovelace")
person.roles = [university]
self.seed([person])
A product that wants other markup for the page overrides
team/list.html in its own templates. Each group is a Role with
description, logo and link next to its name.
Configuration
Declared in [tool.splent.config]. A product overrides them in its own
[tool.splent.config].
| Key | Default | What it does |
|---|---|---|
TEAM_SHOW_EMPTY_ROLES |
false |
Lists on /team the roles with no published member too, each with its heading, logo and description and no people. For a product whose roles stand for organisations. |
TEAM_CARD_EMAIL_ADDRESS |
false |
What a member's card on /team shows for the member's address. false the word "Email", which keeps the card's row of links short; true the address itself, linked the same way. The member's own page always shows the address. |
# the product's pyproject.toml
[tool.splent.config]
TEAM_SHOW_EMPTY_ROLES = true
TEAM_CARD_EMAIL_ADDRESS = true
team/list.html gets those roles in groups with an empty list of
members, so a product that overrides it finds them there as well.
Use it in a product
splent feature:add splent_feature_team
Develop
splent feature:test splent_feature_team
splent feature:contract splent_feature_team
Release
splent feature:release splent_feature_team --dry-run --bump patch
splent feature:release splent_feature_team
The first command rehearses the release and changes nothing. The second publishes it to the git forge and to PyPI, and a PyPI version is permanent.
Metadata
Release files for splent-feature-team 0.8.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| splent_feature_team-0.8.0.tar.gz | 1.8 MB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| splent_feature_team-0.8.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 3.6 MB
Release files / splent_feature_team-0.8.0.tar.gz
| Download URL | splent_feature_team-0.8.0.tar.gz |
|---|---|
| Size | 1.8 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2cae5401a94515e91a0c48937e9ae97c97ad1008562d84e871f2408d3fb29d37
|
|
BLAKE2b-256 checksum How to use checksums |
2ee5d7eeaa870d75dee38692e8bce29977686ccb5a820d578f0c2a92d823d10d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.16
|
Release files / splent_feature_team-0.8.0-py3-none-any.whl
| Download URL | splent_feature_team-0.8.0-py3-none-any.whl |
|---|---|
| Size | 1.8 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
15070cea8039161cde58fb2a286ba93ae44c1cb20ba47f8a8eca902083db3891
|
|
BLAKE2b-256 checksum How to use checksums |
f69edae1595623a47558e90461f123c1c09d3a13a0e6de7526007426f82ee224
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.16
|
Security for splent-feature-team 0.8.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.