Skip to content

fix: render Jinja2 watch URL on diff/preview pages instead of the raw template (#3776)#4256

Open
ebarkhordar wants to merge 1 commit into
dgtlmoon:masterfrom
ebarkhordar:fix/3776-jinja2-url-diff-page
Open

fix: render Jinja2 watch URL on diff/preview pages instead of the raw template (#3776)#4256
ebarkhordar wants to merge 1 commit into
dgtlmoon:masterfrom
ebarkhordar:fix/3776-jinja2-url-diff-page

Conversation

@ebarkhordar

Copy link
Copy Markdown
Contributor

Fixes #3776

Root cause

The diff and preview pages pass the raw watch['url'] into base.html as current_diff_url:

  • changedetectionio/processors/text_json_diff/difference.py (diff page)
  • changedetectionio/processors/image_ssim_diff/difference.py (image diff page)
  • changedetectionio/blueprint/ui/preview.py (preview page)
  • changedetectionio/processors/image_ssim_diff/preview.py (image preview page)

base.html then renders it as <a class="current-diff-url" href="{{ current_diff_url }}">. When a watch URL contains a Jinja2 template such as {% now 'utc', '%Y' %}, the link points at the unrendered template string, so it shows raw and is not clickable (the reported behaviour).

Invariant

The URL linked on the diff and preview pages must be the Jinja2-rendered, safety-validated Watch.link value, never the raw template. Watch.link (model/Watch.py) already does jinja_render() plus is_safe_valid_url() validation and is what the watch list uses, so the diff and preview headers should use the same value.

Fix

Replace current_diff_url=watch['url'] with current_diff_url=watch.link at the four render call sites above. For a plain URL Watch.link returns it unchanged, so nothing changes for non-templated watches; for an invalid URL it returns DISABLED, which base.html already guards with is_safe_valid_url(current_diff_url).

The reported issue is the diff page; the same raw-template value was passed at the preview and image-processor render calls, so I fixed all four rather than leave the preview page showing the same unrendered URL.

Verification

Ran in a clean Docker container (python:3.11-slim, requirements.txt), against this branch and against master:

  • New test tests/test_diff_url_jinja2_render.py (adds a paused watch with a Jinja2 URL, injects two history snapshots, loads the diff page): fails on master (the current-diff-url href is the raw ...{% now ... %}...), passes on this branch (href is the rendered URL). Confirmed both runs load the branch/master copy via module.__file__.
  • Existing tests/test_download_patch.py (renders the diff page for normal URLs): 3 passed on this branch, so watch.link does not change plain-URL rendering.

What I did not verify: tests/test_jinja2.py::test_jinja2_in_url_query (preview page, does a live fetch) could not run in my container because the fetcher could not resolve the live-server host; it fails the same way on unmodified master, so it is an environment limit on my side, not this change. The preview and image-processor call sites get the same one-line substitution and the same base.html contract as the diff page, but only the diff page has a new regression test here.

AI assistance: this fix was prepared with AI help; the reproduction, the differential test, and the Docker runs above were executed and checked before opening.

… template (dgtlmoon#3776)

The diff and preview pages passed the raw watch['url'] into base.html as current_diff_url, so a URL containing a Jinja2 template (e.g. {% now 'utc','%Y' %}) was linked and displayed unrendered and non-clickable. Watch.link already performs jinja_render() plus safe-url validation, so use it at the four render call sites that feed current_diff_url.
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.

URL with Jinja2 variables not resolved/clickable on diff page

1 participant