Skip to main content

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)

Source distribution for splent-feature-editions 0.2.0
File Size Uploaded Provenance
splent_feature_editions-0.2.0.tar.gz 59.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for splent-feature-editions 0.2.0
File Interpreter ABI Platform
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.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page