Skip to main content

mbarde.shorturls

Plone-Addon for managing short URLs.

Installation

uv pip install mbarde.shorturls

Setup

Short URLs live in Short URL Folders (ShortUrlContainer), which only Managers / Site Administrators can add. You can create as many as you like, e.g. one per institution. In a Short URL Folder:

  • every logged-in user can add short URLs - no sharing setup needed
  • every short URL is only visible to and editable by its owner (the user who created it)
  • users with the Editor role on the folder (Sharing tab: Can edit) can see, edit, disable and enable all short URLs in it, users with the Reader role (Can view) can see all of them. Granting these roles on a regular folder containing several Short URL Folders applies to all of them.

Suffixes are unique across the whole site, not per folder. They can't be changed after creation. Leave the suffix empty (in the add form or when creating short URLs via REST API) to get a random one.

Disabling instead of deleting

Owners and Editors can't delete short URLs, they disable them: a disabled short URL doesn't redirect anymore (visitors get the same response as for an unknown suffix), but keeps its suffix reserved - otherwise someone else could register it, and old shared or printed links would lead to their target. Owners and Editors can enable disabled short URLs again. Only Managers / Site Administrators can delete short URLs, which frees their suffix.

Short URL Folders are unordered (no drag & drop sorting), as an ordered folder would get slow with tens of thousands of short URLs.

Allowed domains

Allowed domains in the control panel restricts the target URLs of short URLs to these domains (one per line) and their subdomains: example.org allows example.org, www.example.org etc., but not notexample.org. Leave empty to allow all domains. It's checked when short URLs are added or edited (forms and REST API) - existing short URLs keep redirecting.

Redirecting

<portal-url>/@@go/<suffix> redirects (302) to the target URL of the short URL with that suffix (matched case-insensitively) and counts the click. Unknown suffixes - and the base URL itself (@@go without a suffix) - redirect (302) to the Fallback target URL configured in the control panel (e.g. your main website), or return a 404 if none is configured. Don't set it to the base URL or an unknown short URL, that would redirect in a loop.

To serve short URLs from their own domain (e.g. https://go.example.org/<suffix>), set Base URL in the mbarde.shorturls control panel to that domain (used to display the short URLs) and let the web server rewrite all requests to @@go, e.g. for nginx and a Plone site with id Plone:

server {
    server_name go.example.org;
    ...
    location / {
        rewrite ^/(.*)$ /VirtualHostBase/https/go.example.org:443/Plone/VirtualHostRoot/@@go/$1 break;
        proxy_pass http://127.0.0.1:8080;
    }
}

Contribute

Development

Setup

uv venv venv
source venv/bin/activate
uv pip install -e .
uv pip install -r requirements-dev.txt

Test, lint & format

venv/bin/pytest
venv/bin/pytest -k name_of_a_test
venv/bin/black src/
venv/bin/flake8 src/
venv/bin/isort src/

Run a local Plone instance

Create a Zope/Plone instance once (creates instance/, gitignored, with an admin user):

venv/bin/mkwsgiinstance -d instance -u admin:admin

Start it:

venv/bin/runwsgi instance/etc/zope.ini

Then open http://localhost:8080 and use "Create a new Plone site" (log in as admin), adding mbarde.shorturls as add-on during site creation, or afterwards via Site Setup > Add-ons.

Set debug-mode on in instance/etc/zope.conf for template auto-reload during development (Python changes still need a restart).

Update translations

source venv/bin/activate
uv pip install i18ndude
cd src/mbarde/shorturls/locales
./update.sh

Zope only ever loads compiled .mo catalogs at startup, never the .po source files directly (and .mo files are gitignored, since they're a build artifact). Add this to the <environment> section of instance/etc/zope.conf so a fresh .po is automatically compiled to .mo on every restart - otherwise translations silently keep showing the English text no matter which language is negotiated:

<environment>
  zope_i18n_compile_mo_files true
</environment>

Publish to PyPI

  1. Bump version in pyproject.toml (a version can never be uploaded twice), commit and push.
  2. Run tests: venv/bin/pytest
  3. Build fresh (clear dist/ first, it may contain older versions):
rm -rf dist build src/*.egg-info
uv build
uvx twine check dist/*
  1. Upload with an API token from pypi.org (Account settings > API tokens):
uv publish --token pypi-...
  1. Tag the release: git tag vX.Y.Z && git push --tags
  2. Verify in a clean environment: uv pip install --pre mbarde.shorturls (--pre is only needed for pre-releases like 1.0.0rc2).

Optional dry run against TestPyPI (separate account and token): uv publish --publish-url https://test.pypi.org/legacy/ --token pypi-...

VS Code setup

Plugins:

  • ms-python.black-formatter: Python formatting
  • ms-python.flake8: Python linting
  • ms-python.vscode-pylance: Python language support
  • ms-python.isort: Python imports sorting
  • esbenp.prettier-vscode: .html/.pt/.md formatting
  • redhat.vscode-xml: .xml formatting

Settings:

{
  "[markdown]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[python]": {
    "editor.defaultFormatter": "ms-python.black-formatter"
  },
  "editor.formatOnSave": true,
  "files.associations": {
    "*.pt": "html",
    "*.zcml": "xml"
  },
  "editor.codeActionsOnSave": {
    "source.organizeImports": "always"
  }
}

License

The project is licensed under the GPLv2, see LICENSE.GPL.

AI Usage

Parts of this addon were developed with assistance from Claude Code, Anthropic's agentic coding CLI. The tool was used interactively under human direction and review.

Metadata

Release files for mbarde.shorturls 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mbarde.shorturls 1.0.1
File Size Uploaded Provenance
mbarde_shorturls-1.0.1.tar.gz 49.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for mbarde.shorturls 1.0.1
File Interpreter ABI Platform
mbarde_shorturls-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 119.4 kB

Release files / mbarde_shorturls-1.0.1.tar.gz

Download URL mbarde_shorturls-1.0.1.tar.gz
Size 49.5 kB
Tags Source
SHA-256 checksum
How to use checksums
a25c945f5458d197f3d36b20a63ce7e16bb31243162665228f5fd76d4e70bacc
BLAKE2b-256 checksum
How to use checksums
2ba38f4534b16755bce26f4943a7e00cc8fa518038048a5429765a5ffb0d8127
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / mbarde_shorturls-1.0.1-py3-none-any.whl

Download URL mbarde_shorturls-1.0.1-py3-none-any.whl
Size 69.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
06271ae7ef28f95b75269bfd4cc843a48b383d522f902c204c98672800b175de
BLAKE2b-256 checksum
How to use checksums
2764548231a848a2584e7d3445900e80b7bc84354707008242487e887406a669
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for mbarde.shorturls 1.0.1

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

1.0.1 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