diff --git a/README.md b/README.md index ffaa4e8..7f1d4fc 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Ready-made templates for the [phpBB Modders wiki extension](https://github.com/phpbbmodders/phpbb-ext-wiki), adapted from Wikipedia's and other Wikimedia wikis' for what the wiki can do, so a board can start with a useful set instead of writing every template from nothing. -So far [`templates/`](templates/) holds the hatnotes `{{Main}}`, `{{See also}}`, `{{Further}}` and `{{About}}`; the message boxes `{{Ambox}}`, `{{Update}}`, `{{Unreferenced}}`, `{{More citations needed}}` and `{{Under construction}}`; the stub boxes `{{Asbox}}` and `{{Stub}}`; and `{{Nowrap}}`. The plan for this repository is in the wiki extension's [`docs/TODO/todo-wiki-templates-repo.md`](https://github.com/phpbbmodders/phpbb-ext-wiki/blob/main/docs/TODO/todo-wiki-templates-repo.md). +So far [`templates/`](templates/) holds the hatnotes `{{Main}}`, `{{See also}}`, `{{Further}}` and `{{About}}`; the message boxes `{{Ambox}}`, `{{Update}}`, `{{Unreferenced}}`, `{{More citations needed}}` and `{{Under construction}}`; the stub boxes `{{Asbox}}` and `{{Stub}}`; and the inline helpers `{{Nowrap}}`, `{{Small}}` and `{{Large}}`. The plan for this repository is in the wiki extension's [`docs/TODO/todo-wiki-templates-repo.md`](https://github.com/phpbbmodders/phpbb-ext-wiki/blob/main/docs/TODO/todo-wiki-templates-repo.md). ## Why a separate repository diff --git a/data/templates.json b/data/templates.json index 0952f65..f9295b4 100644 --- a/data/templates.json +++ b/data/templates.json @@ -6,6 +6,13 @@ "status": "adapted", "title": "Template:Stub" }, + "enwiki:828359": { + "name": "Center", + "reason": "needs a
to centre its text, and phpBB has no centring BBCode out of the box", + "revid": 1282577637, + "status": "not adaptable", + "title": "Template:Center" + }, "enwiki:1208356": { "name": "Main", "reason": "", @@ -48,6 +55,13 @@ "status": "adapted", "title": "Template:Update" }, + "enwiki:2385304": { + "name": "Small", + "reason": "", + "revid": 1313016425, + "status": "adapted", + "title": "Template:Small" + }, "enwiki:2425121": { "name": "Under construction", "reason": "", @@ -62,6 +76,13 @@ "status": "adapted", "title": "Template:About" }, + "enwiki:8183126": { + "name": "Large", + "reason": "", + "revid": 1133894340, + "status": "adapted", + "title": "Template:Large" + }, "enwiki:10160967": { "name": "More citations needed", "reason": "", diff --git a/templates/Large.wiki b/templates/Large.wiki new file mode 100644 index 0000000..46482b0 --- /dev/null +++ b/templates/Large.wiki @@ -0,0 +1,9 @@ + +Source: https://en.wikipedia.org/wiki/Template:Large +History: https://en.wikipedia.org/w/index.php?title=Template:Large&action=history +Revision: https://en.wikipedia.org/w/index.php?title=Template:Large&oldid=1133894340 (01/16/2023 1:12 AM UTC) +Adapted by phpBB Modders. +Changes: rewritten with phpBB's [size=120] BBCode instead of the the wiki does not allow, which gives the same size; removed the source's documentation and categories. +Example: {{Large|This is large text.}} +Licence: CC BY-SA 4.0, https://creativecommons.org/licenses/by-sa/4.0/ +[size=120]{{{1}}}[/size] diff --git a/templates/Small.wiki b/templates/Small.wiki new file mode 100644 index 0000000..da026a4 --- /dev/null +++ b/templates/Small.wiki @@ -0,0 +1,9 @@ + +Source: https://en.wikipedia.org/wiki/Template:Small +History: https://en.wikipedia.org/w/index.php?title=Template:Small&action=history +Revision: https://en.wikipedia.org/w/index.php?title=Template:Small&oldid=1313016425 (09/23/2025 9:17 PM UTC) +Adapted by phpBB Modders. +Changes: rewritten with phpBB's [size=85] BBCode instead of the the wiki does not allow, which gives the same size; no check for unknown parameters (Lua) or tracking category; removed the source's documentation and categories. +Example: {{Small|This is small text.}} +Licence: CC BY-SA 4.0, https://creativecommons.org/licenses/by-sa/4.0/ +[size=85]{{{1}}}[/size] diff --git a/tests/test_tools.py b/tests/test_tools.py index c592b53..39675ce 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -100,7 +100,13 @@ def test_translate_markup_is_flagged(self): def test_plain_template_needs_nothing(self): self.assertEqual(fetch_template.needs( - '{{{1}}}'), []) + "
{{{1}}}
"), []) + + def test_html_other_than_tables_is_flagged(self): + self.assertEqual( + fetch_template.needs('{{{1}}}' + '

'), + ["HTML the wiki shows as text:
,
, "]) def test_called_templates_skip_magic_words_and_parameters(self): text = ("{{Hatnote|x}} {{ ambox }} {{{1|{{Main}}}}} {{PAGENAME}} " @@ -368,7 +374,7 @@ def setUp(self): def fake_fetch(site, names, content=True): if content: self.fetched.extend(names) - return {name: (dict(self.INFO, text="{{{1}}}", + return {name: (dict(self.INFO, text="[b]{{{1}}}[/b]", timestamp="2025-05-30T12:00:00Z") if name == "See also" else None) for name in names} @@ -402,13 +408,24 @@ def test_fetch_records_the_page_id_and_skips_a_known_revision(self): self.assertEqual(self.fetched, ["See also"]) self.assertFalse((self.dir / "See also.wiki").exists()) + def test_a_redirect_is_not_fetched_under_its_own_name(self): + redirect = dict(self.INFO, title="Template:Small") + with mock.patch.object(fetch_template, "fetch", + return_value={"Smaller": redirect}): + self.assertEqual(self.run_main("Smaller"), 1) + self.assertEqual(self.printed.call_args.args[0], + "REDIRECT Smaller: redirects to Template:Small; " + "use 'Small'") + self.assertFalse((self.dir / "Smaller.wiki").exists()) + self.assertEqual(self.saved(), {}) + def test_existing_file_is_not_replaced_without_force(self): target = self.dir / "See also.wiki" target.write_text("edited", encoding="utf-8") self.assertEqual(self.run_main("See also"), 1) self.assertEqual(target.read_text(encoding="utf-8"), "edited") self.assertEqual(self.run_main("--force", "See also"), 0) - self.assertIn("{{{1}}}", + self.assertIn("[b]{{{1}}}[/b]", target.read_text(encoding="utf-8")) def test_missing_template_fails_and_dry_run_writes_nothing(self): diff --git a/tools/fetch_template.py b/tools/fetch_template.py index 0891c24..fcb77bb 100755 --- a/tools/fetch_template.py +++ b/tools/fetch_template.py @@ -17,8 +17,8 @@ outside , or inside ) was removed, since the header takes its place; * "Needs adapting:", when the text uses what the phpBB Modders wiki cannot run: - Lua ({{#invoke:}}), TemplateStyles, the Translate extension's markup, or - parser functions and magic words it does not have; + Lua ({{#invoke:}}), TemplateStyles, the Translate extension's markup, HTML + other than tables, or parser functions and magic words it does not have; * the licence notice. Once adapted and passing check_headers.py, --mark-adapted records it as such. @@ -104,6 +104,16 @@ r"|SERVER(?:NAME)?|SCRIPTPATH|DISPLAYTITLE|DEFAULTSORT|PAGESIZE" r"|PROTECTIONLEVEL)$") +# Tags the phpBB Modders wiki allows in articles and templates: its HTML table +# elements, and the template tags it understands itself +ALLOWED_TAGS = { + "table", "caption", "thead", "tbody", "tfoot", "tr", "th", "td", + "noinclude", "includeonly", "onlyinclude", +} + +# Tags reported under their own names above, not again as HTML +REPORTED_TAGS = {"templatestyles", "translate", "languages"} + # Names that cannot be a file in templates/: subpages and path characters. INVALID_NAME = re.compile(r'[/\\<>:"|?*\x00-\x1f]|^\.|^\s|\s$') @@ -313,6 +323,13 @@ def needs(text: str) -> list: if re.search(r"<(?:translate|languages)\b|", text, re.IGNORECASE): problems.append("Translate markup (, )") + # The wiki allows HTML tables and nothing else; other tags show as text + tags = {tag.lower() for tag in re.findall(r", <".join(html) + ">") unsupported = set() for match in re.finditer(r"\{\{\s*(#?[A-Za-z][\w ]*?)\s*:", text): word = match.group(1).strip().lower() @@ -464,6 +481,20 @@ def check_updates(record: dict) -> int: return 0 +def redirected(name: str, page: dict) -> bool: + """ + Whether a name is only a redirect to another template on the wiki, such as + Smaller to Small; prints where it points. A template is kept under its own + name, so the redirect's target should be fetched instead. + """ + if page["title"] == PREFIX + name: + return False + target = page["title"][len(PREFIX):] if page["title"].startswith( + PREFIX) else page["title"] + print(f"REDIRECT {name}: redirects to {page['title']}; use {target!r}") + return True + + def mark_unadaptable(site_id: str, names: list, reason: str, record: dict) -> int: """Record templates as not adaptable; return the exit status.""" @@ -476,6 +507,9 @@ def mark_unadaptable(site_id: str, names: list, reason: str, print(f"MISSING {name}: no such template on {site['label']}") failed += 1 continue + if redirected(name, page): + failed += 1 + continue record[record_key(site_id, page["pageid"])] = record_entry( page, name, "not adaptable", reason) print(f"RECORDED {name} (page {page['pageid']}, revision " @@ -530,6 +564,9 @@ def fetch_templates(names: list, args: argparse.Namespace, print(f"MISSING {name}: no such template on {site['label']}") failed += 1 continue + if redirected(name, page): + failed += 1 + continue entry = record.get(record_key(site_id, page["pageid"])) if entry and entry["revid"] == page["revid"] and not args.force: print(f"KNOWN {name}: recorded at revision {page['revid']} "