Dedicated SEO-optimized project page with a devlog environment #165

Closed
blindxfish wants to merge 5 commits from blindxfish/devplacepy:pr2-project-devlog-seo into master
Contributor

Make the project page a dedicated, SEO-optimized project showcase with a professional devlog environment. Builds on the look-and-feel PR.

The page

  • Hero: owner-uploaded cover banner + framed project logo tile, title/status/tagline/chips/author overlaid on the banner behind a scrim (dark text shadow for readability), Visit Website CTA.
  • One encompassing dark card wraps the whole project; inner panels (tab bar, sidebar cards, devlog entries, comments) sit a step lighter - the reference's elev-1/elev-2 split.
  • Underline section tabs with live counts: Overview, Devlog, Screenshots, Comments, Files - server-rendered anchors, so crawlers index one complete document.
  • Devlog environment: every post linked to the project as styled cards (the page finally loads feed.css), a devlog-count header, and an owner Post update button opening the shared composer preset to the devlog topic + this project (form extracted to _post_composer_form.html, reused by the feed).
  • Screenshots gallery from image attachments with lightbox; owners add more via the More-menu Add screenshots modal (POST /projects/{slug}/screenshots, reusing link_attachments).
  • Sidebar: Links (owner-set website + repository), Stats (stars/updates/comments/files/forks + last update), Author card.

New owner fields

website_url, repo_url (validated/normalized), cover_image, logo_image (multipart uploads via the posts.image pattern) - in the create and edit modals, ProjectOut, the Devii actions and the API docs.

SEO

Type-mapped JSON-LD (game→VideoGame with gamePlatform, website→WebApplication, software/mobile_app→SoftwareApplication, game_asset→CreativeWork) with keywords, image (cover-first), screenshot[], aggregateRating from stars, comment counter, sameAs (website+repo), thumbnailUrl (logo), plus a Blog/BlogPosting graph for the devlog. Meta keywords, crawlable rel=next devlog pagination, and sitemap lastmod following the newest devlog post.

Tests

New unit tests (schema mapping, URL normalization, Blog graph), api tests (devlog counts, JSON-LD render, cover/logo upload round-trip, screenshots flow + non-owner 403, website/repo edit round-trip), e2e tests (stats card, preset composer, guest gating); the project comment/files e2e tests scope their locators per the documented dual-control idiom.

🤖 Generated with Claude Code

Make the project page a dedicated, SEO-optimized project showcase with a professional devlog environment. Builds on the look-and-feel PR. ## The page - **Hero**: owner-uploaded cover banner + framed project logo tile, title/status/tagline/chips/author overlaid on the banner behind a scrim (dark text shadow for readability), Visit Website CTA. - **One encompassing dark card** wraps the whole project; inner panels (tab bar, sidebar cards, devlog entries, comments) sit a step lighter - the reference's elev-1/elev-2 split. - **Underline section tabs** with live counts: Overview, Devlog, Screenshots, Comments, Files - server-rendered anchors, so crawlers index one complete document. - **Devlog environment**: every post linked to the project as styled cards (the page finally loads `feed.css`), a devlog-count header, and an owner **Post update** button opening the shared composer preset to the devlog topic + this project (form extracted to `_post_composer_form.html`, reused by the feed). - **Screenshots gallery** from image attachments with lightbox; owners add more via the More-menu **Add screenshots** modal (`POST /projects/{slug}/screenshots`, reusing `link_attachments`). - **Sidebar**: Links (owner-set website + repository), Stats (stars/updates/comments/files/forks + last update), Author card. ## New owner fields `website_url`, `repo_url` (validated/normalized), `cover_image`, `logo_image` (multipart uploads via the `posts.image` pattern) - in the create and edit modals, ProjectOut, the Devii actions and the API docs. ## SEO Type-mapped JSON-LD (game→VideoGame with gamePlatform, website→WebApplication, software/mobile_app→SoftwareApplication, game_asset→CreativeWork) with keywords, image (cover-first), `screenshot[]`, `aggregateRating` from stars, comment counter, `sameAs` (website+repo), `thumbnailUrl` (logo), plus a `Blog`/`BlogPosting` graph for the devlog. Meta keywords, crawlable `rel=next` devlog pagination, and sitemap `lastmod` following the newest devlog post. ## Tests New unit tests (schema mapping, URL normalization, Blog graph), api tests (devlog counts, JSON-LD render, cover/logo upload round-trip, screenshots flow + non-owner 403, website/repo edit round-trip), e2e tests (stats card, preset composer, guest gating); the project comment/files e2e tests scope their locators per the documented dual-control idiom. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
blindxfish added 9 commits 2026-08-09 22:41:43 +02:00
Retheme every token in variables.css to the terminal design language:
near-black surfaces (#0a0a0f/#111118/#1a1a24), terminal green accent
(#22c55e) with dark on-accent text, gray text ramp, #222233 borders,
sharp 4-8px radii, neutral depth shadows, and JetBrains Mono as the
primary UI font (vendored latin woff2, no CDN).

Follow-through outside the token file: white-on-accent buttons/tabs now
use the new --on-accent token for contrast, three var() fallback
violations shipping the old palette are gone, the dead --bg-hover token
is replaced with --bg-card-hover, avatar fallback SVG, statistics chart
palette, chat light-theme overrides, offline page, PWA manifest,
theme-color meta, OG image + app icons regenerated in the new palette,
and the /docs/styles-colors style guide now documents the new values.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The reference design is the devplace Next.js main branch, not the
terminal branch the previous commit tracked. Swap the token values to
that design language: deep indigo page (#271b5b) over near-black indigo
cards (#13112a/#1a1736), #11101f hairlines, purple-tinted text ramp
(#e9e4ff/#c8c3e5/#9b93c9), burnt-orange primary accent (#b73f1e) with
a raspberry hover (#af3050) and a rust-to-plum brand gradient, white
on-accent text, soft rounded radii (8/12/16px), the reference's diffuse
soft/medium/strong shadows, a warm accent glow, and Trebuchet MS as the
UI font (system font - the vendored JetBrains Mono files are removed
along with their base.html link).

Follow-through updated to match: theme-color meta + PWA manifest
(#271b5b), offline page, avatar fallback SVG, statistics chart palette
(brand ramp), chat light-theme overrides, OG image + app icons
regenerated in the new palette, and the /docs/styles-colors guide.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The signed-in dashboard is a 1200px two-column grid, but the shared
Code Farm promo section stayed at the guest page's 960px centered
measure, so it floated misaligned under the dashboard columns. A
landing-game-dashboard modifier (applied only when a user is signed
in) stretches it to the dashboard's own measure and gutters. The
Latest Posts grid becomes repeat(auto-fit, minmax(320px, 1fr)) so a
single post fills the row instead of leaving a dead half-column while
two or more still lay out as the original two columns.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Flatten control accents: no gradient or glow on buttons, tabs, or the FAB
Some checks failed
DevPlace CI / test (pull_request) Has been cancelled
3fca4be72e
The reference design uses flat primary buttons, so every interactive
control drops the brand gradient and the accent glow: .btn-primary
(flat accent, accent-hover on hover), the feed nav tabs, the projects
tabs, the sidebar active link, and the create-post FAB (which keeps a
neutral elevation shadow). Gradients remain only on decorative meters
and stripes (XP fills, progress bars, the project card top stripe).
The now-unused --glow-accent token is removed, and deepsearch.css
loses its var() fallback on the progress gradient.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The project detail page becomes a professional project overview: hero
with status/type/dates/forked-from, a stats strip (stars, updates,
comments, files, forks with #devlog/#comments anchors), an About
section, platforms, and the Devlog timeline under a proper h2 - now
rendered with feed.css loaded so the post cards are actually styled.
The owner posts updates from the page itself: a Post update button
opens the shared create-post composer preset to the devlog topic and
this project. The composer form is extracted into
_post_composer_form.html and reused by feed.html - one form, two
surfaces.

SEO: software_application_schema is type-aware via project_schema_type
(game -> VideoGame with gamePlatform, website -> WebApplication,
software/mobile_app -> SoftwareApplication, game_asset -> CreativeWork)
and now carries keywords, image, an aggregateRating from stars, and a
comment InteractionCounter. project_devlog_schema emits a Blog node
with one BlogPosting per devlog entry. The detail route feeds both,
adds meta keywords, and exposes the devlog cursor as rel=next; the
sitemap's project lastmod follows the newest devlog post via one
grouped query. devlog_count/comment_count ride ProjectDetailOut, the
docs projects-detail endpoint documents the before cursor, and the
routers/projects CLAUDE.md, templates CLAUDE.md and README document the
new surface. Unit, api and e2e tests cover the schema mapping, the
JSON-LD in the rendered page, the stats strip, and the preset composer.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The project detail page becomes a full project showcase on the site's
content measure. The hero card opens with a cover banner from the
project's first image attachment (brand-gradient band as fallback),
then title + status chip, type/platform chips, dates and forked-from
meta, the author row with an owner-set Visit Website CTA, and the
unchanged action row. A sticky anchor tab bar (Overview, Devlog,
Screenshots when images exist, Comments, Files) navigates the page
with plain server-rendered anchors so crawlers index one complete
document. The two-column body keeps About (description + non-image
attachments), the Devlog timeline and the comment thread in the main
column, adds a Screenshots gallery built from image attachments
(lightbox-wired thumbnails), and a sidebar with Links (website, files,
fork source), the Stats card with a last-update line, and the Author
card.

New optional projects.website_url rides the whole stack: normalized
and validated in models (scheme-less input gets https://, non-http(s)
rejected), settable in the create and edit modals, on ProjectOut, in
the Devii create/edit actions and the API docs, rendered as the hero
CTA and Links entry with rel noopener nofollow, and emitted as
schema.org sameAs. The app schema also gains screenshot urls from the
image attachments. The e2e project comment/files tests scope their
locators (.comment-form textarea, .project-detail-actions a) per the
documented dual-control idiom - the composer modal made the bare
selectors ambiguous - and new unit/api tests cover URL normalization,
sameAs/screenshot schema output, the cover, and the gallery.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The hero now matches the showcase reference: the title block, tagline
(first description line), type/platform chips, author row and started
date render OVERLAID on the cover banner behind a bottom scrim, with
the optional project logo as a framed tile beside them and the Visit
Website CTA on the right. The section tab bar switches to the underline
style with Overview active.

Owners control the missing pieces from the create and edit modals,
which are now multipart: cover_image and logo_image file uploads
(stored as bare uploaded filenames via save_inline_image, the
posts.image pattern; a new upload replaces the previous one) plus a
repo_url sibling of website_url (same normalization/validation). The
cover feeds og:image and the schema image, the logo becomes schema
thumbnailUrl, and sameAs now carries website + repository. repo_url
rides ProjectOut, the Devii create/edit actions and the API docs;
tests cover repo normalization, the multipart upload round-trip and
the hero render.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The showcase reference nests the whole project inside a single dark
card while inner panels sit a step lighter - the previous layout had
it inverted (dark cards straight on the page ground). A .project-shell
container now wraps the hero, tab bar and columns with the bg-card
surface and clipped corners, and every inner panel (tab bar, sidebar
cards, devlog post cards, empty state, comments section) flips to the
lighter bg-secondary elevation inside it. The tab bar loses its sticky
positioning (impossible inside the shell's overflow clip) and the hero
sheds its own card chrome since the shell provides it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Hero text shadow and an owner Add screenshots flow in the More menu
Some checks failed
DevPlace CI / test (pull_request) Has been cancelled
8f9f461244
The hero overlay title, tagline and author row get a dark text shadow
so they stay readable over bright cover art. The owner's More menu
gains Add screenshots: a modal with the shared attachment uploader
whose POST /projects/{slug}/screenshots (ProjectScreenshotsForm,
owner-only, audit project.screenshots.add, catalogued in events.md)
links the uploaded uids through the same attachments.link_attachments
choke point as create/edit and returns to #screenshots. Documented as
projects-screenshots in the API docs, exposed to Devii as
project_add_screenshots (upload via upload_file/attach_url first), and
covered by an api test for the owner flow, the gallery render, and the
non-owner 403.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author
Contributor

Closing this in favour of #166, which is the same feature rebuilt from scratch on current master with the review points addressed. Point by point:

1. The SEO layer is dropped entirely. No seo.py changes, no JSON-LD, no meta or schema work in the replacement. The page is the deliverable; search-engine markup is not part of it.

2. camelCase in the database. Those were schema.org JSON-LD property names (datePublished, sameAs and friends) in the SEO block, not column names. Nothing was ever written to the database in camelCase. Since the SEO layer is gone, the question is moot; the two new columns in the replacement are website_url and repo_url.

3. Every upload path is now the existing attachment pipeline. Cover image, logo and screenshots are all attachment references (cover_attachment_uid, logo_attachment_uid), uploaded by the existing dp-upload widget to /uploads/upload and linked through attachments.link_attachments. There is no second upload path and no bespoke file handling anywhere in the diff. The route validates each uid via database.get_user_attachment (must exist, belong to the actor, be an image) before linking, so a foreign or unknown uid is ignored rather than linked.

4. No markdown re-slicing. The only addition to content.py is count_project_devlog, which is a count query. Rendering stays entirely on render_content / render_title.

5. No comments or docstrings in source. Nothing under devplacepy/ adds either. The only docstrings in the diff are in test files that already use them.

Also folded in: the post composer form now lives once in templates/_post_composer_form.html and is included by both feed.html and project_detail.html, rather than being duplicated.

Full suite on the replacement branch: 3334 passed, 9 failed, the 9 being the tests/api/projects/workspace.py docker-CLI set that fails identically on untouched master here.

Closing this in favour of #166, which is the same feature rebuilt from scratch on current master with the review points addressed. Point by point: **1. The SEO layer is dropped entirely.** No `seo.py` changes, no JSON-LD, no meta or schema work in the replacement. The page is the deliverable; search-engine markup is not part of it. **2. camelCase in the database.** Those were schema.org JSON-LD property names (`datePublished`, `sameAs` and friends) in the SEO block, not column names. Nothing was ever written to the database in camelCase. Since the SEO layer is gone, the question is moot; the two new columns in the replacement are `website_url` and `repo_url`. **3. Every upload path is now the existing attachment pipeline.** Cover image, logo and screenshots are all attachment references (`cover_attachment_uid`, `logo_attachment_uid`), uploaded by the existing `dp-upload` widget to `/uploads/upload` and linked through `attachments.link_attachments`. There is no second upload path and no bespoke file handling anywhere in the diff. The route validates each uid via `database.get_user_attachment` (must exist, belong to the actor, be an image) before linking, so a foreign or unknown uid is ignored rather than linked. **4. No markdown re-slicing.** The only addition to `content.py` is `count_project_devlog`, which is a count query. Rendering stays entirely on `render_content` / `render_title`. **5. No comments or docstrings in source.** Nothing under `devplacepy/` adds either. The only docstrings in the diff are in test files that already use them. Also folded in: the post composer form now lives once in `templates/_post_composer_form.html` and is included by both `feed.html` and `project_detail.html`, rather than being duplicated. Full suite on the replacement branch: 3334 passed, 9 failed, the 9 being the `tests/api/projects/workspace.py` docker-CLI set that fails identically on untouched master here.
blindxfish closed this pull request 2026-08-13 08:07:12 +02:00
Some checks failed
DevPlace CI / test (pull_request) Has been cancelled

Pull request closed

Sign in to join this conversation.
No reviewers
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: retoor/devplacepy#165
No description provided.