Use reverse() and {% url %} instead of hardcoded URL paths#76
Conversation
Replace hardcoded URL construction with Django's reverse() in subscriptions email notifications, page history diff base, and llms.txt entry generation. Fixes a missing slash bug in the subscription diff email link. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hardcoded API and page URLs in JavaScript with values
passed through JSON config blocks using Django's {% url %} tag.
Covers markdown-editor.js, page-form.js, and
username-autocomplete.js across all templates that load them.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Expand the existing URLs coding rule to cover JavaScript: URLs
must be passed from Django templates via JSON config blocks using
{% url %} tags, never hardcoded in .js files.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
LGTM — mechanical URL hardcoding removal with a real bug fix included.
Extended reasoning...
Overview
This PR touches 13 files across Python backend (subscriptions, pages, lib) and JS/template layers. All changes follow a single mechanical pattern: replace hardcoded URL strings with Django reverse() in Python and {% url %} tags passed via JSON config blocks to JavaScript.
Security risks
No security concerns — the change moves away from hardcoded strings toward Django’s URL resolution, which is strictly safer. The JSON config block pattern is standard for safely passing server-side data to client-side JS without inline script injection.
Level of scrutiny
Low. The changes are repetitive and mechanical. The only non-trivial logic is the diff_base construction in pages/views.py, which uses reverse("page_diff", kwargs={..."v1": 0, "v2": 0}).rsplit("0/0/", 1)[0] to strip the dummy values — slightly clever but clearly correct given the URL structure. The subscription task bug fix (missing slash between get_absolute_url() and diff/) is also straightforward.
Other factors
No bugs reported by the automated system. All URL names referenced (resolve_path, page_diff, page_raw_markdown, presign_upload, confirm_upload, file_upload, page_preview, user_search, page_search, dir_inherit_meta, dir_search, check_page_perms) appear to be in active use across the codebase. The CLAUDE.md documentation update correctly codifies the pattern for future contributors.
Fixes
This fixes a missing slash bug in subscription diff email links and eliminates all hardcoded URL paths across Python and JavaScript.
Summary
Replace hardcoded URL construction with Django's
reverse()in Python and{% url %}template tags passed to JavaScript via JSON config blocks.Python backend (3 files):
subscriptions/tasks.py— email notification URLs (page link + diff link) now usereverse(); fixes the original missing-slash bugpages/views.py— page historydiff_basenow usesreverse("page_diff")with dummy values (matches existing directory pattern)lib/views.py— llms.txt entry URLs now usereverse("page_raw_markdown")JavaScript + templates (9 files):
markdown-editor.js— 7 hardcoded API/page URLs replaced withconfig.urls.*page-form.js— 4 hardcoded API URLs replaced withconfig.urls.*username-autocomplete.js— 1 hardcoded API URL replaced with config-driven value<script type="application/json">config blocks using{% url %}tagsDocumentation:
CLAUDE.mdrule 3 expanded to cover JavaScript URL handlingDeployment
This PR should:
skip-deploy(skips everything below)skip-web-deployskip-daemon-deploy🤖 Generated with Claude Code