Skip to content

Commit

Permalink
Analysis page and series (#20)
Browse files Browse the repository at this point in the history
* Add skeleton models for Theme / Topic pages
* Add base analysis series and page models
* Use a custom icon for the contact detail snippet
* Update the StreamField block template to pass the block ID to its children
* Set parent/subpage types for the new page models
* Wire in the analysis page template
* Add series functionality (latest/previous releases)
* Add tests and fail if coverage under 90%
* Tidy up based on code review
  * Make the accredited / census blocks separate includes
  * Include changes to release dates when status is confirmed
  * Allow setting the release date when switching to confirmed
  * Only allow release date or text, not both
  * Prevent release calendar page deletion through the UI
  * Move the changes to the release date below contact details
    e.g. https://www.ons.gov.uk/releases/disabilitypaygapsintheuk2014to2023
  * Switch to using a StreamField for the release page related links
  * Disable the "too-few-public-methods" pylint check globally
  * Make the equation/ONS embed check reusable
  • Loading branch information
zerolab authored Nov 14, 2024
1 parent 4fac1fb commit 1abcd7b
Show file tree
Hide file tree
Showing 47 changed files with 1,339 additions and 39 deletions.
4 changes: 4 additions & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -435,12 +435,16 @@ disable=raw-checker-failed,
wrong-import-order,
missing-module-docstring,
too-many-ancestors,
too-few-public-methods,
missing-class-docstring,
fixme

# note:
# - wrong-import-order: covered by ruff
# - missing-module-docstring: because they should be self-explanatory
# - too-many-ancestors: because of our and Wagtail's use of mixins
# - too-few-public-methods: because of Django Meta classes
# - missing-class-docstring: mostly because of Django classes.
# - fixme: because we want to leave TODO notes for future features.

# Enable the message, report, category or checker with the given id(s). You can
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ lint: lint-py lint-html lint-frontend ## Run all linters (python, html, front-en
.PHONY: lint-py
lint-py: ## Run all Python linters (ruff/pylint/mypy).
poetry run ruff check .
poetry run ruff format --check .
find . -type f -name "*.py" | xargs poetry run pylint --reports=n --output-format=colorized --rcfile=.pylintrc --django-settings-module=cms.settings.production -j 0
make mypy

Expand Down
Empty file added cms/analysis/__init__.py
Empty file.
59 changes: 59 additions & 0 deletions cms/analysis/blocks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from typing import TYPE_CHECKING, ClassVar

from django.utils.text import slugify
from wagtail.blocks import RichTextBlock, StreamBlock, StructBlock
from wagtail.embeds.blocks import EmbedBlock
from wagtail.images.blocks import ImageChooserBlock
from wagtailmath.blocks import MathBlock

from cms.core.blocks import (
DocumentsBlock,
HeadingBlock,
ONSEmbedBlock,
PanelBlock,
RelatedContentBlock,
RelatedLinksBlock,
)

if TYPE_CHECKING:
from wagtail.blocks import StructValue


class SectionContentBlock(StreamBlock):
"""The analysis section content StreamField block definition."""

rich_text = RichTextBlock()
panel = PanelBlock()
image = ImageChooserBlock(group="Media")
documents = DocumentsBlock(group="Media")
embed = EmbedBlock(group="Media")
equation = MathBlock(group="DataVis", icon="decimal")
ons_embed = ONSEmbedBlock(group="DataVis", label="ONS General Embed")
related_links = RelatedLinksBlock(RelatedContentBlock(), icon="link")

class Meta:
template = "templates/components/streamfield/stream_block.html"
block_counts: ClassVar[dict[str, dict]] = {"related_links": {"max_num": 1}}


class SectionBlock(StructBlock):
"""The analysis section block definition."""

title = HeadingBlock()
content = SectionContentBlock()

def to_table_of_contents_items(self, value: "StructValue") -> list[dict[str, str]]:
"""Convert the value to the table of contents component macro format."""
return [{"url": "#" + slugify(value["title"]), "text": value["title"]}]

class Meta:
template = "templates/components/streamfield/analysis_section_block.html"


class AnalysisStoryBlock(StreamBlock):
"""The analysis StreamField block definition."""

section = SectionBlock()

class Meta:
template = "templates/components/streamfield/stream_block.html"
104 changes: 104 additions & 0 deletions cms/analysis/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Generated by Django 5.1.2 on 2024-11-04 17:20

import django.db.models.deletion
import wagtail.contrib.routable_page.models
import wagtail.fields
from django.db import migrations, models

import cms.core.fields


class Migration(migrations.Migration):
initial = True

dependencies = [
("core", "0002_contactdetails"),
("images", "0002_customimage_description"),
("wagtailcore", "0094_alter_page_locale"),
]

operations = [
migrations.CreateModel(
name="AnalysisSeries",
fields=[
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.page",
),
),
],
options={
"abstract": False,
},
bases=(wagtail.contrib.routable_page.models.RoutablePageMixin, "wagtailcore.page"),
),
migrations.CreateModel(
name="AnalysisPage",
fields=[
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.page",
),
),
("listing_title", models.CharField(blank=True, max_length=255)),
("listing_summary", models.CharField(blank=True, max_length=255)),
("social_text", models.CharField(blank=True, max_length=255)),
("news_headline", models.CharField(blank=True, max_length=255)),
("summary", wagtail.fields.RichTextField()),
("main_points_summary", wagtail.fields.RichTextField()),
("release_date", models.DateField()),
("next_release_date", models.DateField(blank=True, null=True)),
("is_accredited", models.BooleanField(default=False)),
("is_census", models.BooleanField(default=False)),
("headline_figures", cms.core.fields.StreamField(blank=True, block_lookup={})),
("content", cms.core.fields.StreamField(block_lookup={})),
("show_cite_this_page", models.BooleanField(default=True)),
(
"contact_details",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to="core.contactdetails",
),
),
(
"listing_image",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to="images.customimage",
),
),
(
"social_image",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to="images.customimage",
),
),
],
options={
"abstract": False,
},
bases=("wagtailcore.page", models.Model),
),
]
Empty file.
Loading

0 comments on commit 1abcd7b

Please sign in to comment.