Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
21 changes: 21 additions & 0 deletions data/templates.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
"status": "adapted",
"title": "Template:Stub"
},
"enwiki:828359": {
"name": "Center",
"reason": "needs a <div> 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": "",
Expand Down Expand Up @@ -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": "",
Expand All @@ -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": "",
Expand Down
9 changes: 9 additions & 0 deletions templates/Large.wiki
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<noinclude>
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 <span style="font-size: 120%"> 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/
</noinclude>[size=120]{{{1}}}[/size]
9 changes: 9 additions & 0 deletions templates/Small.wiki
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<noinclude>
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 <span style="font-size: 85%"> 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/
</noinclude>[size=85]{{{1}}}[/size]
23 changes: 20 additions & 3 deletions tests/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,13 @@ def test_translate_markup_is_flagged(self):

def test_plain_template_needs_nothing(self):
self.assertEqual(fetch_template.needs(
'<span class="nowrap">{{{1}}}</span>'), [])
"<table><tr><td>{{{1}}}</td></tr></table>"), [])

def test_html_other_than_tables_is_flagged(self):
self.assertEqual(
fetch_template.needs('<span class="nowrap">{{{1}}}</span>'
'<div><br/></div>'),
["HTML the wiki shows as text: <br>, <div>, <span>"])

def test_called_templates_skip_magic_words_and_parameters(self):
text = ("{{Hatnote|x}} {{ ambox }} {{{1|{{Main}}}}} {{PAGENAME}} "
Expand Down Expand Up @@ -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="<span>{{{1}}}</span>",
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}
Expand Down Expand Up @@ -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("<span>{{{1}}}</span>",
self.assertIn("[b]{{{1}}}[/b]",
target.read_text(encoding="utf-8"))

def test_missing_template_fails_and_dry_run_writes_nothing(self):
Expand Down
41 changes: 39 additions & 2 deletions tools/fetch_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
outside <onlyinclude>, or inside <noinclude>) 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.
Expand Down Expand Up @@ -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$')

Expand Down Expand Up @@ -313,6 +323,13 @@ def needs(text: str) -> list:
if re.search(r"<(?:translate|languages)\b|<!--T:\d+-->", text,
re.IGNORECASE):
problems.append("Translate markup (<translate>, <languages/>)")
# The wiki allows HTML tables and nothing else; other tags show as text
tags = {tag.lower() for tag in re.findall(r"</?([a-zA-Z][a-zA-Z0-9]*)",
text)}
html = sorted(tags - ALLOWED_TAGS - REPORTED_TAGS)
if html:
problems.append("HTML the wiki shows as text: <"
+ ">, <".join(html) + ">")
unsupported = set()
for match in re.finditer(r"\{\{\s*(#?[A-Za-z][\w ]*?)\s*:", text):
word = match.group(1).strip().lower()
Expand Down Expand Up @@ -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."""
Expand All @@ -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 "
Expand Down Expand Up @@ -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']} "
Expand Down
Loading