wagtail-roost
News and blog publishing for Wagtail: sections, articles, authors, tags and RSS feeds.
Features
- Sections and subsections — organise your news into sections, nested as deep as you like. Each section has its own landing page and a browsable date archive (daily, weekly or monthly — your choice per section).
- Articles — rich article pages with authors, tags and hand-picked related articles.
- Author profiles — every author gets a profile page with their articles.
- Tag pages — every tag gets its own landing page with a description and image.
- RSS feeds — for all articles, per section, per tag and per author, with an on/off switch on each section, tag and author.
- Navigation menus — build multi-level menus in the admin and render them anywhere with a template tag.
- Search-engine and social ready — articles and author profiles include structured data (JSON-LD) for Google News and rich search results, and every page carries Open Graph and Twitter card tags so shared links unfurl with title, description and image.
- Bring your own design — the bundled templates are minimal semantic HTML, meant to be overridden to match your site.
Install
# from PyPi
uv add wagtail-roost # or: pip install wagtail-roost
# or straight from the repository:
uv add git+https://codeberg.org/Lupus/wagtail-roost.git
Add to INSTALLED_APPS:
INSTALLED_APPS = [
"roost",
"wagtail.contrib.redirects",
"wagtail.contrib.routable_page",
"wagtail.contrib.table_block",
"wagtail.embeds",
"wagtail.sites",
"wagtail.users",
"wagtail.snippets",
"wagtail.documents",
"wagtail.images",
"wagtail.admin",
"wagtail",
"modelcluster",
"taggit",
# ... plus the django.contrib apps every Django project has ...
]
On top of a standard Wagtail install, roost needs
wagtail.contrib.routable_page (section, tag and author URLs),
wagtail.contrib.table_block and wagtail.embeds (article body
blocks) and wagtail.snippets (authors, tags and navigations).
Wire up Wagtail's URLs in your project's urls.py:
from django.urls import include, path
from wagtail import urls as wagtail_urls
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.documents import urls as wagtaildocs_urls
urlpatterns = [
...
path("admin/", admin.site.urls), # existing
path("cms/", include(wagtailadmin_urls)),
path("documents/", include(wagtaildocs_urls)),
path("", include(wagtail_urls)), # must be LAST — catch-all
]
Also make sure these standard Wagtail settings are set:
WAGTAIL_SITE_NAME = "My News Site"
WAGTAILADMIN_BASE_URL = "https://www.example.com"
WAGTAIL_SITE_NAME is the default publisher name in structured data,
and WAGTAILADMIN_BASE_URL is needed to build absolute URLs.
Run python manage.py migrate.
Note:
treebeard.E001warning. You may see atreebeard.E001system check warning. This is a known false positive from the Wagtail 7.x + django-treebeard 5.x combination — django-treebeard added this check, and Wagtail's own Page/Collection managers trigger it even though Wagtail handles it correctly internally. It's noise coming from library code, not yours. Wagtail's recommended workaround is to silence it:SILENCED_SYSTEM_CHECKS = ["treebeard.E001"]
Then, in the Wagtail admin: create a News index page (the home of all news, tag pages and the global feed), add Section pages under it, and write Article pages inside sections. Add an Author index page to publish author profiles.
Tip: to get URLs that start with the section slug (/politics/…
rather than /news/politics/…), make the News index your site's
root page (Settings → Sites). The root page's own slug never appears
in URLs.
Navigation
Create a Navigation snippet in the admin and give it a code. Menus can have as many levels as you need — links to pages or external URLs, grouped under dropdowns, with whole navigations nestable inside each other.
Render a navigation by its code:
{% load roost_tags %}
{% navigation "main" %}
Sitemap
Sitemap includes: news index, section, and article pages (via
wagtail.contrib.sitemaps.Sitemap); tag pages (roost.sitemaps.TagSitemap);
author profile pages (roost.sitemaps.AuthorSitemap).
Wire them together in your urls.py:
from wagtail.contrib.sitemaps import views as sitemap_views
from wagtail.contrib.sitemaps.sitemap_generator import Sitemap as WagtailPageSitemap
from roost.sitemaps import AuthorSitemap, TagSitemap
sitemaps = {
"pages": WagtailPageSitemap,
"tags": TagSitemap,
"authors": AuthorSitemap,
}
urlpatterns += [
path("sitemap.xml", sitemap_views.sitemap, {"sitemaps": sitemaps}, name="sitemap"),
]
Requires wagtail.contrib.sitemaps and django.contrib.sitemaps in
INSTALLED_APPS.
Archive bucket pages are intentionally left out of the sitemap — they are non-canonical listing views of articles that are already covered by their own entries.
Settings
All optional, set in your Django settings:
| Setting | Default | Purpose |
|---|---|---|
ROOST_TAG_RSS_DEFAULT |
True |
whether new tags start with their feed enabled |
ROOST_ARCHIVE_GRANULARITY_DEFAULT |
"month" |
default archive period for new sections |
ROOST_FEED_LIMIT |
10 |
max items per feed |
ROOST_LATEST_COUNT |
10 |
articles shown on landing pages |
ROOST_PUBLISHER_NAME |
Wagtail site name | publisher name in structured data |
ROOST_PUBLISHER_LOGO |
None |
publisher logo URL in structured data (required for Google News rich results) |
ROOST_SOCIAL_NETWORKS |
built-in list | networks offered for author social links (default: Bluesky, Facebook, Instagram, LinkedIn, Mastodon, Website, X, YouTube) |
Templates
Templates extend base.html from your project and expect title,
meta, extra_head and content blocks. Override any of them under
roost/ in your own templates directory.
When starting a new project, the best practice is to copy the roost templates into that project and adapt them there — they're meant as a starting point for your own design, and having them in your project makes them easy to edit and keeps your markup under version control.
Because the markup is plain semantic HTML, a lightweight stylesheet
is enough for a decent default look — the bundled demo project simply
links Pico CSS in its base.html.
Development
Uses uv — no manual venv or activation needed:
uv sync # create .venv, install everything
uv run pytest # run the test suite
uv run testproject/manage.py migrate # set up the demo project
uv run testproject/manage.py runserver
uv build # build sdist + wheel
uv publish # release to PyPI
Release files for wagtail-roost 0.3.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| wagtail_roost-0.3.5.tar.gz | 114.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wagtail_roost-0.3.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 140.0 kB
Release files / wagtail_roost-0.3.5.tar.gz
| Download URL | wagtail_roost-0.3.5.tar.gz |
|---|---|
| Size | 114.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bc23b816ac2fd05a498fb7da26de8358c584d75f468b2453990332c17480bba7
|
|
BLAKE2b-256 checksum How to use checksums |
52c953b34a16e6f090963c7d3b06521a3ea8a42918ef9c9816db8bf74ac9073f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.14 {"installer":{"name":"uv","version":"0.12.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"CachyOS Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / wagtail_roost-0.3.5-py3-none-any.whl
| Download URL | wagtail_roost-0.3.5-py3-none-any.whl |
|---|---|
| Size | 25.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
90868ebdf32629be6bdc25b1260e7f604d3fc55c7cd4ef709aea5facba673a96
|
|
BLAKE2b-256 checksum How to use checksums |
3922ca97aef7d7c2ca53d238ea8a83f791d4299a74a924a8c7f828f9d8cf717c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.14 {"installer":{"name":"uv","version":"0.12.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"CachyOS Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|