Translations - Playwright macro unused, add extra linting for translations, add TRANSLATORS.md (#4087)
Build and push containers / metadata (push) Has been cancelled
Build and push containers / build-push-containers (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Test the built package works basically. (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been cancelled
ChangeDetection.io App Test / lint-code (push) Has been cancelled
ChangeDetection.io App Test / lint-translations (push) Has been cancelled
ChangeDetection.io App Test / lint-template-i18n (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-10 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-11 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-12 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-13 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-14 (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/amd64 (alpine) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm64 (alpine) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/amd64 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm/v7 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm/v8 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm64 (main) (push) Has been cancelled

This commit is contained in:
dgtlmoon
2026-04-26 20:36:50 +10:00
committed by GitHub
parent fd636f16b1
commit 79d75f7926
34 changed files with 264 additions and 402 deletions
+55 -5
View File
@@ -44,10 +44,60 @@ jobs:
exit 1
fi
lint-template-i18n:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Check for fragmented gettext calls in templates
run: |
python3 << 'PYEOF'
import re, sys
from pathlib import Path
# Detects adjacent {{ _(...) }} calls on the same line separated only by HTML
# tags, whitespace, or non-translating Jinja2 variables — the anti-pattern of
# splitting a single sentence across multiple msgids.
# See https://github.com/dgtlmoon/changedetection.io/issues/4074 for background.
#
# The correct fix is to consolidate fragments into one entire-sentence msgid,
# injecting dynamic values via %(name)s kwargs — per the GNU gettext manual
# sections "Entire sentences" and "No string concatenation". See PR #4076 for
# worked examples of each consolidation pattern.
#
# BASELINE: this limit reflects pre-existing violations present when this check
# was introduced. It must only ever go DOWN. Each time you fix a template, lower
# the limit by the number of lines fixed so the improvement is locked in.
# When the count reaches 0, replace the baseline check with a hard sys.exit(1).
BASELINE_LIMIT = 44
FRAGMENT_RE = re.compile(
r'\{\{[^{}]*\b_\s*\([^)]*\)[^{}]*\}\}'
r'(?:\s*(?:<[^>]+>|\{\{(?![^}]*\b_\s*\()[^}]*\}\})\s*)+'
r'\{\{[^{}]*\b_\s*\([^)]*\)[^{}]*\}\}'
)
violations = []
for f in sorted(Path('changedetectionio').rglob('*.html')):
for lineno, line in enumerate(f.read_text().splitlines(), 1):
if FRAGMENT_RE.search(line):
violations.append(f"{f}:{lineno}: {line.strip()[:120]}")
count = len(violations)
print(f"Fragmented i18n calls found: {count} (limit: {BASELINE_LIMIT})")
for v in violations:
print(v)
if count > BASELINE_LIMIT:
print(f"\nERROR: {count} fragmented gettext calls exceed the baseline of {BASELINE_LIMIT}.")
print("Consolidate adjacent _() calls into a single entire-sentence msgid.")
print("See https://github.com/dgtlmoon/changedetection.io/issues/4074 for patterns.")
sys.exit(1)
PYEOF
test-application-3-10:
# Only run on push to master (including PR merges)
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
needs: [lint-code, lint-translations]
needs: [lint-code, lint-translations, lint-template-i18n]
uses: ./.github/workflows/test-stack-reusable-workflow.yml
with:
python-version: '3.10'
@@ -55,7 +105,7 @@ jobs:
test-application-3-11:
# Always run
needs: [lint-code, lint-translations]
needs: [lint-code, lint-translations, lint-template-i18n]
uses: ./.github/workflows/test-stack-reusable-workflow.yml
with:
python-version: '3.11'
@@ -63,7 +113,7 @@ jobs:
test-application-3-12:
# Only run on push to master (including PR merges)
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
needs: [lint-code, lint-translations]
needs: [lint-code, lint-translations, lint-template-i18n]
uses: ./.github/workflows/test-stack-reusable-workflow.yml
with:
python-version: '3.12'
@@ -72,7 +122,7 @@ jobs:
test-application-3-13:
# Only run on push to master (including PR merges)
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
needs: [lint-code, lint-translations]
needs: [lint-code, lint-translations, lint-template-i18n]
uses: ./.github/workflows/test-stack-reusable-workflow.yml
with:
python-version: '3.13'
@@ -81,7 +131,7 @@ jobs:
test-application-3-14:
#if: github.event_name == 'push' && github.ref == 'refs/heads/master'
needs: [lint-code, lint-translations]
needs: [lint-code, lint-translations, lint-template-i18n]
uses: ./.github/workflows/test-stack-reusable-workflow.yml
with:
python-version: '3.14'
+2
View File
@@ -352,4 +352,6 @@ changedetectionio.html_tools.elementpath_tostring: Copyright (c), 2018-2021, SIS
Recognition of fantastic contributors to the project
<sub>Developer note: see [translation guide](changedetectionio/translations/README.md) for i18n template patterns and workflow.</sub>
- Constantin Hong https://github.com/Constantin1489
@@ -1,6 +1,6 @@
{% extends 'base.html' %}
{% block content %}
{% from '_helpers.html' import render_field, render_checkbox_field, render_button, render_time_schedule_form, playwright_warning, only_playwright_type_watches_warning, highlight_trigger_ignored_explainer, render_conditions_fieldlist_of_formfields_as_table, render_ternary_field %}
{% from '_helpers.html' import render_field, render_checkbox_field, render_button, render_time_schedule_form, only_playwright_type_watches_warning, highlight_trigger_ignored_explainer, render_conditions_fieldlist_of_formfields_as_table, render_ternary_field %}
{% from '_common_fields.html' import render_common_settings_form %}
<script src="{{url_for('static_content', group='js', filename='tabs.js')}}" defer></script>
<script src="{{url_for('static_content', group='js', filename='vis.js')}}" defer></script>
@@ -179,15 +179,6 @@
</div>
{% endmacro %}
{% macro playwright_warning() %}
<p><strong>{{ _('Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled.') }}</strong> {{ _('Alternatively try our') }} <a href="https://changedetection.io">{{ _('very affordable subscription based service which has all this setup for you') }}</a>.</p>
<p>{{ _('You may need to <a href="%(url_pinned)s">Enable playwright environment variable</a> and uncomment the <strong>sockpuppetbrowser</strong> in the <a href="%(url_master)s">docker-compose.yml</a> file.',
url_pinned='https://github.com/dgtlmoon/changedetection.io/blob/09ebc6ec6338545bdd694dc6eee57f2e9d2b8075/docker-compose.yml#L31',
url_master='https://github.com/dgtlmoon/changedetection.io/blob/master/docker-compose.yml')|safe }}</p>
<br>
{% endmacro %}
{% macro render_time_schedule_form(form, available_timezones, timezone_default_config) %}
<style>
.day-schedule *, .day-schedule select {
+191 -63
View File
@@ -1,103 +1,231 @@
# Translation Guide
# Translators Guide
## Updating Translations
This document is for contributors who write templates (HTML) and for translators who maintain `.po` files.
It exists because fragmented `msgid`s — splitting a single sentence across multiple `_()` calls — cause
systematic translation breakage across many languages. Follow the patterns here to prevent that.
To maintain consistency and minimize unnecessary changes in translation files, run these commands:
---
```bash
python setup.py extract_messages # Extract translatable strings
python setup.py update_catalog # Update all language files
python setup.py compile_catalog # Compile to binary .mo files
## Terminology
- **Always use "monitor" or "watcher"** for the concept of watching a URL — never the bare word "watch",
which translates to "clock" (e.g. `hodinky` in Czech, `시계` in Korean, `時計` in Japanese).
- Use the **shortest suitable wording** for each language. If a language naturally uses the English
derivative, prefer that.
---
## Template rules: do not fragment `msgid`s
### Why fragments break translation
The GNU gettext manual is explicit on this:
> **[Entire sentences](https://www.gnu.org/software/gettext/manual/html_node/Entire-sentences.html)**:
> Translatable strings should be entire sentences. Because gender/number declension depends on other
> parts of the sentence, half-sentence *"dumb string concatenation"* breaks in many languages other than English.
> **[No string concatenation](https://www.gnu.org/software/gettext/manual/html_node/No-string-concatenation.html)**:
> Placing adjacent `_()` calls is semantically equivalent to runtime `strcat` concatenation, so the same
> guideline applies. The manual also notes that "in some languages the translator might want to swap the
> order" of components.
> **[No embedded URLs](https://www.gnu.org/software/gettext/manual/html_node/No-embedded-URLs.html)**:
> URLs should not be written directly inside `msgid`s; they should be injected via `%(name)s` placeholders
> and values passed as kwargs.
> **[No unusual markup](https://www.gnu.org/software/gettext/manual/html_node/No-unusual-markup.html)**:
> "HTML markup, however, is common enough that it's probably ok to use in translatable strings."
Fragments break differently depending on language family:
| Language family | How fragmentation breaks it |
|---|---|
| SOV (Japanese, Korean, Turkish) | Verb-final word order can't be achieved when verb and subject are in separate fragments |
| Germanic (German) | Gender/case agreement between article and noun is lost across fragment boundaries |
| Romance (French, Spanish, Italian, Portuguese) | Adjective placement, subjunctive mood, verb agreement can't be maintained |
| Slavic (Czech, Ukrainian) | Case (driven by preposition/verb relationships) is easy to get wrong |
| CJK (Chinese, Japanese, Korean) | Modifier position and SVO-vs-topic-prominent differences can't be applied at fragment level |
A past workaround was redistributing translations across adjacent fragments and using `msgstr " "` (a
single space) to suppress unused fragments. This is fragile: as soon as the same short `msgid` is reused
in a different template, the redistributed translation is applied verbatim and breaks the new context.
---
## The four correct patterns
### Pattern 1 — Inline HTML embedding
Keep markup **inside** the `msgid`. Render with `| safe`. This also lets CJK translators decide how to
handle `<i>` (see CJK section below).
```jinja
{# BAD: three fragments; CJK translators can't see the <i> at all #}
{{ _('Helps reduce changes detected caused by sites shuffling lines around, combine with') }}
<i>{{ _('check unique lines') }}</i>
{{ _('below.') }}
{# GOOD: one msgid, rendered with |safe #}
{{ _('Helps reduce changes detected caused by sites shuffling lines around, combine with <i>check unique lines</i> below.') | safe }}
```
## Configuration
### Pattern 2 — URL as kwarg
All translation settings are configured in **`../../setup.cfg`** (single source of truth).
Pass URLs via `%(name)s` so translators can freely reorder them.
The configuration below is shown for reference - **edit `setup.cfg` to change settings**:
```jinja
{# BAD: URL hardcoded between three fragments #}
{{ _('Use') }}
<a target="newwindow" href="https://github.com/caronc/apprise">{{ _('AppRise Notification URLs') }}</a>
{{ _('for notification to just about any service!') }}
{# GOOD: URL passed as kwarg, <a> embedded in the msgid #}
{{ _('Use <a target="newwindow" href="%(url)s">AppRise Notification URLs</a> for notification to just about any service!',
url='https://github.com/caronc/apprise') | safe }}
```
### Pattern 3 — Literal `{{}}` escape as kwarg
Jinja2 would double-interpolate `{{token}}` inside a `_()` call. Pass it as a kwarg instead.
```jinja
{# BAD: literal {{token}} in the middle forces splitting #}
{{ _('Accepts the') }} <code>{{ '{{token}}' }}</code> {{ _('placeholders listed below') }}
{# GOOD: literal passed as kwarg; msgid stays as an entire sentence #}
{{ _('Accepts the <code>%(token)s</code> placeholders listed below', token='{{token}}') | safe }}
```
### Pattern 4 — `{% if %}` outside the `msgid`
Move conditional branches outside `_()` so each branch is a complete sentence, not a fragment.
```jinja
{# BAD: three fragments; SOV languages can't reorder %(title)s relative to "URL or Title" #}
{{ _('URL or Title') }}{% if active_tag_uuid %} {{ _('in') }} '{{ active_tag.title }}'{% endif %}
{# GOOD: branch between two complete msgids; each language can freely reorder %(title)s #}
{% if active_tag_uuid %}
{{ _("URL or Title in '%(title)s'", title=active_tag.title) }}
{% else %}
{{ _('URL or Title') }}
{% endif %}
```
---
## CJK italic policy
CJK fonts typically have no true italic cut — `<i>` falls back to a mechanical slant that reduces
legibility. Now that `<i>` is inside `msgid`s, CJK translators can handle it per-locale. Apply this policy
for `ja` / `zh` / `zh_Hant_TW`:
| Context | Action |
|---|---|
| `<i>` used for general emphasis | Replace with `<strong>`, or drop if the emphasis is self-evident |
| `<strong><i>...</i></strong>` | Collapse to `<strong>...</strong>` |
| `<i>` wrapping a UI term (e.g. "check unique lines") | Wrap in locale-conventional quotation marks: 「」 for `ja`/`zh_Hant_TW`, `""` for `zh` |
---
## Translation workflow
**Always use these commands** — they read consistent settings from `setup.cfg` and produce minimal diffs:
```bash
python setup.py extract_messages # Extract translatable strings from source
python setup.py update_catalog # Propagate new msgids to all .po files
python setup.py compile_catalog # Compile .po files to binary .mo files
```
Running `pybabel` directly without the project options causes reordering, rewrapping, and line-number
churn that makes diffs hard to review.
### Configuration
All translation settings are in `setup.cfg` (single source of truth):
```ini
[extract_messages]
# Extract translatable strings from source code
mapping_file = babel.cfg
output_file = changedetectionio/translations/messages.pot
input_paths = changedetectionio
keywords = _ _l gettext
# Options to reduce unnecessary changes in .pot files
sort_by_file = true # Keeps entries ordered by file path
width = 120 # Consistent line width (prevents rewrapping)
add_location = file # Show file path only (not line numbers)
[update_catalog]
# Update existing .po files with new strings from .pot
# Note: 'locale' is omitted - Babel auto-discovers all catalogs in output_dir
input_file = changedetectionio/translations/messages.pot
output_dir = changedetectionio/translations
domain = messages
# Options for consistent formatting
width = 120 # Consistent line width
width = 120
no_fuzzy_matching = true # Avoids incorrect automatic matches
[compile_catalog]
# Compile .po files to .mo binary format
directory = changedetectionio/translations
domain = messages
```
**Key formatting options:**
- `sort_by_file = true` - Orders entries by file path (consistent ordering)
- `width = 120` - Fixed line width prevents text rewrapping
- `add_location = file` - Shows file path only, not line numbers (reduces git churn)
- `no_fuzzy_matching = true` - Prevents incorrect automatic fuzzy matches
---
## Why Use These Commands?
## Multi-language fix process
Running pybabel commands directly without consistent options causes:
- ❌ Entries get reordered differently each time
- ❌ Text gets rewrapped at different widths
- ❌ Line numbers change every edit (if not configured)
- ❌ Large diffs that make code review difficult
When you find a translation error in **any** language, you must check all others for the same `msgid`:
Using `python setup.py` commands ensures:
- ✅ Consistent ordering (by file path, not alphabetically)
- ✅ Consistent line width (120 characters, no rewrapping)
- ✅ File-only locations (no line number churn)
- ✅ No fuzzy matching (prevents incorrect auto-translations)
- ✅ Minimal diffs (only actual changes show up)
- ✅ Easier code review and git history
```bash
for lang in cs de en_GB en_US es fr it ja ko pt_BR tr uk zh zh_Hant_TW; do
echo "=== $lang ===" && grep -A1 'msgid "YourString"' changedetectionio/translations/$lang/LC_MESSAGES/messages.po
done
```
These commands read settings from `../../setup.cfg` automatically.
1. Identify every language with the same problem
2. Fix all affected `.po` files in the same session
3. Recompile: `python setup.py compile_catalog`
## Supported Languages
Never fix one language and move on.
- `cs` - Czech (Čeština)
- `de` - German (Deutsch)
- `en_GB` - English (UK)
- `en_US` - English (US)
- `fr` - French (Français)
- `it` - Italian (Italiano)
- `ja` - Japanese (日本語)
- `ko` - Korean (한국어)
- `pt_BR` - Portuguese (Brasil)
- `zh` - Chinese Simplified (中文简体)
- `zh_Hant_TW` - Chinese Traditional (繁體中文)
---
## Adding a New Language
## Supported languages
1. Initialize the new language catalog:
```bash
pybabel init -i changedetectionio/translations/messages.pot -d changedetectionio/translations -l NEW_LANG_CODE
```
2. Compile it:
```bash
python setup.py compile_catalog
```
| Code | Language |
|---|---|
| `cs` | Czech (Čeština) |
| `de` | German (Deutsch) |
| `en_GB` | English (UK) |
| `en_US` | English (US) |
| `es` | Spanish (Español) |
| `fr` | French (Français) |
| `it` | Italian (Italiano) |
| `ja` | Japanese (日本語) |
| `ko` | Korean (한국어) |
| `pt_BR` | Portuguese (Brasil) |
| `tr` | Turkish (Türkçe) |
| `uk` | Ukrainian (Українська) |
| `zh` | Chinese Simplified (中文简体) |
| `zh_Hant_TW` | Chinese Traditional (繁體中文) |
Babel will auto-discover the new language on subsequent translation updates.
## Adding a new language
## Translation Notes
```bash
pybabel init -i changedetectionio/translations/messages.pot \
-d changedetectionio/translations \
-l NEW_LANG_CODE
python setup.py compile_catalog
```
From CLAUDE.md:
- Always use "monitor" or "watcher" terminology (not "clock")
- Use the most brief wording suitable
- When finding issues in one language, check ALL languages for the same issue
Babel auto-discovers the new language on subsequent runs.
---
## CI linter
A GitHub Actions job (`lint-template-i18n`) checks for adjacent `{{ _(...) }}` calls on the same line
separated only by HTML — the primary symptom of fragmented `msgid`s. It enforces a declining baseline:
the count of existing violations may only go down, never up. When you fix a template, lower the
`BASELINE_LIMIT` in `.github/workflows/test-only.yml` by the number of lines you fixed.
See [issue #4074](https://github.com/dgtlmoon/changedetection.io/issues/4074) for full background and
[PR #4076](https://github.com/dgtlmoon/changedetection.io/pull/4076) for worked consolidation examples.
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: 2026-01-02 11:40+0100\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: cs\n"
@@ -3695,25 +3695,6 @@ msgstr ""
msgid "Verify this rule against current snapshot"
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr ""
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr ""
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: 2026-01-14 03:57+0100\n"
"Last-Translator: \n"
"Language: de\n"
@@ -3749,29 +3749,6 @@ msgstr "Diese Zeile/Regel entfernen"
msgid "Verify this rule against current snapshot"
msgstr "Überprüfen Sie diese Regel anhand des aktuellen Snapshots."
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr ""
"Fehler Diese Überwachung benötigt Chrome (mit Playwright/Sockpuppetbrowser), aber das Abrufen über Chrome ist nicht"
" aktiviert."
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr "Alternativ können Sie auch unser"
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr "ein sehr günstiges Abonnement-basiertes Angebot, das all diese Einstellungen für Sie übernimmt"
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
"Sie müssen möglicherweise <a href=\"%(url_pinned)s\">Aktivieren der Umgebungsvariable „Playwright“</a> und entferne "
"den Kommentar von <strong>sockpuppetbrowser</strong> in der <a href=\"%(url_master)s\">docker-compose.yml</a> Datei."
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr "Legen Sie einen Stunden-/Wochenplan fest."
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: changedetection.io\n"
"Report-Msgid-Bugs-To: https://github.com/dgtlmoon/changedetection.io\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: 2026-01-12 16:33+0100\n"
"Last-Translator: British English Translation Team\n"
"Language: en_GB\n"
@@ -3689,25 +3689,6 @@ msgstr ""
msgid "Verify this rule against current snapshot"
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr ""
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr ""
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: https://github.com/dgtlmoon/changedetection.io\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: 2026-01-12 16:37+0100\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en_US\n"
@@ -3689,25 +3689,6 @@ msgstr ""
msgid "Verify this rule against current snapshot"
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr ""
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr ""
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: changedetection.io 0.53.6\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: 2026-03-20 18:13+0100\n"
"Last-Translator: Adrian Gonzalez <adrian@example.com>\n"
"Language: es\n"
@@ -3764,29 +3764,6 @@ msgstr "Eliminar esta fila/regla"
msgid "Verify this rule against current snapshot"
msgstr "Verifique esta regla con la instantánea actual"
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr ""
"Error: este monitor necesita Chrome (con playwright/sockpuppetbrowser), pero la obtención basada en Chrome no está "
"habilitada."
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr "Alternativamente prueba nuestro"
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr "servicio basado en suscripción muy asequible que tiene toda esta configuración para usted."
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
"Es posible que necesites <a href=\"%(url_pinned)s\">Habilitar la variable de entorno de playwright</a> y descomentar "
"el <strong>sockpuppetbrowser</strong> en el fichero <a href=\"%(url_master)s\">docker-compose.yml</a>."
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr "Establecer un horario por horas/días de la semana"
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: 2026-01-02 11:40+0100\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: fr\n"
@@ -3702,25 +3702,6 @@ msgstr ""
msgid "Verify this rule against current snapshot"
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr ""
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr ""
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: 2026-01-02 15:32+0100\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: it\n"
@@ -3691,25 +3691,6 @@ msgstr ""
msgid "Verify this rule against current snapshot"
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr ""
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr ""
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: changedetection.io 0.53.6\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: 2026-03-31 23:52+0900\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: ja\n"
@@ -3722,27 +3722,6 @@ msgstr "この行/ルールを削除"
msgid "Verify this rule against current snapshot"
msgstr "現在のスナップショットに対してこのルールを検証"
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr "エラー - このウォッチは Chromeplaywright/sockpuppetbrowser付き)が必要ですが、Chromeベースの取得が有効になっていません。"
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr "または以下をお試しください:"
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr "すべての設定が完了した手頃な価格のサブスクリプションサービス"
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
"<a href=\"%(url_pinned)s\">playwright 環境変数の有効化</a>と <a href=\"%(url_master)s\">docker-compose.yml</a> ファイル内の "
"<strong>sockpuppetbrowser</strong> のコメント解除が必要な場合があります。"
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr "時間/曜日スケジュールを設定"
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: 2026-01-02 11:40+0100\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: ko\n"
@@ -3692,25 +3692,6 @@ msgstr ""
msgid "Verify this rule against current snapshot"
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr ""
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr ""
+1 -20
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: changedetection.io 0.54.10\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -3688,25 +3688,6 @@ msgstr ""
msgid "Verify this rule against current snapshot"
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr ""
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr ""
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: changedetection.io 0.54.8\n"
"Report-Msgid-Bugs-To: mstrey@gmail.com\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: 2026-04-07 22:00-0300\n"
"Last-Translator: Gemini AI\n"
"Language: pt_BR\n"
@@ -3739,29 +3739,6 @@ msgstr "Remover esta linha/regra"
msgid "Verify this rule against current snapshot"
msgstr "Verificar esta regra contra o instantâneo atual"
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr ""
"Erro - Este monitoramento precisa do Chrome (com playwright/sockpuppetbrowser), mas a busca baseada em Chrome não "
"está ativada."
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr "Alternativamente, tente nosso"
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr "serviço por assinatura muito acessível que já tem toda essa configuração pronta para você"
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
"Você pode precisar <a href=\"%(url_pinned)s\">Ativar a variável de ambiente do Playwright</a> e descomentar o "
"<strong>sockpuppetbrowser</strong> no arquivo <a href=\"%(url_master)s\">docker-compose.yml</a>."
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr "Definir um agendamento por hora/dia da semana"
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: changedetection.io 0.53.6\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: 2026-04-10 20:38+0300\n"
"Last-Translator: \n"
"Language: tr\n"
@@ -3744,29 +3744,6 @@ msgstr "Bu satırı/kuralı kaldır"
msgid "Verify this rule against current snapshot"
msgstr "Bu kuralı mevcut anlık görüntüye karşı doğrula"
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr ""
"Hata - Bu izleyicinin Chrome'a (playwright/sockpuppetbrowser ile) ihtiyacı var, ancak Chrome tabanlı getirme etkin "
"değil."
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr "Alternatif olarak şunu deneyin"
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr "sizin için tüm bu kuruluma sahip çok uygun fiyatlı abonelik tabanlı hizmetimiz"
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
"<a href=\"%(url_pinned)s\">Playwright ortam değişkenini etkinleştirmeniz</a> ve <a href=\"%(url_master)s\">docker-"
"compose.yml</a> dosyası içindeki <strong>sockpuppetbrowser</strong> satırının yorumunu kaldırmanız gerekebilir."
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr "Saatlik/hafta içi bir zamanlama ayarla"
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: changedetection.io\n"
"Report-Msgid-Bugs-To: https://github.com/dgtlmoon/changedetection.io\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: 2026-02-19 12:30+0100\n"
"Last-Translator: \n"
"Language: uk\n"
@@ -3721,27 +3721,6 @@ msgstr "Видалити цей рядок/правило"
msgid "Verify this rule against current snapshot"
msgstr "Перевірити це правило на поточному знімку"
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr "Помилка - Це завдання потребує Chrome (playwright/sockpuppetbrowser), але завантаження через Chrome не увімкнено."
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr "Альтернативно спробуйте наш"
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr "дуже доступний сервіс за передплатою, де все це вже налаштовано для вас"
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
"Вам може знадобитися <a href=\"%(url_pinned)s\">Увімкнути змінну оточення playwright</a> та розкоментувати "
"<strong>sockpuppetbrowser</strong> у файлі <a href=\"%(url_master)s\">docker-compose.yml</a>."
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr "Встановити розклад по годинах/днях тижня"
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: 2026-01-18 21:31+0800\n"
"Last-Translator: 吾爱分享 <admin@wuaishare.cn>\n"
"Language: zh\n"
@@ -3695,27 +3695,6 @@ msgstr "移除此行/规则"
msgid "Verify this rule against current snapshot"
msgstr "使用当前快照验证此规则"
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr "错误 - 该监控项需要 Chromeplaywright/sockpuppetbrowser),但未启用基于 Chrome 的抓取。"
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr "也可以试试我们的"
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr "价格实惠的订阅服务,已为你完成全部配置"
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
"您可能需要<a href=\"%(url_pinned)s\">启用 Playwright 环境变量</a>,并在 <a href=\"%(url_master)s\">docker-compose.yml</a> 文件中取消注释 "
"<strong>sockpuppetbrowser</strong>。"
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr "设置按小时/工作日计划"
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-04-25 01:52+0900\n"
"POT-Creation-Date: 2026-04-26 20:03+1000\n"
"PO-Revision-Date: 2026-01-15 12:00+0800\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: zh_Hant_TW\n"
@@ -3693,27 +3693,6 @@ msgstr "移除此行 / 規則"
msgid "Verify this rule against current snapshot"
msgstr "針對目前快照驗證此規則"
#: changedetectionio/templates/_helpers.html
msgid "Error - This watch needs Chrome (with playwright/sockpuppetbrowser), but Chrome based fetching is not enabled."
msgstr "錯誤 - 此監測任務需要 Chrome(搭配 playwright / sockpuppetbrowser),但未啟用基於 Chrome 的抓取功能。"
#: changedetectionio/templates/_helpers.html
msgid "Alternatively try our"
msgstr "或者嘗試我們"
#: changedetectionio/templates/_helpers.html
msgid "very affordable subscription based service which has all this setup for you"
msgstr "非常實惠的訂閱服務,為您準備好所有設定"
#: changedetectionio/templates/_helpers.html
#, python-format
msgid ""
"You may need to <a href=\"%(url_pinned)s\">Enable playwright environment variable</a> and uncomment the "
"<strong>sockpuppetbrowser</strong> in the <a href=\"%(url_master)s\">docker-compose.yml</a> file."
msgstr ""
"您可能需要 <a href=\"%(url_pinned)s\">啟用 playwright 環境變數</a> 並取消註解 <strong>sockpuppetbrowser</strong> 在 <a "
"href=\"%(url_master)s\">docker-compose.yml</a> 檔案."
#: changedetectionio/templates/_helpers.html
msgid "Set a hourly/week day schedule"
msgstr "設定每小時 / 平日排程"