Skip to content

Story 2375: Wagtail Integration for create a post#2526

Open
jlchilders11 wants to merge 3 commits into
developfrom
jc/2375-create-a-post
Open

Story 2375: Wagtail Integration for create a post#2526
jlchilders11 wants to merge 3 commits into
developfrom
jc/2375-create-a-post

Conversation

@jlchilders11

@jlchilders11 jlchilders11 commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Issue: #2375

Summary & Context

Implements backend wagtail integration with the V3 create a post page. When creating a post, new pages are saved as revisions and submitted for moderation.

Changes

  • Replaces the backend creation of Entry models with the creation of PostPage models on the V3 create a post page
  • Maintains all existing form validation to ensure no regression of functionality
  • Implements library based tagging of created pages. Uses existing tags if possible, otherwise creates tags on submission.
  • On submission, submits pages to the moderation queue and alerts moderators.

‼️ Risks & Considerations ‼️

Please list any potential risks or areas that need extra attention during review/testing

Notes: The moderation queue will be upgraded in another ticket in order to only send pages to human moderation if they fail automated moderation. Additionally, we currently only bother running the summary and video thumbnail tasks if the page is set to live. This means that moderators will not see the description and thumbnail before the page is live.

Testing notes:
In order to see the moderation queue in action, the tester may want to set themselves as a moderation. This can be done through the cms at Settings > User > Username, going to the group tab, checking the box next to moderator, and saving the model. This will cause them to get alerts when pages are sent to moderation as well as being able to see the moderation queue on the home page of the cms.

Self-review Checklist

  • Link this PR to the related GitHub Project ticket

Summary by CodeRabbit

  • New Features

    • Added support for creating and publishing V3 posts with multiple content types.
    • Added optional images and library tagging during post creation.
    • Added workflow initiation and success redirects for newly created posts.
    • Added validation for unsupported post types with clear error handling.
  • Bug Fixes

    • Improved error handling when V3 post submissions fail, preserving entered draft content for correction.

@jlchilders11 jlchilders11 linked an issue Jul 15, 2026 that may be closed by this pull request
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jlchilders11, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 44 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 45d61570-728b-4e31-b251-2ccb116a3383

📥 Commits

Reviewing files that changed from the base of the PR and between 328513f and a85332b.

📒 Files selected for processing (1)
  • news/views.py
📝 Walkthrough

Walkthrough

Changes

V3 Post Creation

Layer / File(s) Summary
Reusable post block definitions
pages/blocks.py
Named blog, news, URL, and video block constants are reused by POST_BLOCKS.
V3 type selection and context
news/views.py
V3 post types resolve to block and form mappings, invalid selections are rejected, and related-library options come from ordered Library records.
Wagtail draft creation and submission
news/views.py
Submissions create PostPage drafts with optional images and library tags, save revisions, start workflow, and update validation and redirect handling.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant V3CreateForm
  participant V3AllTypesCreateView
  participant PostPage
  participant ContentTag
  participant Workflow
  V3CreateForm->>V3AllTypesCreateView: submit selected post type and fields
  V3AllTypesCreateView->>PostPage: create draft with block content
  V3AllTypesCreateView->>ContentTag: attach related library tags
  V3AllTypesCreateView->>PostPage: save revision
  V3AllTypesCreateView->>Workflow: start workflow
Loading

Possibly related issues

  • boostorg/website-v2 issue 2375 — Covers the post-creation flow involving moderation, draft handling, image uploads, and related-library tagging.

Possibly related PRs

Suggested reviewers: herzog0, javiercoronadonarvaez, julioest

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly names the main change: Wagtail integration for create-a-post.
Description check ✅ Passed The description covers issue, summary, changes, risks, and testing notes, with only some template fields left unfilled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jc/2375-create-a-post

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
news/views.py (1)

524-529: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Map post types directly to block names.

The block instance is never used, triggering RUF059, while Ruff also requires the mutable class mapping to be declared as ClassVar.

Proposed cleanup
+from typing import ClassVar

-    _POST_BLOCK_MAP: dict[str, tuple[str, Block]] = {
-        "blog": BLOG_BLOCK,
-        "news": NEWS_BLOCK,
-        "link": LINK_BLOCK,
-        "video": VIDEO_BLOCK,
+    _POST_BLOCK_MAP: ClassVar[dict[str, str]] = {
+        "blog": BLOG_BLOCK[0],
+        "news": NEWS_BLOCK[0],
+        "link": LINK_BLOCK[0],
+        "video": VIDEO_BLOCK[0],
     }
...
-        block_config = self._POST_BLOCK_MAP.get(post_type, None)
+        block_name = self._POST_BLOCK_MAP.get(post_type)
...
-        if block_config is None or form_class is None:
+        if block_name is None or form_class is None:
...
-        block_name, block_class = block_config

Also applies to: 552-563

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@news/views.py` around lines 524 - 529, Update the post-type mappings in the
relevant view class to map each type directly to its block-name string instead
of storing unused block instances, and annotate the mutable class-level mappings
with ClassVar. Apply the same change to both _POST_BLOCK_MAP and the additional
mapping around the referenced section, preserving all existing post-type keys
and block names.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@news/views.py`:
- Around line 580-582: Update the view flow around PostIndexPage.objects.first()
to explicitly handle a missing index_page before calling
index_page.add_child(...). Ensure fresh or misconfigured sites receive the
intended safe response or initialization behavior instead of dereferencing None,
while preserving the existing path when a PostIndexPage exists.
- Around line 596-603: Update the image handling in the form submission flow to
avoid using Image.objects.get_or_create with title=image.name, which can
associate an unrelated existing image. Create a fresh Wagtail Image for each
upload, or use an explicit file-content-based deduplication strategy if reuse is
required, then assign the resulting image to page.image.
- Around line 604-627: Update the tag assignment in the flow around
index_page.add_child and page.tags.add so TaggableManager receives the
ContentTag instance directly, or explicitly unpack the collection if retaining
plural handling; preserve the existing conditional behavior and ensure tagging
succeeds after page creation.
- Around line 586-588: In the page update flow, replace the assignment to the
read-only cached property page.publish_at with an assignment to page.go_live_at
using the cleaned publish_at value. Ensure this occurs before save_revision() so
the requested publish time is persisted on PostPage.

---

Nitpick comments:
In `@news/views.py`:
- Around line 524-529: Update the post-type mappings in the relevant view class
to map each type directly to its block-name string instead of storing unused
block instances, and annotate the mutable class-level mappings with ClassVar.
Apply the same change to both _POST_BLOCK_MAP and the additional mapping around
the referenced section, preserving all existing post-type keys and block names.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e130d60d-0c42-4ee0-911e-df1366e9b5e7

📥 Commits

Reviewing files that changed from the base of the PR and between 865a4ac and 328513f.

📒 Files selected for processing (2)
  • news/views.py
  • pages/blocks.py

Comment thread news/views.py
Comment thread news/views.py Outdated
Comment thread news/views.py
Comment thread news/views.py Outdated
@julhoang julhoang self-requested a review July 15, 2026 21:38

@julhoang julhoang left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Jeremy! I think we're missing the image reduction task from the workflow. Would you mind adding it?

Accepted formats: PNG and JPEG. Maximum upload file size: 5MB. Any uploaded file larger 1MB should be reduced to <1MB before saving to S3, the reduction function is out of scope. Note: Please update the image limit in the copy from 1MB to 5MB

Comment thread news/views.py
@@ -392,11 +397,13 @@ def _v3_create_context():
],
"related_libraries_options": [
("", "Select"),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we remove this ("", "Select") option as well?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to maintain the Select option, or otherwise have a "clear selection" option, just in case the post is actually unrelated to any library and one is selected in error.

@herzog0 herzog0 self-requested a review July 16, 2026 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Webpage Integration: Create a Post

2 participants