splent_feature_editions
The editions 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
The editions of a recurring event. It refines splent_feature_events, so
every event can belong to an edition. /editions is the archive, with the
current edition on top, and /editions/<slug> shows one edition with its
programme day by day, its photos, posters and sponsors. With a current
edition, /events becomes that edition's programme and the home page hero
shows its dates, venue and registration link. All of it goes through the
slots events opens, so this feature copies none of its templates.
The description of an edition is stored HTML, and the edition page renders
it with the framework's rich_text filter, which keeps the formatting and
drops scripts, event handlers and javascript: links.
The image of an edition and its registration page are addresses typed in
the panel, which the pages put in an src and in the href of the Register
button. The form refuses an address that is not http://, https://,
mailto: or a path on the site, javascript: and data: among them, with
the reason above the form and what was typed still in it, and saves nothing.
The pages draw those addresses through the framework's safe_url filter,
and the website of a sponsor and the photo of a speaker, which other
features store, too, so an address stored before a form checked it points
nowhere instead of running.
The panel manages the editions at /admin/editions. There an edition is
created, edited, flagged as the current one or deleted, gets its photo
gallery, posters and sponsors, and adopts the events with no edition dated
within it.
The events form gets an edition selector, which offers "No edition" and
every edition. Before it is drawn, this feature sends the
event-edition-choices signal with the account, the choices and the event,
so another feature may narrow what the selector offers that account without
this one knowing about it. A listener returns the choices it allows, or None
to have no say, and the selector keeps what every listener allows. The
edition the event is in already always stays, so the form never moves an
event by leaving its edition out. splent_feature_edition_staff listens
there. When narrowing fails, a listener that raises for instance, the error
is logged and the selector offers what it offers with no listener, "No
edition" and every edition, so the site administrator keeps every choice,
and a feature that narrows the selector still checks the save.
This feature does not depend on splent_feature_edition_staff and works
the same without it. It only sends the signal and asks has_role, so
nobody has to listen or register a policy.
Access
The screens of this feature under /admin/editions open for the accounts
whose role is admin or staff, the same pair the admin dashboard lets in.
Any other signed-in account gets 403 and does not see the Editions link in
the sidebar, and an anonymous visitor is sent to log in. The public pages
stay open to everyone. The /admin/editions/<id>/staff screens belong to
splent_feature_edition_staff and follow its rules.
Another feature can decide for these screens through an access policy, which
the framework asks before the roles (register_access_policy for the
endpoints under editions.admin). splent_feature_edition_staff registers
one, which lets in an account that holds a role in some edition although its
own role is user, and that feature then narrows it to what its role allows
in each edition. splent_feature_edition_staff also keeps out a staff
account that holds no role in an edition. The sidebar link follows the same
answer. Without such a feature the roles alone decide, and to let a person
manage the editions you give their account the staff role.
splent feature:auth set-role someone@example.com staff
With splent_feature_edition_staff installed, give the person a role in an
edition instead (see that feature). There, taking events out of the site
level, where an event with no edition sits, or into it belongs to the site
administrator, with adopting events as the one deliberate exception. The
editor of an edition may adopt the events with no edition dated within it,
and from then on they are the edition's events and its staff manage them.
That is how an editor brings site-level events into their edition.
Every button of the editions list, and the "+ New edition" button of the
events admin, is drawn only when has_role, asked with the endpoint it
opens, says yes. A button on the row of an edition asks with
view_args={"edition_id": ...} for that edition, as the screen's own gate
does. So an access policy that closes one of those screens to an account,
for every edition or for one, hides its button too, and no button answers
403.
The edit form of an edition offers the current edition flag to the accounts
that the screen setting the current edition lets in. It asks has_role
about editions.admin_set_current, so an access policy for that screen
decides here too. Anyone else sees the flag without being able to change
it, and a hidden field sends the flag as it was when the form was drawn, so
saving the form keeps it. A stale form, drawn before someone else moved the
flag, sends the old flag, and a crafted one may send any. The view refuses
such a save from those accounts with 403 and saves nothing of it, instead of
putting the flag back, and reloading the form shows the flag as it is now.
The form adding an edition locks the flag the same way, and a new edition
sent with the flag by such an account gets 403 too.
The site shows the flagged edition as current while it is published. When no
published edition is flagged, it shows the published edition that starts
last, of two that start on the same day the one with the higher number, and
of two with the same number too the one stored last. Data written outside
the form can leave two published editions flagged, and the site then shows
the one stored last. So the accounts that may not set the current edition
get the Published box locked where publishing or unpublishing the edition
would change which edition is current, with a hidden field that sends it as
it is and a line under it that says why. That is always the case for the
flagged edition, and otherwise for the published edition that starts last
and for a draft that starts after it. When no published edition is flagged,
the form also tells them under the start date that the dates, and the number
on a tie, decide which edition is current. Whatever the form sends, the view
refuses with 403 a save by those accounts after which current() would
return another edition, so the rule holds with any access policy, and a
feature that checks the save first, as splent_feature_edition_staff does,
may answer it its own way. A save sent back to the form, by this view or by
such a feature, says why above the form.
A new edition can become current by its dates alone, when no published edition is flagged and it is published and starts last. So the form adding an edition, for an account that may not set the current edition, works out whether the new edition would be current, and if so saves nothing and sends the save back to the form with the reason. A draft is always saved, and so is an edition added while a published edition is flagged.
EditionsService.current_if_saved(edition, data) answers which edition
would be current were the edition saved with the form's values, from the
query current() runs and with nothing saved, and
EditionsService.current_moves_if_added(data) whether a new edition saved
with them would make another edition current. edition_form_data(form) in
routes.py reads the form as the view saves it. All three are public, so
a feature that checks a save before the view runs reads it as this feature
does.
Use it in a product
splent feature:add splent_feature_editions
Develop
splent feature:test splent_feature_editions
splent feature:contract splent_feature_editions
Release
splent feature:release splent_feature_editions --dry-run --bump patch
splent feature:release splent_feature_editions
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.
splent_feature_edition_staff needs the version of this feature that sends
event-edition-choices and has current_if_saved, so when both change,
release this one first.
Metadata
Release files for splent-feature-editions 0.2.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_editions-0.2.0.tar.gz | 59.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| splent_feature_editions-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 137.4 kB
Release files / splent_feature_editions-0.2.0.tar.gz
| Download URL | splent_feature_editions-0.2.0.tar.gz |
|---|---|
| Size | 59.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a0185bb0bb3452c4355e15f2fca9ca13dd2a8126ac920b9389f07148530c8139
|
|
BLAKE2b-256 checksum How to use checksums |
efe33457e344e3d3a51ec2bbc74c9ce28c2f0795be3ef27f6855fd0917ec729e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|
Release files / splent_feature_editions-0.2.0-py3-none-any.whl
| Download URL | splent_feature_editions-0.2.0-py3-none-any.whl |
|---|---|
| Size | 78.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
781e70373e51c013d4f3f9cc2578c5457b2902672b20846141887f6e2606939e
|
|
BLAKE2b-256 checksum How to use checksums |
7b0b324d5f3fdc40cfe4e3275f62743ce6bc2254b6912945c9355278e883745a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|
Security for splent-feature-editions 0.2.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.